PegNet Part Three: Conversions, Transactions, and more

A lot of the dust has settled on PegNet’s specification since my last blog. Mining and burning FCT have been launched with success and the implementation of transactions and conversions is underway, which means I can finally write this blog post about them. We’re also introducing a new way to grade miners, the motivation for which I’ll detail below.

Transactions & Conversions

Transactions and Conversions are very similar and PegNet is using the same chain and data structure to record both. However, we have opted to separate the logic for these. That means Transactions are operations where assets move from one address to a different address, and Conversions are operations where one asset is converted to a different asset but remains at the same address.

The reasoning behind this separation is threefold:

  1. Ease-of-use: A transaction is always 1:1. If you want to pay a bill of 100 pUSD, you don’t have to worry about current exchange prices at all, you just have to send 100 pUSD. This means a transaction from one party to another will always go through provided you have the necessary funds.
  2. Regulatory Concerns: PegNet’s ability to seamlessly change assets from one to another is new ground, where the rules aren’t exactly clear. Typically taxable events are between two parties but internal conversions are not tracked. By removing the ability to convert and transact at the same time, the hope is that PegNet conversions remain internal conversions. Though I have to point out that I’m a developer with minimal knowledge of tax laws and how it ultimately will be taxed will depend on your local laws.
  3. Faster Transactions: This is described in more detail below but by separating the logic, we can process transactions in the same block they’re sent, meaning they’ll take somewhere between 0 and 10 minutes to complete.

Conversions and Transactions are a work in progress slated to be completed in October.

Transactions

Transactions are very straightforward. If you send 100 pFCT from address A to address B, the recipient will receive 100 pFCT provided you have enough balance on address A. If you sent 123,456 pBTC from A to B, the recipient will get 123,456 pBTC. The only fee associated is the external 1 EC cost of submitting the transaction, but there are no internal PegNet fees.

Conversions

Conversions are the heart of PegNet. A lot of thought has gone into making them usable, safe, and fair. There are two key features that you need to know:

  1. There are two types of conversions
  2. Conversions are processed in the next block, meaning they’ll take somewhere between 10 and 20 minutes to complete

Conversion Types

At the time of submission, you don’t know the exact currency exchange rate that will be used at the time the conversion is processed, since that depends on the mining process. This has the downside of inconsistency in conversions.

Type A: I want to convert X pUSD to pFCT

This is the simple conversion from asset A to asset B. When it’s processed, it will convert all of the specified amount (ie pUSD) to the desired asset (ie pFCT) using the current exchange rate. This transaction can never fail as long as you have the required amount of assets in your wallet, which can be checked at the time of submission.

Type B: I want to convert enough pUSD to create Y pFCT

This is the more complex conversion, which creates a desired amount of asset B. When it’s processed, it will check your maximum allowed value of asset A and calculate to see if you have enough balance in order to create the specified amount of asset B. That means that Type B can fail due to a fluctuating exchange rate. However, it does give you greater control.

Here are some examples of Type B conversions:

For the sake of this example, I will use USD and BTC, where BTC has an average value of 10,000 USD, swinging between 9,500 and 10,500.

Example 1: I have a bill of 10 pBTC that needs to be paid urgently but I have 200,000 pUSD. I don’t have the time to wait for a favorable exchange rate. I create the following conversion:

  • Input: empty
  • Output: 10 pBTC

When the transaction is processed, the exchange rate happens to be 10,250 USD = 1 BTC. It sees that it would take 102,500 pUSD to create 10 pBTC. The balance allows up to 200,000. The conversion goes through, subtracting 102,500 pUSD from the balance and crediting 10 pBTC. The remaining 97,500 pUSD are not touched.

Example 2: I purchased an item worth 2 pBTC but I’m on a very tight budget this quarter. The bill doesn’t need to be paid for a couple of weeks so I’m trying to get the most out of my pUSD by waiting for an exchange rate of 9,600 USD = 1 BTC or better. I create the following conversion:

  • Input: 19,200 pUSD
  • Output: 2 pBTC

When the transaction is processed, the exchange happens to be 9,700 USD = 1 BTC. It sees that it would take 19,400 pUSD to create 2 pBTC and the conversion fails.

I see that it didn’t go through and submit the same conversion again. This time, the exchange rate happens to be 9,500 USD = 1 BTC. It sees that it would take 19,000 pUSD to create 1 pBTC. The conversion goes through, subtracting 19,000 pUSD to the balance and crediting 2 pBTC. The over-allocated 200 pUSD remain as pUSD.

Finality: Why 20 minutes?

As I mentioned above, the finality of transactions is the same block they’re submitted in. For conversions, it’s the next block. The reason is simple: we don’t want anyone to be able to trade with knowledge of the future. To explain this, let’s take a look at the Grade => Create => Mine => Write cycle of the Oracle, laid flat over two blocks:

PegNet behavior during two factom blocks

The Problem

If you recall, miners will pull the current exchange rates from APIs at the start of the block, between N and N+1. At the end of Block N, the exchange data is 10 minutes old. If conversions submitted in block N are processed at the end of block N, it can be exploited the following way:

  1. At minute N, the price of BTC is 10,000 USD = 1 BTC
  2. At minute N+8, the price of BTC is 10,100 USD = 1 BTC
  3. A savvy trader compares the prices and sees that BTC is going to swing up, so they convert 1,000 pUSD to pBTC
  4. At minute M, the trader is credited with 0.1 BTC using the exchange rate of minute N
  5. At minute M, the price of BTC ends up being 10,990 pUSD = 1 BTC, pretty close to the number in 2.
  6. At minute M+8, the price of BTC plummets down to 9,000 USD = 1 BTC
  7. The trader converts 0.1 pBTC back to pUSD
  8. At the end of block M, the trader is credited with 1,099 pUSD

With the ability to see around 9 minutes into the future, you can create essentially risk-free conversions that will always increase your net worth. The only way it can fail is if the price of the target currency swings down harder during minute N+8 to M than it swung up during minutes N to N+8. This process can be automated and will quickly spiral out of control. Backtesting has shown that this would have yielded around 8% daily using a USD-BTC trading scheme.

I want to give a shoutout to AroundTheBox here for his efforts of digging into this issue and kicking off the conversation.

The Solution

The solution PegNet employs is to only process conversions at the end of the next block, which uses exchange rates set at the beginning of that block. A conversion at minute N+3 will be processed at minute M+9 using the exchange rates set at minute M. It sounds confusing at first but it can be simplified down to this: a conversion will always use the earliest available exchange rates.

The downside is that conversions submitted at minute N won’t be processed until minute M+9, a 20-minute window, but the upside is that traders are subject to the whims of the marketplace. If you hold pBTC and the price of BTC suddenly plummets, you won’t be able to get all of your pBTC out before PegNet becomes aware of the change.

Burning

Burning ended up being very simple, since the ability to burn FCT already exists in the Factom Protocol. The way it’s done is by creating an entry credit purchase of zero entry credits to a specific address: EC2BURNFCT2PEGNETooo1oooo1oooo1oooo1oooo1oooo19wthin. The amount of FCT used as input (the transaction fee) is burned and will be credited as an equivalent amount of pFCT to the address that paid for the transaction. For every 1 FCT burned, you get 1 pFCT.

You can look up the above address in an explorer and see that people have already burned thousands of FCT. Or you can look at a chart on factoshi.io:

FCT burned

Grading V2

Work on Version 2 is complete and new clients have already been released. It will activate with block height 210330, some time around 17:00 UTC on Monday, Sep 16, 2019. In addition to the new grading algorithm, Palladium (pXPD) and Platinum (pXPT) are being dropped due to not having good sources of exchange rates available, and PNT is renamed to PEG due to a conflict with another project.

If you recall, V1 took 50 OPRs with the highest difficulty, then threw out the farthest outlier 40 times, leaving ten winners. After the launch, we noticed some discrepancy between the amount of records miners got into the top 50 vs the amount of records that made it to the top 10. The goal was that if you get one record into the top 50, it should make it to the top 10 at a rate of one-fifth of the time. This turned out not to be the case, with some miners who frequently made it into the top 50 never managing to win at all.

This turned out to be caused by the different exchange rates reported by different APIs. Miners who were configured to use different APIs than the majority were disfavored in the grading process. Ultimately, it led to miners sharing config settings to coordinate the configuration that would yield the most “accurate” numbers. Miners who aren’t active members of the community would have been unaware of this, however, and so we looked for a more optimal solution.

How it works:

  1. Select 50 OPRs with the highest difficulty
  2. Calculate the normalized average for every asset
  3. Throw out the OPR with values farthest from the average using a band of 1%
  4. Repeat steps 2 and 3 until there are 25 left
  5. Every OPR in 4. gets awarded 200 PEG
  6. Repeat steps 2 and 3 until there is one OPR left but this time without the band
  7. The remaining OPR is the winner

The band is a step during the calculation of the “distance” to the average. If a value is within 1% of the average, it counts as distance 0 and all distances greater than 1% are moved up. This effectively means there is a 1-2% tolerance between different exchange APIs, allowing for a much broader configuration.

The other key change is that the winner no longer gets 800 PEG but more miners are rewarded. The total PEG payout every block remains the same. Overall, this results in miner rewards being closer to their overall percentage of hash power.

A Visual Explanation

Let’s assume for a moment that we can plot OPR exchange rates on a two-dimensional graph to illustrate how the grading process works. We have five different clusters, with the majority being blue dots. Red and green are mostly using the same set of APIs with some differences. Magenta and Cyan forgot to configure their miners right and are using the fallback APIs, which have stale data:

(the real graph would have 30 axes instead of just 2)

The band can be visualized as an area around the average value. All values inside of that area are considered to be “at the center”. That means effectively the graph looks like this:

As if every OPR inside the band landed on exactly the same spot. When two OPRs have the same distance, proof of work is used to break the tie. Since the majority of APIs all fall into the 1% band, grading will more likely reward miners based on their proof of work.

Why 1%?

We’ve done a lot of research into this topic and settled on 1% because it works for most of the APIs in our set and works as a compromise between the algorithm doing what it’s supposed to do and allowing for a wide variety of APIs. I collected about five day’s worth of samples from all APIs (both business days and weekend) and calculated the maximum band:

Percentage difference between the lowest and the highest price point sampled every 10 minutes

The full data is available as a 33-sheet spreadsheet: https://docs.google.com/spreadsheets/d/1uy5cbFaRUNA0QN8pPQvzo61slWUwAY2NXGeVKmN6lXA/edit. The first sheet calculates the maximum band for all assets, where lines going above the “1” line indicate that they would not have made it inside the band. The other sheets contain data for a specific asset. For example, the USD-EUR exchange rates remain the same at the end because the markets are closed:

Price of USD-EUR over five day period, sampled every 10 minutes

But USD-Bitcoin is traded even on weekends, providing steady data:


Price of USD-Bitcoin over five day period, sampled every 10 minutes

Not The End

This concludes describing the core PegNet functionality and once Transaction and Conversions are working, PegNet will be operational, but that doesn’t mean it’s finished. Far from it. That’s only the beginning of a hopefully long and prosperous journey.

If you want to take part in that journey, check out: