Name: Continuous payment of fees
Status: Draft - Rejected
Scope: Allow Darknode operators to collect fees second-by-second without needing to submit Ethereum transactions.
This proposal introduces the Operator Fee Token (OFT). This token is automatically paid to operators per-Darknode per-block. For example, if an operator owns 10 Darknodes, then the operator will receive 10 OFT tokens per block. OFT tokens can be burned for a proportional share of redeemable fees. For example, burning 1% of the OFT supply entitles you to 1% of the redeemable fees.
Fees are paid to a non-redeemable pool. Every block, 0.0002865% of the non-redeemable pool is moved to the redeemable pool. Assuming Ethereum blocks are ~10 seconds, this equals a total payout of ~50% per epoch (the same as it is right now). At any point, Darknode operators are able to burn some or all of their OFT and redeem their share of the redeemable pool.
Right now, Darknode operators collect fees in discrete intervals through a process called “claiming”. Fees are paid to the Darknode Payment contract on Ethereum and at the end of the epoch 50% of the fees in that contract can be claimed by Darknode operators. However, for the claim to happen, each Darknode must explicitly submit an Ethereum transaction to call the
claim function on the Darknode Payment contract.
There are several drawbacks to this approach:
- Darknode operators must wait until the end of the epoch before fees are accessible. This creates opportunity loss, where Darknode operators are unable to utilise fees for an entire epoch.
- Darknode operators are bound to receive the fees. This means that the operators are unable to delegate fee collection to other addresses (for example, one could imagine that it would be desirable for an operator to automatically delegate their collected fees to a contract).
- Darknode operators must spend ETH so that their Darknodes are able to call the
claimfunction. In the latest epoch, each Darknode had to spend just under $7 USD to
claim. This essentially doubles the operating costs of a Darknode, and requires regular attention from the operator.
- In the future, we want to be able to compute fees on RenVM instead of on the minting chain (e.g. Ethereum). The use of an explicit Darknode Payment contract, bound to pay fees to an exact address (the operator), does not make for a smooth transition away from Ethereum.
- Darknodes need to claim fees every epoch. This puts restrictions on how often epochs can happen. Having 24 hour epochs would cause Darknode operators to spend $6 per day per node (which is clearly unacceptable). See RFC-000-001: Continuous payment of fees.
The OFT will be an ERC20 with some unique implementation details:
- OFT has a special
balance_ofimplementation that deviates from the norm:
This will result in the
def balance_of(addr): return balances[addr] + (now - updated_at[addr]) * num_nodes[addr]
balance_offunction returning different values even when no transfer are made. However, this will only be observed for operator addresses. All other addresses remain unaffected, because
num_nodes[addr]would be zero.
- OFT transfers must do
balance[addr] = balance_of(addr)before running the usual transfer logic, for both the sender and receiver, and must set
updated_at[addr]to the current block for both the sender and receive.
- Darknode being de/registered must update
addris the address of the operator. The same transaction must also set
balance[addr] = balance_of(addr)and set
updated_at[addr]to the current block.
The FeePool will be the contract that receive all fees from the Gateways (all Gateways for all renTokens will send their fees to the same FeePool contract).
- There will be a
redeemfunction that burns the OFT out of existence in exchange for a share of the redeemable fees. This function also updates the redeemable fee amounts. Some pseudo code:
def redeem(amount, to): OFT.transferFrom(msg.sender, this, amount) for token in renTokens: redeemable[token] += (token.balance_of(this) - redeemable[token]) * pow(1 + rate, now - updated_at) update_at = now for token in renTokens: token.transfer(to, redeemable[token] * amount / OFT.total_supply())
ratevariable in the FeePool should be subject to governance by RenVM. Initially, the value will be set to 0.0002865% per block so that the payout rate of the FeePool matches the current payment mechanism (50% every 4 weeks).
As is seen in the pseudo-code for the FeePool
redeem function; gas is spent withdrawing every token every time OFT is burned. While this approach might be an acceptable overhead, an alternative is to have a different OFT for every available token that fees can be earned in. See RFC-000-001: Continuous payment of fees.
- Develop, test, and audit the OFT contract.
- Develop, test, and audit the FeePool contract.
- Upgrade the Gateway contract to mint fees to the FeePool.