# Improving Network Properties via Dynamic Network Fees ## Overview As we launch SSV's Shifu V2 Testnet and move closer to a subsequent release candidate, the details of the network are beginning to solidify. But at this moment, before all of this is finalized in preparation for mainnet launch, we have an opportunity to augment the project's tokenomics to improve the network's properties, support the SSV community, and better serve the greater Ethereum ecosystem. This article illustrates how we might seek to achieve such effects and presents some example solutions for us to consider, including: - Encouraging decentralization by giving advantages to small operators - Increasing network and market stability by incentivizing users to hold more SSV - Creating a method to "stake" SSV and earn a return without needing the DAO to mint new tokens to pay for it - Increasing DAO governance participation by incentivizing regular voting But please do not view this as an exhaustive list. Instead, the purpose of this is to explain how our objectives can be transformed into tangible features, and the primary concept that I wish to convey is this: **If we can define objectives, and if we can formulate those objectives in terms of measurable metrics, then we can design mathematical mechanisms to encourage those desired properties.** So let's discuss what our objectives should be and then work towards designing the corresponding mechanisms that support them. You'll see that I dive into the math a bit here, but **don't worry if you're non-technical**. We have plenty of people that can listen to your ideas and handle the math, and I encourage everyone in the community to share their thoughts and ideas. With that said, I have tried to be demonstrative about how I think we should approach the design process, including the tuning of those functions and ensuring that they are bounded to guarantee safety. ## Overview of Existing Tokenomics Framework For a description of the complete tokenomics design, [see the documentation](https://ssv.network/tokenomics/). However, to summarize the relevant concepts, let's use a figure from the documentation above: ![](https://i.imgur.com/KeAUYrO.png) From this diagram, we can see that **ETH stakers on the network pay operators a fee (in SSV tokens) to run their validators. A small additional "network fee" is also charged to the staker**, which goes to the DAO treasury to fund further ecosystem development and other activities approved by the DAO. To ensure the network stays solvent and that operators always get paid for their work, **each validator must maintain a minimum balance of SSV, called the "liquidation collateral"**. If a user balance drops below this minimum amount, their remaining balance will be liquidated, and their selected operators will cease performing duties for their validators. So to represent it mathematically, let the fees be defined per validator as: \begin{equation} \tag{1} F_v = \sum_{i} (O_i + N_i) \end{equation} where $F_v$ denotes the total fee owed by a validator, $O_i$ is the operator fee of their $i^{th}$ operator, $N_i$ is the network fee for the validator running on their $i^{th}$ operator, and $\Sigma$ is a summation over the selected operators. Therefore the fees paid by the validator for their $i^{th}$ operator are a sum of the operator fee, $O_i$ (a constant, as set by that operator), and the network fee, $N_i$. ## Objective: Increase decentralization by favoring many small operators over few large ones **By increasing the network fee on an operator as their number of validators increases, we can discourage centralization by incentivizing stakers to choose smaller operators.** We can achieve this by defining the network fee as, \begin{equation} \tag{2} N_i = B + P_i \end{equation} where $B$ is a constant base network fee and $P_i$ is a centralization penalty for a validator's $i^{th}$ operator. **This penalty increases with the number of validators running on that operator.** In my opinion, each subsequent validator added should carry a larger penalty than the ones before it, so I'm choosing to use a "superlinear" function here to get that property. For example, we can use an exponential function with a small exponent value: \begin{equation} \tag{3} P_i = \alpha V_i^{\beta} \end{equation} where $V_i$ is the number of validators on the $i^{th}$ operator, and $\alpha$ and $\beta$ are constants chosen to adjust the function steepness and curvature. With some example parameter choices (let’s use $B$ = 0.1, $\alpha$ = 0.0000025, and $\beta$ = 1.5 to illustrate), this gives the following plot: | ![](https://i.imgur.com/9qlpXJU.png) | |:--:| | *Penalty function that increases the network fee as the size of an operator increases.* | Note that from Equation (2), $P_i$ in this plot is added to the base network fee, $B$, to get the network fee, $N_i$. For example, as the penalty is defined, an operator with 200 validators would have a 7% higher network fee than one with 0 validators (0.1 + 0.007 = 0.107), an operator with 1000 validators would have a 79% higher fee, and with 2000 validators a 224% higher fee. We have the ability to customize and tune the function above, but the idea is that **smaller validators will now have an advantage over large ones.** **Tuning and bounding:** This function has two parameters to tune: $\alpha$ and $\beta$. $\alpha$ is a simple coefficient that scales the values, and $\beta$ affects the curvature. If you want penalties to be higher overall, increase $\alpha$. If you want larger operators to be punished to a greater degree than smaller ones, increase $\beta$. We don't have any bounding concerns with this function, since $V_i \ge 0$ will always be true, and the exponential shape gives us a "soft bound", where the penalty will grow so large that it effectively limits the size of $V_i$. When choosing these values, we should be thinking about questions like "At what size do we want to make an operator's cost untenable? And what penalty would achieve that untenable cost?" You can experiment with different values using this [graphing tool](https://www.desmos.com/calculator/w4poahxzgu). **Additional considerations:** We might not have a reliable way to measure an operator's total size because they could spin up many nodes and try to keep each of them small. Without any mitigation of this, the above is still a partial solution, but a more robust way to evaluate operator size would be useful. ## Objective: Increase network and market stability by incentivizing users to hold more SSV **We can create the incentive for users to hold SSV by decreasing the network fee paid by validators as their amount of held SSV increases.** This can be achieved by defining the network fee, $N_i$, to include a discount factor as follows: \begin{equation} \tag{4} N_i = BD_{SSV} \end{equation} where $B$ is a constant base network fee and $D_{SSV}$ defines a discount given to users for holding more SSV. In my opinion, there should be diminishing returns for holding more SSV, so I selected a "sublinear" function to govern the discount: \begin{equation} \tag{5} D_{SSV} = 1 - \frac{(S-L)}{(S-L) + \gamma} \end{equation} where $S$ is the amount of SSV tokens held by the user, $L$ is the liquidation collateral (the minimum number of tokens that must be held to avoid liquidation), and $\gamma$ is a constant chosen to adjust the steepness of the function. This comes from the cheap bounded logarithmic-like function: $y=x/(x+a)$. We could configure this in several ways, but here’s an example to illustrate: Let the amounts of SSV be defined with respect to the length of time the validator can be paid for (maybe using some average cost). So if we use a unit of months and let $L$ = 12 months, then all validators must have enough SSV to keep themselves running for 12 months. And let $\gamma$ = 20, arbitrarily. This gives: | ![](https://i.imgur.com/LIq3uO3.png) | |:--:| | *Discount function that decreases the network fee as the amount of SSV held by a user increases.* | With these example values, at the minimum amount of SSV held ($S$ = $L$ = 12 months), $D_{SSV}$ = 1, and no discount is given. At twice the required amount ($S$ = 24 months), $D_{SSV}$ = 0.625, giving a 37.5% discount. At $S$ = 48 months, $D_{SSV}$ = 0.357 (64.3% discount). And at $S$ = 120 months, $D_{SSV}$ = 0.156 (84.4% discount). Observe that the effects of holding additional SSV are very high initially, with decreasing effect as more SSV is added, asymptotically approaching a full cancelation of the network fee ($D_{SSV}$ = 0). **Tuning and bounding:** This function has one main parameter to tune: $\gamma$. The liquidation collateral, $L$, is also a parameter, but it shouldn't be used to tune this function. It simply shifts the function left and right anyway and doesn't impact the shape of the curve. $\gamma$ affects the steepness of the curve (i.e. how quickly the discount is earned). If we want the discount to be easier to get, then decrease $\gamma$, and vice-versa. However, if you zoom out on a plot of this function, you'll see that we're only using a specific region of it (and need to stay there). So we have some constraints with setting $\gamma$ to prevent it from going into other regions where the math isn't what we want. In other words, we're limited to the region where $D_{SSV}$ > 0, which is true for all $S$ > 0 when $L$ < $\gamma$. Also note that $D_{SSV}$ goes to infinity when $S$ = 0, when $L$ = $\gamma$. So basically... just make sure $\gamma$ is greater than $L$, and we're all good. You can experiment with different values using this [graphing tool](https://www.desmos.com/calculator/ownmqjsjyi). ## Combining mechanisms: centralization penalty + holder discount It's important to note that **the mechanisms above can be implemented independently or in combination**. I'll illustrate how we could combine them here by putting Equations (2) and (4) together, defining the network fee as, \begin{equation} \tag{6} N_i = (B + P_i)D_{SSV} \end{equation} **Now the value of $N_i$ is adjusted in two ways: it increases as the operator’s size increases, and it decreases as the amount of SSV held by the user increases.** Also note that I opted to wrap the discount mechanism around the penalty mechanism, which allows the discount to mitigate the penalty as well as the base fee. We can show the result by plotting the network fee, $N_i$: | ![](https://i.imgur.com/OKYqdCj.png) | |:--:| | *Function combining the discount from holding SSV with the centralization penalty for choosing large operators.* | The constants were set to the same values used above ($B$ = 0.1, $L$ = 12, $\alpha$ = 0.0000025, $\beta$ = 1.5, $\gamma$ = 20). Giving values for each corner of the plot: --For a user with the minimum SSV ($S$ = $L$ = 12 months) and using an operator with 0 validators, their network fee is **100% of the base network fee. [new operator, no fee mitigation]** --For a user with 120 months of SSV and an operator with 0 validators, the network fee is **15% the base network fee. [best case: new operator, high fee mitigation]** --For a user with the minimum SSV using an operator with 2000 validators, the network fee is **320% the base network fee. [worst case: large operator, no fee mitigation]** --For a user with 120 months of SSV and an operator with 2000 validators, the network fee is **50% the base network fee. [large operator, high fee mitigation]** ## Objective: Create a way to earn a return on SSV tokens without depending on inflation (needing to mint new tokens) This feature is an exception in that it's not a direct mapping from objective to mechanism (although this might be possible). Rather, this is achieved through a secondary feature of the fee discount mechanism described above. The fee discount creates a dynamic where a staker would save money by having more SSV tokens. We can extend this further and observe that they would also be incentivized to borrow those additional tokens if they could do so at a cost that is less than the savings earned. From the other side, a holder of SSV would be incentivized to lend their tokens to that staker because they could earn a return by taking a share of the staker's savings. In other words, **the staker and the lender can work together to extract value from the fee discount mechanism, then share it.** To illustrate with an example, imagine a staker is paying a network fee of 1 SSV per year, and if they had more SSV, the discount would reduce that to 0.5 SSV per year, giving them 0.5 SSV of savings. Another SSV holder that wishes to earn a return on their tokens offers to lend those tokens to the staker for a price of 0.25 SSV. The staker accepts that deal and pays the lender their price of 0.25 SSV, so the lender walks away with 0.25 SSV profit. The staker uses those tokens to save 0.5 SSV, which after their payment to the lender, they have 0.25 SSV remaining as profit. Both the staker and lender made 0.25 SSV from this deal. This value extraction can be utilized to create a method to stake SSV and earn a return on those tokens. However, there are a few ways this could be implemented. The simplest way is to take the staked SSV and apply it to the discount of all validators, lowering the network fee for everyone. But we could also have this be more directed, where a user would assign their staked SSV to a specific validator or group of validators. For example, they could decide to lower the cost of validators run on certain operators (e.g. small operators, operators running minority clients, etc.) to give them a competitive advantage and have an altruistic effect on the ecosystem. Or the staked SSV could be assigned dynamically to validators that would see the greatest discount, maximizing the return for SSV stakers. What do you think our objectives should be? ## Objective: Increase governance participation **I suspect this design might be too complex to implement robustly on mainnet SSV.** But regardless, I am presenting it here because it's a good opportunity to further illustrate this general approach. And we could still opt to use it for future incentivized testnet programs, where increased complexity carries far fewer costs. One struggle of the SSV community has been our low rate of voter participation on DAO proposals. We can attempt to address this by incentivizing participation among users through rewards or penalties. For the sake of consistency, let's demonstrate it on the network fee, $N_i$. One approach is to simply **give a small discount for voting on DAO proposals, where the more a user votes, the greater their discount.** We can achieve this by again modifying the network fee to be, \begin{equation} \tag{7} N_i = B - D_{vote} \end{equation} where $B$ is the constant base network fee and $D_{vote}$ is a voter discount function. In choosing the function for $D_{vote}$, we have many options, so let's walk through an example design process to illustrate. To start simply, we could just have the discount be proportional to how many times a user has voted on proposals, like this: \begin{equation} \tag{8} D_{vote} = \alpha\frac{P_{voted}}{P_{total}} \end{equation} where $P_{voted}$ is the number of proposals voted on by this user, $P_{total}$ is the number not voted on, and $\alpha$ is reused as a constant scaling coefficient that gives the magnitude of the discount. However, this is vulnerable to abuse, since users could spam the submission of proposals to increase their participation score. **To mitigate this possible abuse, we can change our approach slightly to one where $D_{vote}$ measures the time over which a user has participated, rather than the absolute number of votes.** This can be done by giving each user a monthly score, defined as the voting participation ratio ($P_{voted}/P_{total}$) for each month. Changing Equation (8) to now iterate backward in time through each month $j$, up to the total past months, $M$, we get, \begin{equation} \tag{9} D_{vote} = \frac{\alpha}{M} \sum_{j = 1}^{M}\frac{P_{voted_j}}{P_{missed_j}} \end{equation} where $\alpha$ is again a constant chosen to scale the discount magnitude, and $\Sigma$ is a summation over past months. Let's set $\alpha = 1.0$ arbitrarily so we can evaluate the math. Note that because we sum these values, we must also divide by $M$ to normalize the discount (i.e. keep the maximum consistent, regardless of the number of months summed). We can simulate this design and see how $D_{vote}$ will compute for a new user that has no prior voting (12 months of not voting) but will participate in every vote from now on. Plotting the network fee, $N_i$, as it decreases as the user votes: | ![](https://i.imgur.com/rfoPi1V.png) | |:--:| | *Network fee that decreases as a user voting participation increases.* | **Observe that the network fee decreases as the user votes over time**, and therefore this should effectively reward participation without allowing significant abuse. However, **we can refine this further, so let's ask ourselves some questions:** Do we want to value consistent long-term participation more than short-term? Do we want new devoted users to be capable of earning the same discount as those that have participated from the beginning? How quickly should new users earn this discount? Should it expire? With answers to these questions, we can make adjustments. **To value long-term participation more highly,** we can use another function to give little weighting to the users' early votes and more weighting as they continue. I'll use a [logistic function](https://en.wikipedia.org/wiki/Logistic_function) to control the weighting here. I'm choosing it because it's effectively an "on-off switch", and I want to the discount to "turn on" when a user participates sufficiently. There are many similar functions that achieve a switching effect (e.g. [step function](https://en.wikipedia.org/wiki/Heaviside_step_function), [clamp function](https://en.wikipedia.org/wiki/Clamping_(graphics)), [smoothstep function](https://en.wikipedia.org/wiki/Smoothstep)), but I want something continuous and smooth, and the logistic function has a good shape for this application, while being fairly simple to evaluate. Written out, it looks like this, \begin{equation} \tag{10} y = \frac{1}{1 + e^{-x}} \end{equation} and we can integrate it into Equation (9) by wrapping our summed ratio, using parameters $\beta$ and $\gamma$ to tune the shape, \begin{equation} \tag{11} D_{vote} = \alpha\left(\frac{1}{1+e^{-\beta(R+\gamma)}}\right) \end{equation} where \begin{equation} \tag{12} R = \sum_{m=1}^{M}\left[\left(\frac{P_{voted}}{P_{missed}}\right)\right] \end{equation} Choosing arbitrary values for the constants, $\alpha$ = 1, $\beta$ = 1 and $\gamma$ = -5, we can again simulate how $D_{vote}$ will evolve for a new user with no prior voting (12 months of misses) and perfect participation into the future. Plotting the network fee, $N_i$, as it decreases as the user votes: | ![](https://i.imgur.com/yxtv22o.png) | |:--:| | *Network fee that decreases as a user votes for several months.* | Observe that the logistic function produces a property where **a user must vote for several months before the discount grows significantly**. Another feature of this function the flat section to the right, where the fee stops decreasing. This gives the discount an effective cap, such that participation above some threshold gives no additional discount, which **limits the advantage of old users over new ones**. Now if we continue with this, we'll notice that with the function in Equations (11) and (12), a user could vote for a year or so then stop, and they would still keep the discount. If we want to encourage continued participation, **we can modify the function to cause the discount to expire or decay**. There are again several options to accomplish this, but I'll use our friend the logistic function once more because it can "turn off" the discount in the same way it turned it on. We can weight each participation ratio using this function with respect to the number of months into the past, which will cause old votes to lose their value after a period of time. Modifying Equation (12) in this way, we get, \begin{equation} \tag{13} R = \sum_{m=1}^{M}\left[\left(\frac{1}{1+e^{-\delta(R+\epsilon)}}\right)\left(\frac{P_{voted}}{P_{missed}}\right)\right] \end{equation} where $\delta$ and $\epsilon$ are parameters to tune the shape, similarly to $\beta$ and $\gamma$. Choosing arbitrary values of $\alpha$ = 1, $\beta$ = 1, $\gamma$ = -5, $\delta$ = -2, and $\epsilon$ = -14, we can simulate this discount decay mechanism for a user that votes for 12 months, then stops. | ![](https://i.imgur.com/vijohHO.png) | |:--:| | *Network fee that decreases as a user votes for several months and reverts after they stop voting.* | Observe that the **decay feature requires the user to continue participating to maintain their discount**, and if they stop, the discount is lost over time. If we put everything together, **we have created a mechanism (Equations (7), (11), and (13)) with the following objectives and corresponding features**: - A network fee discount is given for users that participate in DAO governance. - Users that vote more often and over a longer length of time receive larger discounts. - Abuse through spamming proposal submissions is mitigated. - The advantage that old users have over new ones is limited. - A user must continue participating to maintain their discount. Let's conclude by considering what we just did. We **started with some objectives**, and we showed how we can design a mechanism that achieves them. There are many ways to approach constructing designs, and this is all intended to illustrate a process more than to propose specific plans. So please don't get too hung up on the details of what's above. We have the freedom to engineer and tune all of this. Rather, **let's ask ourselves these questions:** - Are these our objectives, and are these the features we want? If not, what are they? - Are these features practical to develop and execute? - Is the added complexity and computational cost worth the value? - Are we ensuring that all mechanisms are safe and without risk of abuse? Do we need to add bounding to anything? Thanks for reading, and [please visit the SSV Discord](https://discord.com/channels/723834989506068561) to discuss these topics with the community :slightly_smiling_face: