HackMD
  • Beta
    Beta  Get a sneak peek of HackMD’s new design
    Turn on the feature preview and give us feedback.
    Go → Got it
      • Create new note
      • Create a note from template
    • Beta  Get a sneak peek of HackMD’s new design
      Beta  Get a sneak peek of HackMD’s new design
      Turn on the feature preview and give us feedback.
      Go → Got it
      • Sharing Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • More (Comment, Invitee)
      • Publishing
        Please check the box to agree to the Community Guidelines.
        Everyone on the web can find and read all notes of this public team.
        After the note is published, everyone on the web can find and read this note.
        See all published notes on profile page.
      • Commenting Enable
        Disabled Forbidden Owners Signed-in users Everyone
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Invitee
      • No invitee
      • Options
      • Versions and GitHub Sync
      • Transfer ownership
      • Delete this note
      • Template
      • Save as template
      • Insert from template
      • Export
      • Dropbox
      • Google Drive Export to Google Drive
      • Gist
      • Import
      • Dropbox
      • Google Drive Import from Google Drive
      • Gist
      • Clipboard
      • Download
      • Markdown
      • HTML
      • Raw HTML
    Menu Sharing Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Versions and GitHub Sync Transfer ownership Delete this note
    Export
    Dropbox Google Drive Export to Google Drive Gist
    Import
    Dropbox Google Drive Import from Google Drive Gist Clipboard
    Download
    Markdown HTML Raw HTML
    Back
    Sharing
    Sharing Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    More (Comment, Invitee)
    Publishing
    Please check the box to agree to the Community Guidelines.
    Everyone on the web can find and read all notes of this public team.
    After the note is published, everyone on the web can find and read this note.
    See all published notes on profile page.
    More (Comment, Invitee)
    Commenting Enable
    Disabled Forbidden Owners Signed-in users Everyone
    Permission
    Owners
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Invitee
    No invitee
       owned this note    owned this note      
    Published Linked with GitHub
    Like2 BookmarkBookmarked
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 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

    Import from clipboard

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lost their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template is not available.


    Upgrade

    All
    • All
    • Team
    No template found.

    Create custom template


    Upgrade

    Delete template

    Do you really want to delete this template?

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Tutorials

    Book Mode Tutorial

    Slide Mode Tutorial

    YAML Metadata

    Contacts

    Facebook

    Twitter

    Feedback

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions

    Versions and GitHub Sync

    Sign in to link this note to GitHub Learn more
    This note is not linked with GitHub Learn more
     
    Add badge Pull Push GitHub Link Settings
    Upgrade now

    Version named by    

    More Less
    • Edit
    • Delete

    Note content is identical to the latest version.
    Compare with
      Choose a version
      No search result
      Version not found

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub

        Please sign in to GitHub and install the HackMD app on your GitHub repo. Learn more

         Sign in to GitHub

        HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Available push count

        Upgrade

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Upgrade

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully