It’s been a while since I’ve chimed in here, but I want to bring into this official proposal some context of a piece of very relevant discourse that the one and only @PoktNews has highlighted in the past week, because I think it is a piece that is important, although buried in what is a very complex and deep proposal here.
Overview
https://x.com/PoktNews/status/1809583495804510376
Assuming that the embed feature for posts has been broken, it is a reply to this callout.
Open vector for bad actors to exploit Morse. Certain gateway operator can send fake relays (fake demand) and print coins out of thin air. Something that shouldn’t be possible in case that Grove and PNF management is closely tied.
These callouts of themselves shouldn’t be something that ultimately blocks a single party from governing the parameters, but deeper transparency into the tokenomic emissions control that is possible from this is a piece of transparency that should be highlighted, because I know this community of individuals has the ability to understand what they would require to have transparency that the kind of funny business that isn’t possible isn’t happening.
This all being said, having been someone that worked on the Grove team at one point, this notion of self dealing was well understood, and any work done internally was with the perspective of not allowing this behavior at bay to happen. These points don’t represent my views about if this proposal should or should not move forward, but rather to make sure those who are independent actors in the DAO have a wider view of the possible implications of what can be possible when turning off the gateway burn mechanism, paired with having full control of new network token emissions.
He Who Controls the App Keys Controls the Token Distribution
Fundamentally in Morse, the app key is the control point of token emissions. This was the motivation for keeping the gateway run by Grove, and was one of the original motivators for the migration away from Morse, and moving the system to a sampling based mechanism.
The problem that exists in Morse, is that if you simultaneously hold both an app key and the node key for a given app/node session pair, the owner of that app key can, for every session where they’re matched with their own nodes, simply sign randomized data and generate the corresponding Merkle Proofs against random streams of data. This means that if an app is able to pair itself with up to X nodes in a session, that party can generate X/24 (current nodes per session) of the total allocation of relays staked to that application fee.
What’s very important to consider here, is that if a Gateway operator also operates a majority of the node network for a given chain, they can mint a significant amount of that corresponding chain’s full bandwidth of relays without having to ever service the underlying RPC data.
Additionally, there is nothing that forces a gateway to send relays to all nodes in a session. Internal ranking systems like the cherry picker were built in a good faith way to properly tie rewards to meaningful quality of service. A third party gateway can send relays to only nodes that they want, possibly only the nodes they control.
The introduction of a burn mechanism for gateway actors completely eliminated any economic incentive for that app key owner (currently a gateway) to indulge in this kind of behavior.
Gaming Custom Network Rewards and No DAO Approval System for New Chains
This is a very important piece. Because while it would be clear that a gateway is sending it’s tokens only to it’s nodes in the long term, the real economic gain to be had here is to race to stake as many nodes on the new chain that the gateway can service. If there isn’t the same open process for onboarding a new chain to the protocol, there is an insider advantage to getting ready to allocate enough tokens to stake a majority of the early nodes on a new chain. Pairing this with incentivized bootstrapping rewards and a lack of burn, means that gateway operators who would be advantaged to quickly stake a lot of nodes on a new chain can simply mint themselves as many tokens as they can.
It is very important to note, that this isn’t about net inflation rate, rather total concentration of capture of new token emissions.
What Pieces Need to Be Watched
Again, I don’t inherently see these as risks that can keep this proposal from moving forward, but there are some important questions that other node runners should be asking to have the full picture of the implications for the impact to their network work reward share.
The App Stake Amounts for Gateway Operators
Specifically, what is important for node runners to know is how many relays an application is entitled to with their stake. If a new gateway manages to come into the system, what is the maximum amount of relays that the gateway can send?
This isn’t magic, these numbers are knowable from on-chain data, but the changes made with Gigastakes do make the total possible amount of relays a gateway can send at a number that might shock everyone involved.
Will these parameters still remain in place?
The Relationship Between Gateway Operators, and New Chain Node Shares
The other piece that should be watched, and again, can be from on chain data, is if gateway operators also magically end up being the fastest and first to support new chains.
As there will be new chain incentives, the opportunity to game this system is at its strongest in the time immediately after a new chain launch.
App Stake Growth
Assuming that the solution for this would be to force the gateways to actually stake app sizes relative to service, the economic game would become that it is more beneficial for a node runner to pour rewards into more app stakes than staking more nodes.
What makes me a little uncomfortable is I called out this mechanism in some earlier protocol work, but that has seemed to disappear from the public GitHub repo on what was the V1 protocol.
I’m going to leave the math here, because I know that there are some brilliant data engineers in the community who are fully able to absorb and model these implications and bring this back to the community.
Economic Security Guarantees
The idempotency requirement however does not protect against the above when the
same actor controls:
- $50% + 1$ of the $S$ nodes in a session
- The application sending the requests
For a given relay chain ID, assume that there exists $a$ existing apps, and
there are $n$ total existing nodes already staked for the relay chain.
The probability of a single node being selected for a session should be
$\frac{1}{n}$.
As session selection currently happens as random selection with replacement,
then we can represent the probability of controlling the majority of a session
as the probability of having between $\lfloor \frac{S}{2} \rfloor + 1$ and $S$
successes in $S$ attempts of an $\frac{m}{n}$ discrete event, assuming that $m$
represents the total number of nodes that the actor has staked on that relay
chain. We model this using the binomial distribution, with $p = \frac{m}{n}$
and
$n \in \lbrace \lfloor \frac{S}{2} \rfloor + 1, \lfloor \frac{S}{2} \rfloor+ 2, …, S \rbrace$
$$
P_{MC}(m,n,S) := \sum_{k=\lfloor \frac{S}{2} \rfloor + 1}^{S}{\binom{S}{k} \left(\frac{m}{n}\right)^{k}\left(1 - \frac{m}{n}\right)^{S-k}}
$$
This is the probability of controlling a session for an arbitrary app. Assuming
that the same actor controls $a$ apps, then the probability that the actor is
able to fully control at least one session for their own application would be:
$$
P_{SD}(a,m,n,S) := 1 - \left(1 - P_{MC}(m,n,S)\right)^{a}
$$
Then given $R :=$ application/BaseRelaysPerPOKT
, $B :=$
pos/BlocksPerSession
, and $N :=$ pos/StakeMinimum
, the cost of a configuration
of $a$ app stakes and $m$ node stakes, for which the probability of capturing a session
can be calculated via $P_{SD}$, is computed as follows:
$$
C(a,m,R,S,B,N,T) = \frac{100aBS}{R} + mN
$$
Economics Code Sample
from functools import partial
import numpy as np
def p_binom(n: int, p: float, k: int) -> float:
return (
np.math.factorial(n)
/ (np.math.factorial(k) * np.math.factorial(n - k))
* p ** (k)
* (1 - p) ** (n - k)
)
def p_majority_session(
nodes_staked: int, total_nodes: int, nodes_per_session: int
) -> float:
start = nodes_per_session // 2 + 1
end = nodes_per_session + 1
binom = partial(p_binom, nodes_per_session, nodes_staked / total_nodes)
return sum(map(binom, range(start, end)))
def p_self_dealing(
apps_staked: int, nodes_staked: int, total_nodes: int, nodes_per_session: int
) -> float:
return (
1
- (1 - p_majority_session(nodes_staked, total_nodes, nodes_per_session))
** apps_staked
)
def cost(
apps_staked: int,
nodes_staked: int,
pokt_to_usd: float,
nodes_per_session: int = 24,
base_relays_per_pokt: int = 200000,
stake_minimum: int = 15000,
) -> float:
apps_cost = (
apps_staked
* nodes_per_session
/ (base_relays_per_pokt / 100)
)
nodes_cost = nodes_staked * stake_minimum
return (apps_cost + nodes_cost) * pokt_to_usd
print(1 / p_self_dealing(10, 150, 350, 24))
print(cost(10, 15, 0.07))
This work was about the economics of a node/app pairing gaining a majority control of the truth of a session, i.e. 51% percent control. In this case, this math is capturing the assumed cost of a network actor gaining that 51% control, but it can be easily extended to see the implications of how the current network stake topology could lead to outsized distributions of these newly proposed token mechanisms.