owned this note
owned this note
Published
Linked with GitHub
# PMTP - (Old Draft 3/2)
Protocol Monetary Trade Policy (PMTP) enables monetary policy for Rowan enforced by Sifchain’s liquidity.
Problem Statement:
- Premise: Through inflation, Rowan holders use a standard tool in the cryptocurrency monetary policy toolkit.
- Problem: Rowan holders seek alternative monetary policy options.
- Solution: Protocol Monetary Trade Policy is a viable alternative, using Sifchain’s liquidity to influence trade on its DEX.
This “Protocol Monetary Trade Policy” feature opens a new space in cryptoeconomic design. We’re naming our first implementation of a feature of this kind after the category for now. Hopefully, the name sparks additional creativity in the ideation of future extensions or alternative methods of execution.
## PMTP Basics
Sifchain’s liquidity pool code sets a price ratio for assets in its two-sided liquidity pools. The formula for this price ratio for a given swap is:
$$y(x)=\frac{xYX}{(x+X)^2}$$
Please see [AMM Specification](https://hackmd.io/6VK2LSYjRTyeNCoHpVt2hg) for more details including variable definitions and the derivation of this formula.
The formula above is modified to accomodate weighting of the X and Y tokens in the pool as follows:
$$y(x)=Y(1-(\frac{X}{x+X})^\frac{w_x}{w_y}) (1-\frac{x}{x+X})$$
subject to the constraint $$ w_x + w_y = 1$$
Thus giving the PMTP mechanism.
Here, $w_x$ and $w_y$ control the weight that is assumed for each token in the pool, removing the implicit pre-existing assumption that equal quantities in the pool result in equal prices (equivalently, the special case where $w_x=w_y=1/2$). The variables $w_x$ and $w_y$ are analogous to the weights $W_i$ and $W_o$ in the [Balancer Whitepaper](https://balancer.fi/whitepaper.pdf), check there for further explanation.
For the first version, governance can set this ratio and a target block height by which that ratio should be achieved. The protocol will shift the ratio to be closer for every block until it reaches its target.
## Monetary Policy and Trade Policy
Fiat currency managers use monetary policy to influence the interest rates for short term borrowing or the supply of money. They use trade policy to influence the rate at which goods in their sovereign domain are exchanged.
The PMTP feature allows Sifchain governance to combine the two objectives by influencing exchange rates amongst assets (trade policy) to influence currency-wide purchasing power (monetary policy).
Most cryptocurrencies influence monetary policy through inflationary rewards. This is increasing the quantity of tokens a token holder has to trade. Protocol Monetary Trade Policy allows Sifchain governance to instead influence the number of opportunities a currency holder has to trade their existing quantity of tokens at a specified ratio.
Note that setting $w_x$ and $w_y$ does not necessarily set $P_{x,y}$. Market participants inside Sifchain's DEX and outside it will be able to swap tokens freely and shift the ratio of X and Y in Sifchain's liquidity pools.
## Track Purchasing Power Multiplier
Goal: On a per block basis, we need to increase the purchasing power multiplier $r_{running}$ so that it fits the constraints set by governance parameters. We outline this in the subsequent steps and have a numerical computation example in the spreadsheet in Appendix 1.
### Variable Definitions
| Variable Name | Descriptive Name | Description | Symbol |
|----|----|----|----|
| start_block_height | Start Block Height| First block of a given policy period| $h$ |
| final_block_height| Final Block Height | Last block of a given policy period| $h_F$ |
| current_block | Current Block | Current block | $h_{current}$ |
| epoch_length | Epoch Length | Number of blocks in an epoch | $epoch\_length$ |
| policy_length_in_epochs | Policy Length in Epochs | Number of epochs in the policy | $number\_of\_epochs$ |
| gov_rate | Gov Rate | Per-epoch (approximately daily) rate of purchasing power increase voted in by governance | $r_{gov}$ |
| final_compounded_rate | Final Compounded Rate | Overall rate of increase over the policy length| $final\_compounded\_rate$|
| block_rate | Block Rate| Incremental increase on a per block basis to reach ${final\_compounded\_rate}$ | $r_{block}$|
| running_rate | Running Rate| The purchasing power multiplier rate at a given block | $r_{running}$ |
| y_o | y_o | $y$ amount resulting from the swap at the starting time. Calculate the value of y that a user would get if there was no purchasing power increase. | $y_o(x)$ |
| x_weight | X Weight | Exponent weight for Rowan | $w_x$ |
| y_weight | Y Weight | Exponent weight for non-Rowan token | $w_y$ |
#### Additional Details on these Variables:
The total duration of a policy is the span of blocks between $h$ and $h_F$
The duration of the policy can be divided into epochs which are sections of blocks of equal length. An obvious option for epochs would be one epoch per day. Of course, this would need to be measured against an average block duration as not all blocks have equal duration. For example, if blocks were approximately 5 seconds long then an epoch would be 17280 blocks, but because the blocks were not exactly 5 seconds long the epochs would not be exactly 1 day long.
The epoch are a user experience affordance to make governance reasoning about the effects of PMTP in intuitive units.
### Use $r_{gov}$ to Derive $r_{block}$
Let $r_{gov}$ be the per-epoch rate increase voted in by governance. Each epoch, the purchasing power of Rowan (treated as the $x$ token in the above formulas) should increase by this percentage.
Let ${final\_compounded\_rate}$ = $(1 + r_{gov}) ^ {number\_of\_epochs} - 1$. Rowan should increase by this percentage between $h$ and $h_F$ (ie. across all epochs).
Now we compute $r_{block}$:
$$r_{block} = (1 + r_{gov}) ^ {{number\_of\_epochs}/{h_F}} - 1$$
$r_{block}$ function derivation can be found in Appendix 1 at the end of this document
** From this point onward we only focus on blocks. Given a block rate calculated at the initial governance decision, there is no further role for the epoch rate or to keep track of epochs. The block rate is not recalculated again after the initial goverance decision, so a token against which Rowan is losing value in the original pricing $y_o$ will not reach the implied governance target.
### Use $r_{block}$ to Derive $r_{running}$
Let $r_{running}$ be the running rate that is compounded over time (at any particular block). Similarly
$$r_{running} = (1+r_{block})^i-1$$
where
$$ i = {h_{current}} - h $$
## Final Computations
Now that we know the purchasing power increases by $r_{running}$ for any given block, we can then use it to calculate $y(x)$ for a given swap as it occurs.
Step 1: Calculate the value of $y$ that a user *would get* if there was no purchasing power increase. We can call this value $y_o$.
$$y_o(x) = f(X,Y,x) = Y(1-(\frac{X}{x+X})^\frac{w_x}{w_y}) (1-\frac{x}{x+X})$$
We can even simplify this (for the policy start time) by just using the old swap formula instead.
$$y_o(x) = f(X,Y,x) =\frac{xYX}{(x+X)^2}$$
The two formulas are identical when $w_x$ = $w_y$ = $0.50$ which is the case for this particular step.
Step 2: Now that we have calculated $y_o$ we can use it to determine the value a user *should* get with the purchasing power increase. This value is y(x) and is the output of our swap function.
$$ y(x) = y_o(x) * (1+r_{running})$$
### Addendum
The weights are no longer as important for our calculations given this structure. If we choose to share the weights:
#### Deriving the weights $w_x$ and $w_y$:
Use the liquidity depth values $X$ and $Y$ at that given time, take the $x$ swap input to get the output $y$ as above, and calculate:
$$log_ba$$
where
$$a = 1-\frac{y}{Y(1-\frac{X}{x+X})} = 1-\frac{y(x+X)}{YX} $$
$$b = \frac{X}{x+X}$$
From this we can get the following weights for each block: $$w_x = \frac{log_ba}{1+log_ba}$$ $$w_y = 1 - w_x$$
## Computations for Swaps from TKN to Rowan
Now we look at swaps that go in the other direction. We take the swap formula for $y$ to $x$, which is the opposite of the formula above.
Step 1: Calculate the value of $x$ that a user *would get* if there was no purchasing power increase. We can call this value $x_o$.
$$x_o(y) = f(X,Y,y) = X(1-(\frac{Y}{y+Y})^\frac{w_y}{w_x}) (1-\frac{y}{y+Y})$$
We can even simplify this (for the policy start time) by just using the old swap formula instead.
$$x_o(y) = f(X,Y,y) =\frac{yXY}{(y+Y)^2}$$
The two formulas are identical when $w_y$ = $w_x$ = $0.50$ which is the case for this particular step.
Step 2: Now that we have calculated $x_o$ we can use it to determine the value a user *should* get with the purchasing power increase. This value is $x(y)$ and is the output of our swap function.
$$ x(y) = \frac{x_o(y)}{1+r_{running}}$$
** Note: We can calculate the weights $w_x$ and $w_y$ at each block from the earlier section (of Rowan to TKN swaps) and do not need to repeat here. The weights are the same from this perspective, and the only change is that we would raise the modified swap function to the $\frac{w_y}{w_x}$ power.
We have some example calculations in the spreadsheet in Appendix 3.
## Appendix
#### Appendix 1: Reference Spreadsheet
Shows a numerical example of using $r_{gov}$ to derive $r_{block}$, then using $r_{block}$ to derive $r_{running}$, computing $y_o$ from $r_{running}$, and finally calculating the weights $w_x$ and $w_y$. Random number generation was used for the inputs x, X, and Y. There are two examples: the first with one swap per block, and the second with zero, one, and or many swaps per block.
https://docs.google.com/spreadsheets/d/1jRHXJDZOfc-u_VWO8SCILPRF34JIEI6zDjRwcqmxAm8/edit#gid=1690856320
#### Appendix 2: Deriving $r_{block}$
$$ (1+r_{block})^{h_F} = (1+final\_compounded\_rate) = (1 + r_{gov})^{number\_of\_epochs}$$
$$ 1+r_{block} = (1 + r_{gov})^{{number\_of\_epochs}/{h_F}}$$
$$ r_{block} = (1 + r_{gov})^{{number\_of\_epochs}/{h_F}}-1$$
#### Appendix 3: Reference Spreadsheet for Swaps in Both Directions
The same per-block calculations can be used from the Rowan to TKN calculations, so $r_{block}$ and $r_{running}$ will be the same as in the other direction. We solve for $x_y$ as above in the case of TKN to Rowan swaps, and the spreadsheet highlights the different calculations for the PMTP-modified $x_y$ and $y_x$ based on the direction of the swap.
https://docs.google.com/spreadsheets/d/1jRHXJDZOfc-u_VWO8SCILPRF34JIEI6zDjRwcqmxAm8/edit#gid=1183483560
## MVP Goals
Establish a PMTP governance framework for managing monetary policy through time-based parameter selection over trade policy.
## Future Goals
Extend the PMTP governance surface to include parameter selection for trade policy based on trading activity
## Further Reading:
https://www.nber.org/system/files/working_papers/w18092/w18092.pdf
https://arxiv.org/pdf/1905.11905.pdf
https://www.imf.org/external/pubs/ft/wp/2008/wp08132.pdf
## Open Questions:
1. Does the section below make sense or do you need a copy of the inverted $r_a$?
`"Note: The examples in the spreadsheet assume a user is swapping Rowan for some TKN, so it is always showing a purchasing power increase. To make the above logic work in the opposite way, where a user is swapping TKN for Rowan, $r_a`
## Extension With Weights (Complete)
We can take the Sifchain swap formula
$$y_o(x) = f(X,Y,x) =\frac{xYX}{(x+X)^2}$$
and modify it to accomodate weighting of the X and Y tokens in the pool as follows, to calculate the value of $y$ that a user *would get* if there is a purchasing power increase. We can call this value $y_o$.
$$y_o(x) = f(X,Y,x) = Y(1-(\frac{X}{x+X})^\frac{w_x}{w_y}) (1-\frac{x}{x+X})$$
subject to the constraint $$ w_x + w_y = 1$$
Here, $w_x$ and $w_y$ control the weight that is assumed for each token in the pool, removing the implicit pre-existing assumption that equal quantities in the pool result in equal prices (equivalently, the special case where $w_x=w_y=0.5$). The variables $w_x$ and $w_y$ are analogous to the weights $W_i$ and $W_o$ in the [Balancer Whitepaper](https://balancer.fi/whitepaper.pdf), check there for further explanation.
### Addendum
The weights are no longer as important for our calculations given this structure. If we choose to share the weights:
#### Deriving the weights $w_x$ and $w_y$:
Use the liquidity depth values $X$ and $Y$ at that given time, take the $x$ swap input to get the output $y$ as above, and calculate:
$$log_ba$$
where
$$a = 1-\frac{y}{Y(1-\frac{X}{x+X})} = 1-\frac{y(x+X)}{YX} $$
$$b = \frac{X}{x+X}$$
From this we can get the following weights for each block: $$w_x = \frac{log_ba}{1+log_ba}$$ $$w_y = 1 - w_x$$