owned this note
owned this note
Published
Linked with GitHub
[](https://)# Token design
## Token flow
![Token flow](https://i.imgur.com/KXGfh7S.png)
Three major sub-flows:
1. Spam prevention
2. Rewards
3. Staking
## Spam prevention
- Tokens are staked by block producers as collateral against any spam that they might send
- Optionally, they may outsource this to an attester in exchange for a fee
- The deposit entitles a producer to send a given amount of data through the network
- Any data exceeding this limit is simply dropped, acting as a rate limit to ensure the slashing mechanism isn't overwhelmed
- After propagation through the network, spam checkers verify that the message is not spam
- If they determine it to be spam, they submit a proof to the deposit contract and trigger the slashing mechanism
- *The more data (and people) that needs to be sent through the network, the more stake is locked up as deposits*
## Rewards
- Receivers pay into a monthly subscription fee pool (may be any mix of tokens/coins supported on Ethereum)
- A subsidy pool is provisioned to bootstrap the network in the initial stages (with Marlin native token, POND)
- Attested blocks flow from the producer through the relayers to the receivers
- Receivers send tickets to (a subset of) relayers to confirm timely block delivery
- Relayers submit tickets to the subscription and inflation pools in exchange for fees and rewards
- *The more people that need to receive data from the the network, the more tokens that are locked up in the fee pool **on a monthly recurring basis***
## Staking
- Stakers and delegators stake tokens in a staking pool of their choice
- They can of course choose to stake in their own personal "pool"
- Staking pools redelegate the stake towards different relayers in exchange for rewards
- As indicated above, relayers can set up personal pools and delegate towards themselves
- Rewards are modified by the [Cobb-Douglas utility function](https://en.wikipedia.org/wiki/Cobb-Douglas_production_function) before they are received by the relayers
- Of the form $(r/R)^\alpha * (s/S)^{1-\alpha}$
where
- $r$ = Relayer rewards
- $R$ = Total rewards
- $s$ = Relayer stake
- $S$ = Total stake
- $\alpha$ = System parameter
- Rewards are maximized when the ratio $r/s$ is a constant depending only on $\alpha$
- This ensures that people are incentivized to stake in proportion to their rewards and vice versa, run nodes in proportion to the stake delegated to them which is crucial for security
- Another way of looking at it is people have a fixed amount of resources they are willing to put towards the Marlin network, the above function incentivizes them to split the resources optimally between participating (by running nodes) and securing (by staking), both of which are critical for long term viability
- Positive feedback loop encouraging sustainable network growth
- If relayers are delegated more stake, they are incentivized to run more nodes to increase tickets
- If more people start using the network and relayers receive more tickets, they are incentivized to stake more (or attract more delegations)
- Some nice things about the function:
- Stable equilibrium ratio between activity and security
- Optimal strategy is individual, not collective
- i.e. even if other people don't stake in the optimal ratio, rewards are maximized for an individual when he does it optimally
- No coordination needed
- This also means people don't need to periodically rebalance their resources just because *other people* started running more nodes or staking
- Equilibrium is stable from an individual perspective as well
- *The more bandwidth capacity used by the network (both in terms of unique data as well as receiver numbers), the more stake is locked up towards relayers*
## Remarks
- The roles given above aren't exclusive
- Relayer would almost always also be a staker/delegator
- Receiver would almost always also be a spam checker
- Etc
- Implementation details which don't affect the system a lot are omitted for brevity
## The network tokens
Marlin uses POND and MPOND tokens as part its token economy.
### POND
POND is a standard ERC-20 token contract with a total supply of 10 billion. Network rewards via the subsidy pool for work done by relayers as mentioned above are distributed in POND. POND may delegated to relayers and subject to slashing penalties if the relayer its delegated to doesn't follow the protocol.
### MPOND
MPOND is Marlin's governance and staking token. It can used to create and vote on proposals. It is also required to run a Marlin node - every Marlin node requires a certain amount of MPOND staked or delegated.
#### Properties
- Total supply of MPOND is 10,000.
- Every cluster is cumulatively required to have atleast 1 MPOND staked or delegated.
- MPOND can be used to vote and create proposals, where 1 MPOND tokens = 1 vote (votes are fungible as tokens).
- MPOND tokens delegated to other users will be locked.
- Direct MPOND transfers will be locked except for whitelisted addresses (like the bridge and stakedrop contracts). Until universal transfers are enabled, only transfers to/from whitelisted addresses are possible.
- MPOND can be converted to POND via the bridge.
- If delegated or staked, users will first have to unlock the tokens before being able to make a transfer.
### Bridge
A bridge contract is used to convert between MPOND and POND. 1 MPOND can exchanged for 1 million POND tokens and vice-versa via the bridge.
#### POND to MPOND
POND can be converted to MPOND by sending POND to the bridge and an equivalent number of MPOND (#POND/1m) is received on the same address while burning the POND tokens sent.
#### MPOND to POND
The bridge also allows conversion of MPOND to an equivalent number of POND (#POND X 1m). However, the conversion is a bit nuanced and not instantaneous as above. The mechanism is described below.
A request can be made on the bridge to convert a certain number of MPOND (say P). After transfer request is made, there is a wait time of W blocks before a conversion can be attempted. During the wait time, MPOND can still be used towards staking and governance. After the wait time, a fraction L of P MPOND can be sent to the bridge for conversion.
Parameters W and L are both controlled by governance. These parameters make sure that there are always enough MPOND locked to ensure that the security of the network and its governance is not compromised. After every W blocks, $L$ of P MPOND requested initially can be sent to the bridge for conversion. That is, if W and $L$ remain constant, the user can convert all the requested MPOND to POND in $\lceil{\frac{100}{L}}\rceil*W$ blocks.
A series of scenarios and expected results of calls made to the Bridge are illustrated in the table below.
| Timespan | MPOND balance | Call Maxima | Result | Maxima mapping | Maxima used mapping | Liquidity | Effective Liq. (calculated) | Call convert | Result |
|----------|---------------|-------------|--------|------------------|---------------------|-----------|-----------------------------|--------------|--------|
| Day -1 | 1000 | | | {-1:0} | | 0% | | | |
| Day 0 | 1000 | 1100 | reject | {-1:0} | | 0% | | | |
| Day 0 | 1000 | 900 | accept | {0: 900} | {0:0} | 0% | | | |
| Day 30 | 1000 | 50 | accept | {0: 900, 30: 50} | {0:0, 30:0} | 0% | | | |
| Day 31 | 1000 | 100 | reject | {0: 900, 30: 50} | | | | | |
| Day 180 | 1000 | | | {0: 900, 30: 50} | {0:0, 30:0} | 0% | | 950, 0 | reject |
| Day 180 | 1000 | | | {0: 900, 30: 50} | {0:0, 30:0} | 10% | | | |
| Day 180 | 1000 | | | {0: 900, 30: 50} | {0:0, 30:0} | 10% | | 85, 0 | accept |
| Day 180 | 915 | | | {0: 900, 30: 50} | {0:85, 30:0} | 10% | | 10, 0 | reject |
| Day 180 | 915 | | | {0: 900, 30: 50} | {0:85, 30:0} | 5% | | 10, 0 | reject |
| Day 180 | 915 | | | {0: 900, 30: 50} | {0:85, 30:0} | 10% | | 10, 0 | reject |
| Day 180 | 915 | | | {0: 900, 30: 50} | {0:85, 30:0} | 10% | | 2, 0 | accept |
| Day 180 | 913 | | | {0: 900, 30: 50} | {0:87, 30:0} | 10% | | | |
| Day 210 | | | | {0: 900, 30: 50} | {0:87, 30:0} | 10% | | 10, 30 | reject |
| Day 210 | | | | {0: 900, 30: 50} | {0:87, 30:0} | 20% | | 10, 30 | accept |
| Day 211 | | | | {0: 900, 30: 50} | {0:87, 30:10} | 20% | | 100, 0 | reject |
| Day 212 | | | | {0: 900, 30: 50} | {0:87, 30:10} | 20% | 20% | 93, 0 | accept |
| Day 213 | | | | {0: 900, 30: 50} | {0:180, 30:10} | 20% | 20% | | |
| Day 360 | | | | {0: 900, 30: 50} | {0:180, 30:10} | 20% | 40% | | |
| Day 390 | | | | {0: 900, 30: 50} | {0:180, 30:10} | 15% | 30% | | |
#### Properties
* POND can be instantly converted into MPOND with 1MPOND yielded against 10^6 POND.
* To convert MPOND to POND, there is a delay of atleast W blocks.
* At any point after W, $min(100, liquidityRatio*floor[(time since request)/W])$ % of the total requested amount, including all previous conversions for the request, can be transferred to POND.
* If POND/MPOND are staked/delegated, then they can’t be transferred to the bridge.
* During wait period, MPOND can be used for governance and staking.
* User can partially/fully cancel conversion requests from MPOND to POND at any time, even after wait time is over as long as the conversion is not completed.
## Staking contract architecture
### Phase before FlowMint: Bootstrapping clusters in the absence of enough gateways to sign receipts
#### Requirements
- Clusters will join as a single entity and stake
- Stake should be more than a minimum for them to be active
- Any one with POND/MPOND should be able to delegate their stake to clusters.
- Clusters need a minimum amount of MPOND staked/delegated to be considered active in the registry
- Reward that cluster receives is distributed to the people who delegated stake weighted by the amount of stake. The calculated reward will be given to the delegator after the cluster takes a commission.
- Clusters can be configure their commissions (its not fixed)
#### Staking contract
- Users can lock their stake with a staking contract and delegate it to any cluster.
- Users can create multiple such stake locks and delegate to different clusters.
- User can undelegate their stake
- Undelegation involves a certain bonding period
- User can redelegate undelegated stake
- User can withdraw stake
#### Cluster contract
- This contract manages the clusters, their info like commission percent and reward address.
- Manages cluster entry and exit
- Calculates total stake with cluster and it’s delegators
#### Performance registry
- This registry provides the performance information of every cluster which was active during the last epoch.
#### Distribution Contract
- Rewards will be fixed for an epoch
- Based on the data from performance registry and stakes of the cluster, rewards are distributed
- Rewards can be claimed by delegators less the commission of the cluster
- Cluster owner can also claim rewards (including commissions from delegators)
### FlowMint: Bootstrapping gateways
Read more at https://hackmd.io/vxEd8aLBRL-Gcj4RVokZ5g?view
API: http://34.93.40.96:3001/api-docs/
### Phase after FlowMint: After enough gateways have joined the network
#### Types of Actors
- Delegators: Users who have tokens and would like to judiciously delegate their tokens to relayers so that they can gain part of their service rewards.
- Pools: Token pools where delegators can (but don't need to) stake and pool (enables staking companies to run multiple relayers without having their delegators to use different addresses for different relayers - can just have 1 pool address as the interface)
#### Requirements
- Users who have tokens can delegate them to relayers in 2 ways
- Directly delegate to relayers
- Delegate them to Pools which delegate to relayers on behalf of the users
- Users who delegate tokens to relayers get rewarded a fraction of what the relayer earns.
- fraction is decided by relayers
- Some tokens from the stash account are bonded to a controller account
- Controller account controls all non funding operations onchain
- Stash account that holds all the balance and involves adding more funds
- Session keys that are the keys with which the relayer signs. The session keys need to be set by sending a tx from the controller account. Session keys are what binds controller to the relayer.
- Rewards earned can behave in the following ways
- Go to stash and staked to self
- Go to stash and staked to someone else
- Go to controller
- Go to a payment address
- Set a proxy address which can do the following
- Any action
- Non transfer
- Governance
- Staking
- Set onchain identity for the address
#### Actions
- User has tokens
- User has to bond those tokens to a controller to begin staking. Once bonded that money is locked.
- Same controller can’t be used for 2 stashes
- Controller has control over unbond funds and everything else
- Stash address can add funds and change controller
- Same stash can’t have 2 controllers.
#### Architecture
##### Stashing Contract
- Users can send tokens to the stashing contract and set a controller.
- Controller can be same or different than stashing address but different is recommended
- Same user can create another stash with another controller. But not with same controller
- User can add funds to an existing stash
- Once a stash is created, it can be delegated to another address by the controller.
- If not delegated the stash is not delegated to anyone by default.
- You can create stash and delegate in one go as well.
- Users can unbond tokens to a stash, there will be a waiting time based on the waiting period for relayer unbonding time.
- Once unbonding time is done, user can withdraw the tokens
- When a stash is created, the user has to specify how the rewards for this needs to be distributed.
##### Allocation Contract
- When a user delegates to another address, this data is added here.
- The delegated address can stake it to any relayer or a group of relayers
- If multiple relayers are delegated to, then incase of any addition of stake. It will be unallocated to any of the existing relayers unless specified.
- The unallocated stake can be allocated by the delegated address to any of the existing/ new relayers.
- In case of withdrawal of stake, the last relayer to whom stake was added, will lose the stake. Delegated address can specify the relayer to withdraw from first as well.
- If user delegates to self, then also user has to set the relayer in the allocation contract
- Any changes to the stash (add/remove) will be reflected in the allocation contract
##### Relayer Contract
- Gets the stake data from allocation contract and maintains cluster to relayer mapping
- Relayer should be able to join cluster, if min req are passed
- If the allocations are updated due to funds being bonded and unbonded, that should be reflected here.
- Cluster contract needs to be created beforehand for the relayers to join it.
- Relayers can add the session keys which will be used by nodes here.
##### Producer Contract
- Producer contract stores the producer account and the mapping to the session keys of producer
- A type of stash account can be created for producer as well
- Stash account will have a controller attached
- Stash account can be allocated to producer for producer staking