# Sifchain Margin Trading Cryptoeconomics Paper
# Part 2
## To go back to [Part 1](Sifchain_Margin_Trading_Cryptoeconomics_Paper_pt_1.md)
# Protocol Monetary and Fiscal Policy (PMFP) and Governance of the Liquidity Provider Subsystem
Protocol Monetary and Fiscal Policy (PMFP) enables monetary and policy for Rowan enforced by Sifchain’s liquidity with three modules: Ratio Shifting, DEX Liquidity Protection, and a Liquidity Provider Distribution.
The overall purpose of PMFP is to provide stability, security, and rewards to Liquidity Providers commensurate with the risks they are undertaking. The Ratio Shifting module allows Sifchain governance to influence the ratio a currency holder faces to trade their existing quantity of tokens, creating more favorable trades. Liquidity Provider Distribution increases the purchasing power of Rowan by removing Rowan liquidity from all pools for every new block and distributing the removed liquidity to liquidity providers of that pool weighted by their ownership of the pool. DEX Liquidity Protection enables the coordination of profit taking and rebalancing among liquidity providers
## Monetary Policy and Fiscal Policy
Fiat currency managers use monetary policy to influence the interest rates for short term borrowing and the money supply. Fiscal policy is the means by governments set their spending priorities, influencing the cost of goods and services.
The Ratio Shifting feature allows Sifchain governance to combine the two objectives by influencing exchange rates amongst assets to influence currency-wide purchasing power.
Most cryptocurrencies influence monetary policy through inflationary rewards: They increase the quantity of tokens a token holder has. Protocol Monetary and Fiscal Policy allows Sifchain governance to instead influence the ratio a currency holder uses to trade their existing quantity of tokens for others.
## Ratio Shifting
The Ratio Shifting module allows Sifchain governance to influence the ratio a currency holder faces to trade their existing quantity of tokens, creating more favorable trades. The governance rate changes the ratio at which liquidity providers (LPs) offer to trade these tokens via the AMM. In effect, Sifchain DAO governance will set policy objectives for the purchasing power of Rowan. This governance can be analogised with traditional currency pegging and foreign exchange rate controls commonly used by monetary policy authorities to stabilize economies within traditional finance.
### Ratio Shifting Multiplier
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.
### Additional Details on Governance-specific Variables:
The total duration of a policy is the span of blocks between $h_S$ 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. 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 epochs are a user experience affordance to put governance reasoning about the effects of PMFP in intuitive units.
### Use $r_{gov}$ to Derive $r_{block}$
Let $r_{gov}$ be the per-epoch rate increase or decrease voted in by governance. Each epoch, the purchasing power of Rowan (treated as the $y$ token in Variable Definitions above) should increase or decrease by this percentage.
Let the final compounded rate, ${r_{final}}$, be defined as follows:
$${r_{final}} = (1 + r_{gov}) ^ {l_{policy}} - 1$$
Rowan should increase by this percentage between $h_s$ and $h_F$ (ie. across all epochs).
Now we compute $r_{block}$, which is the incremental increase on a per block basis (to reach $final\_compounded\_rate$):
$$r_{block} = (1 + r_{gov}) ^ {l_{policy}/({h_F-h_s})} - 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 - h_S $$
**Implementation Note:** At the first block of the policy, $r_{running}$ can be calculated ahead of time for every block in the policy, particularly if it helps make things easier for writing the code.
## Ratio Shifting Computations
### Rowan to TKN Swaps
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 the following, and we can set it to $x_o$ as the pre-ratio shifting output of the swap:
$$x_o(y)= f(X,Y,y) = \frac{yXY}{(y+Y)^2}$$
Please see [AMM Specification](https://hackmd.io/6VK2LSYjRTyeNCoHpVt2hg) for more details including variable definitions and the derivation of this formula.
Now that we have calculated $x_o(y)$ 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) = x_o(y) * (1+r_{running})$$
Mathematically, this multiplier to derive $x(y)$ is a local linear approximation.
### TKN to Rowan Swaps
Calculate $y_o$:
$$y_o(x) = f(X,Y,x) =\frac{xYX}{(x+X)^2}$$
Now that we have calculated $y_o(x)$ 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) = \frac{y_o(x)}{1+r_{running}}$$
## No policy condition
A null ratio shifting policy would be consist of a:
1. $l_{policy} = 0$,
2. $l_{epoch} = 0$, and
3. $r_{gov} = 0$, where previous $r_{final}=0$
A policy with $r_{gov} = 0$ with a nonzero length would be an intentional policy in effect for its policy length. There would be cases to pledge an $r_{gov} = 0$ for some period of time.
## Sign Convention on Ratio Shifting
An $r_{gov}$ with positive rate, where $0<r_{gov}\leq1$, then a trade of RWN to TKN will result in a greater return of TKN in the amount of $(1+r_{running})$. This is the intended direction of ratio shifting to 'increase the purchasing power of Rowan'.
An $r_{gov}$ with negative rate, where $-1<r_{gov}\leq 0$, then a trade of TKN to RWN will result in a greater return of RWN in the amount of $(1+r_{running})$. This is the opposite direction of ratio shifting to 'increase the purchasing power of Rowan'. However, a 'negative' policy could used to drive the relative weight of the liquidty pools in the opposite direction.
## The Direct Effect of Ratio Shifting on the Liquidity Pool
### Governance periods
$G$ is parameterized by a start time ($t_i$), an end time ($t_f$), and a block rate ($r_{block}$), which is the desired change in purchasing power.
Let $G$ be a governance decision such that $t_i(G)$ is the start time, $t_f(G)$ is the end time, and $r_{block}(G)$ is the block rate.
Given $block(t)$ as the number of blocks from the start of the governance period until timestep $t$, swap formulae being dependent on the pool depths $X, Y$ yields the generalized form that is both time and path dependent:
$$
r_{running}^G(t) = (1+r_{block}(G))^{block(t) - t_i(G)} - 1
$$
To analyze metrics across different governance decisions, define the metrics using $\mathcal{G}$, the set of governance decisions that occur during the interval $[t, t')$.
$$
\mathcal{G}(t, t') = \{G | \exists t\in [t, t'] s.t.\ t\in [t_i(G), t_f(G)) \}
$$
For convenience, let $G=0$ represent the policy with $r_{block}=0$. Thus, $x_{CLP}^0$ is a swap with no governance policy or, the simple continuous liquidity pool (CLP) swap formula.
### Swap Offsets
As noted above, $Y,y$ is assumed to be Rowan and $X,x$ is assumed to be the other token in a two-sided liquidity pool.
Offset is the term used in this paper to represent the difference between a swap executed under the simple CLP and the swap executed under a governance policy with a block rate > 0. In other words, offset is the additional purchasing power enabled by ratio shifting.
### Rowan to TKN Swaps
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 the following:
$$
x = f_x(X,Y,y) = \frac{yXY}{(y+Y)^2}
$$
Given our convenience notion of $G=0$, we can use this CLP swap formula as as the pre-ratio shifting or no-ratio shifting output of the swap:
$$
x_{CLP}^0(y, X, Y, t)= f_x(X,Y,y) \cdot (1+r_{running}^0(t)) \\
= f_x(X,Y,y) = \frac{yXY}{(y+Y)^2}
$$
Please see [AMM Specification](https://hackmd.io/6VK2LSYjRTyeNCoHpVt2hg) for more details including variable definitions and the derivation of this formula.
Now that we have calculated $x_{CLP}^0(y, X, Y, t)$ we can use it to determine the value a user *should* get with the purchasing power increase. This value is $x_{CLP}^G(y, X, Y, t)$ and is the output of our swap function.
$$
x_{CLP}^G(y, X, Y, t) = x_{CLP}^0(y, X, Y, t) \cdot (1+r_{running}^G(t))
$$
Mathematically, this multiplier to derive $x_{CLP}^G(y)$ is a local linear approximation.
### TKN to Rowan Swaps
The swap from an outside token into Rowan is as follows:
Calculate $y_{CLP}^0$:
$$
y_{CLP}^0(x, X, Y, t) = \frac{f_y(X,Y,x)}{1+r_{running}^0(t)} \\
= f_y(X,Y,x) = \frac{xYX}{(x+X)^2}
$$
Now that we have calculated $y_{CLP}^0(x, X, Y, t)$ 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_{CLP}^G(x, X, Y, t) = \frac{y_{CLP}^0(x, X, Y, t)}{1+r_{running}^G(t)}
$$
### Offset Derivation
We can calculate the difference in the amount output by the swap under ratio shifting from $y$ to $x$:
$$
x_{CLP}^G(y, X, Y, t) - x_{CLP}^0(y, X, Y, t) \\
= x_{CLP}^0(y, X, Y, t) \cdot (1+r_{running}^G(t)) - x_{CLP}^0(y, X, Y, t) \\
= x_{CLP}^0(y, X, Y, t) \cdot r_{running}^G(t)
$$
And similarly from $x$ to $y$:
$$
y_{CLP}^G(x, X, Y, t) - y_{CLP}^0(x, X, Y, t) \\
= \frac{y_{CLP}^0(x, X, Y, t)}{1+r_{running}^G(t)} - y_{CLP}^0(x, X, Y, t) \\
= -\frac{y_{CLP}^0(x, X, Y, t)}{1+r_{running}^G(t)}
$$
From the signs of the offsets we see that indeed a positive $r_{running}$ should incentivize swaps from $y$ to $x$ while disincentivizing the reverse: $x(y) > x_{CLP}^0(y)$ while $y(x) < y_{CLP}(x)$. [See the PMFP Domain and Sign Convention document](https://hackmd.io/5h19fsHGTbCRcvTBS12j1g?view#Sign-Convention-on-PMTP-Policy).
### Offset Metric
These differences correspond to the amount of tokens that will be taken out of the pool *in addition to* the invariant-preserving swap formula and fees.
$$
offset_X(y, X_t, Y_t, r) = x_{CLP}^0(y, X, Y, t) \cdot r \\
offset_Y(x, X_t, Y_t, r) = -\frac{y_{CLP}^0(x, X, Y, t)}{1+r}
$$
Offsets can be calculated for a full governance period:
$$
period\_offset_x(t_i, t_f, G) = \Sigma_{t=t_i}^{t_f} offset_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}), X_t, Y_t, r_{running}^{G}(t)) \\
= \Sigma_{t=t_i}^{t_f} x_{CLP}^0(y, X_{t-1}, Y_{t-1})r_{running}^G(t) \\
period\_offset_y(t_i, t_f, G) = \Sigma_{t=t_i}^{t_f} offset_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}), X_t, Y_t, r_{running}^{G}(t)) \\
= \Sigma_{t=t_i}^{t_f} \frac{-y_{CLP}^0(x, X_{t-1}, Y_{t-1})r_{running}^G(t)}{1+r_{running}^G(t)}
$$
And for the whole system over a period of timesteps:
$$
total\_offset_x(0,T) = \Sigma_{G\in \mathcal{G}(0,T)} period\_offset_x(max(0, t_i(G), min(T, t_f(G)), G) \\
total\_offset_y(0,T) = \Sigma_{G\in \mathcal{G}(0,T)} period\_offset_y(max(0, t_i(G), min(T, t_f(G)), G)
$$
## Price Deviation Metrics
It is also useful to know how the price or value of a token, again denominated in Rowan, will behave under different governance policies. The price deviation metrics account for this difference. Again, it is a useful counterfactual analytical tool, rather than a built-in part of the Sifchain PMFP system.
### Depths with Offsets
The depths $X_T^{r_{block}}, Y_T^{r_{block}}$ are functions of:
- $X_0, Y_0$, the initial depths
- $x_t, y_t$, the incoming swap amounts
- $x_{CLP}, y_{CLP}^0$, the CLP swap functions
- $\phi_x(x_{CLP}), \phi_y(y_{CLP}^0)$, the CLP fees
- $offset_x^{r_{block}}(x_{CLP}), offset_y^{r_{block}}(y_{CLP}^0)$, the swap offsets that result from $r_{block}$
Thus for the depth of a pool following a swap we have initial depths, plus incoming swaps and fees, less the offsets:
$$
X_T^G = X_0 + \Sigma_{t=1}^{T-1}x_t - x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}) + \phi_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1})) \\ - offset_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}), X_t, Y_t, r_{running}^{G(t)}(t)) \\
Y_T^G = Y_0 + \Sigma_{t=1}^{T-1}y_t - y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}) + \phi_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1})) \\ - offset_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}), X_t, Y_t, r_{running}^{G(t)}(t)) \\
$$
Alternatively, the recursive definitions:
$$
X_T^G = X_{T-1}^G + x_T - x_{CLP}^0(y_T, X_{T-1}, Y_{T-1}) + \phi_x(x_{CLP}^0(y_T, X_{T-1}, Y_{T-1})) \\ - offset_x(x_{CLP}^0(y_t, X_{T-1}, Y_{T-1}), X_T, Y_T, r_{running}^{G(T)}(T)) \\
Y_T^G = Y_{T-1}^G + y_T - y_{CLP}^0(x_T, X_{T-1}, Y_{T-1}) + \phi_y(y_{CLP}^0(x_T, X_{T-1}, Y_{T-1})) \\ - offset_y(y_{CLP}^0(x_t, X_{T-1}, Y_{T-1}), X_T, Y_T, r_{running}^{G(T)}(T)) \\
$$
For $G=0$, the case where Ratio Shifting is "disabled" (i.e. $r_{block} = 0$), we have the following depths:
$$
X_T^0 = X_0 + \Sigma_{t=1}^{T-1}x_t - x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}) + \phi_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1})) - offset_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}), X_t, Y_t, 0) \\
= X_0 + \Sigma_{t=1}^{T-1}x_t - x_{CLP}^0(y_t, X_{t-1}, Y_{t-1}) + \phi_x(x_{CLP}^0(y_t, X_{t-1}, Y_{t-1})) \\
Y_T^0 = Y_0 + \Sigma_{t=1}^{T-1}y_t - y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}) + \phi_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1})) - offset_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}), X_t, Y_t, 0) \\
= Y_0 + \Sigma_{t=1}^{T-1}y_t - y_{CLP}^0(x_t, X_{t-1}, Y_{t-1}) + \phi_y(y_{CLP}^0(x_t, X_{t-1}, Y_{t-1})) \\
$$
Essentially, the offsets disappear in the absence of a Governance policy which leaves depth purely as a function of the CLP.
### Price Ratio Deviation Metric
As the CLP price is defined as $P=\frac{Y}{X}$, for a given governance decision $G$ we have:
$$
P_T^{G} = \frac{Y_T^G}{X_T^G}
$$
For example, with $G=0$ (i.e. $r_{block}=0$) we have the following price:
$$
P_T^0 = \frac{Y_T^0}{X_T^0}
$$
The ratio $\frac{P_{T, CLP}^G}{P_{T, CLP}^{G'}}$ between prices under $G$ and $G'$ represents the deviation in price that would result from having had $G$ in place instead of $G'$ at $t=T$ (assuming the same history of incoming trades). That is, the ratio represents price deviation that would have resulted from the different offsets that would be incurred.
For example, comparing a given governance decision $G$ to the "no ratio shifting" decision $G'=0$:
$$
\frac{P_{T}^G}{P_{T}^0} = \frac{ \frac{Y_T^G}{X_T^G} }{ \frac{Y_T^0}{X_T^0} } = \frac{Y_T^G \cdot X_T^0}{X_T^G \cdot Y_T^0}
$$
### Pool Weights
The value of the pool, denominated in $Y$, is given using the price formula $P(X,Y)=\frac{Y}{X}$:
$$
P(X,Y) = Y+XP = Y+X\frac{Y}{X} = 2Y
$$
The pool weights $w_X, w_Y$, are the fractions of the total value of the pool that $X$ or $Y$ comprise. These weights are defined as:
$$
w_X(X, Y) = \frac{XP}{Y+XP} \\
w_Y(X, Y) = \frac{Y}{Y+XP}
$$
Under $r_{block}=0$, i.e. the original CLP curve, the swap curve invariant maintains that $w_x=w_y=0.5$. However, a non-zero $r_{block}$ leads to cumulative offsets that must be reset either using fees or by adjusting $r_{block}$.
Measuring the deviation in weights after a change in liquidity depths, we get:
$$
\Delta_{w_X}(X, X', Y, Y') = w_X(X', Y') - w_X(X, Y) = \frac{X'P'}{Y'+X'P'} - \frac{XP}{Y+XP} \\
\Delta_{w_Y}(X, X', Y, Y') = w_Y(X', Y') - w_Y(X, Y) = \frac{Y'}{Y'+X'P'} - \frac{Y}{Y+XP} \\
$$
The swap formulas $x(y) =(1+r_{running})x_{CLP}^0(y)$ and $y(x) = \frac{y_{CLP}^0(x)}{1+r_{running}}$ offset the ratio between $X, Y$ tokens in the pool away from a $50/50$ split. Specifically, without Ratio Shifting $y$ Rowan tokens would remove $x_{CLP}^0(y)$ from the other side of the pool, but under a non-0 $r_{block}$, the accumulated offsets move the pool weights.
To measure the deviation that occured during the current governance period $G$ compared to the previous policy $G'$, take:
$$
\Delta_{w_X}(X_T^G, X_T^{G'}, Y_T^G, Y_T^{G'}) \\
\Delta_{w_Y}(X_T^G, X_T^{G'}, Y_T^G, Y_T^{G'})
$$
### Liquidity Offset Metric
We can expand the notion of an offset from a single swap to an entire pool. However, because governance decisions and offsets are path dependent (the rate at timestep $t+1$ depends on the rate at timestep $t$) this is used primarily for the analysis of counterfactual situations.
$$
liquidity\_offset_y(Y^G, Y^{G'}) = Y^{G'} -Y^G \\
liquidity\_offset_x(X^G, X^{G'}) = X^{G'} -X^G
$$
### Liquidity Provider Position Offset
For an agent with shares $s$ of total shares $S$, under the governance decision $G$, define the liquidity position as the tuple $position_X(t, G), position_Y(t, G)$, with:
$$
position_x(s, S, X) = \frac{s}{S} \cdot X \\
position_y(s, S, Y) = \frac{s}{S} \cdot Y
$$
Where $position_x(s_t, S_t, X_t^G)=\frac{s_t}{S_t} \cdot X_t^G$ and $position_Y(s_t, S_t, Y^G)= \frac{s_t}{S_t} \cdot Y_t^G$ correspond to the positions under $G$ at time $t$.
For a liquidity provider's position from $t=t$ until $t=t'$, the liquidity offsets incurred compared to the no-ratio shifting case are:
$$
position\_offset_x(s, S, X, X') = liquidity\_offset_x(position_x(s, S, X), position_x(s, S, X')) \\
position\_offset_y(s, S, Y, Y') = liquidity\_offset_y(position_y(s, S, Y), position_y(s, S, Y'))
$$
- Governance period offsets:
$$
position\_period\_offset_x(t_i, t_f, G) = \Sigma_{t=t_i}^{t_f}position\_offset_x(s_t, S_t, X_t^G, X_t^0) \\
position\_period\_offset_y(t_i, t_f, G) = \Sigma_{t=t_i}^{t_f}position\_offset_y(s_t, S_t, Y_t^G, Y_t^0)
$$
- Total offsets (trim the start of first governance period and end of last):
$$
position\_total\_offset_x(0,T) = \Sigma_{G\in \mathcal{G}(0,T)} position\_period\_offset_x(max(0, t_i(G), min(T, t_f(G)), G) \\
position\_total\_offset_y(0,T) = \Sigma_{G\in \mathcal{G}(0,T)} position\_period\_offset_y(max(0, t_i(G), min(T, t_f(G)), G)
$$
## Oracle Signals as Inputs
The information necessary to use an oracle as pricing information at a minimum requires a tuple of **either**: $(D_{\oslash}, {P_{\oslash}})$ **or** $(X_{\oslash}, {Y_{\oslash}})$.
### Coordinate Systems
The selection of a $D-P$ coordinate system or an $X-Y$ coordinate system requires a transformation matrix that enables switching between coordinate systems: $(D_{\oslash}, {P_{\oslash}}) \in\mathbb{R_+^2} \iff (X_{\oslash}, {Y_{\oslash}}) \in\mathbb{R_+^2}$.
#### From $D-P$ to $X-Y$:
From the defintion of pricing consistent with pool ratio pricing:
$$P_{\oslash} = \frac{Y_{\oslash}}{X_{\oslash}}$$
With equally valued (50/50) liquidity pools, as is the case in Sifchain, we can define $X$-valued depth as:
$$D_{\oslash} = P_{\oslash} \cdot Y_{\oslash} + X_{\oslash}$$
Through susbtitution, we attain depth in terms of $(X_{\oslash}, {Y_{\oslash}})$:
$$D_{\oslash} = 2 \cdot X_{\oslash}$$
#### From $X-Y$ to $D-P$:
With equally valued (50/50) liquidity pools, as is the case in Sifchain, we can define $X$ in terms of the depth:
$$X_{\oslash} = \frac{D_{\oslash}}{2}$$
Through susbtitution and the definition of price, we attain $Y_{\oslash}$ in terms of $(D_{\oslash}, {P_{\oslash}})$ :
$$Y_{\oslash} = \frac{D_{\oslash}}{2 \cdot P_{\oslash}}$$
#### Coordinate Transformation
We define a transformation matrix $T$ where it provides a change between coordinate systems and its inverse maps in the reverse, satisfying the equations:
$$T \begin{bmatrix}
X_{\oslash} \\
Y_{\oslash}
\end{bmatrix} = \begin{bmatrix}
D^\prime_{\oslash}\\
P^\prime_{\oslash}
\end{bmatrix}$$
and:
$$T^{-1} \begin{bmatrix}
D_{\oslash} \\
P_{\oslash}
\end{bmatrix} = \begin{bmatrix}
X^\prime_{\oslash}\\
Y^\prime_{\oslash}
\end{bmatrix}$$
The matrix:
$$T =\begin{bmatrix}
2 & 0\\
0 & \frac{X_{\oslash}}{Y^2_{\oslash}}
\end{bmatrix}$$
with its inverse:
$$T^{-1} =\begin{bmatrix}
\frac{1}{2} & 0\\
0 & \frac{Y^2_{\oslash}}{X_{\oslash}}
\end{bmatrix}$$
satisfy the above equations.
**Note:** The last term in the inverse matrix is equivalent to $\frac{D_{\oslash}}{2 \cdot P^2_{\oslash}}$ .
## Differential Requirements
Under the set of actions where price is not expected to be constant, we can define the requirements of each action in terms of its expected change to the pool token state and its incidence upon the exposure to liability in the pool. These requirements define the direction of change in the admissible action space.
### Open
The opening of a margin position will result in the pool taking on more liability.
$$\Delta (P \cdot Y_L + X_L) > 0$$
The increase in liability must be coincident with an increase in custodied assets.
$$\Delta (P \cdot Y_C + X_C) > 0$$
The open action results in a reduction of asset depth in the pool.
$$\Delta (P \cdot Y_A + X_A) < 0$$
### Close
The closing of a margin position will result in the pool shedding liability.
$$\Delta (P \cdot Y_L + X_L) < 0$$
The decrease in liability is accompanied by a release of custodied assets.
$$\Delta (P \cdot Y_C + X_C) < 0$$
The close action results in an increase of asset depth in the pool.
$$\Delta (P \cdot Y_A + X_A) > 0$$
### Swap
A swap in the liquidity pool will have no affect on the liability of the pool.
$$\Delta (P \cdot Y_L + X_L) = 0$$
The custodied assets in the pool will also remain unchanged through a swap.
$$\Delta (P \cdot Y_C + X_C) = 0$$
The swap action will preserve the asset depth in the pool, where the slip-based fee preserves the invariant.
$$\Delta (P \cdot Y_A + X_A) = 0$$
If additional fees collected stay in the pool, then the depth will increase as a result of swap actions.
$$\Delta (P \cdot Y_A + X_A) > 0$$
## Pricing
Given the differential requirements above, there is a pricing function for the token state of the pool conditioned on an exogenous oracle signal.
$$P(X_A,Y_A,X_L,Y_L,X_C,Y_C| X_{\oslash},Y_{\oslash})$$
Let $\theta$ be the relative ratio of depths:
$\theta = \frac{D_R}{D_R+D_{\oslash}}$
where $D_R$ is the pool depth:
$D_R = P(X_A + X_C+X_L)+Y_A+Y_L+Y_C$
$D_R := 2(X_A + X_C+X_L)$
The pricing formula is then a convex combination of the pool and the oracle signal, dependent on their relative depths:
$$P= \theta \frac{Y_A+Y_L+Y_C}{X_A + X_C+X_L} + (1 - \theta)\frac{Y_{\oslash}}{X_{\oslash}}$$
This yields a swap formula of the form:
$$\Delta y=\mathbf{Y} - [\theta\frac{x\mathbf{X}\mathbf{Y}}{(x+\mathbf{X})^2}+(1 - \theta)\frac{xX_{\oslash}}{Y_{\oslash}}]$$
where:
$\mathbf{Y} = Y_A+Y_L+Y_C$
$\mathbf{X} = X_A+X_L+X_C$
## DEX Liquidity Protection
Sifchain's DEX Liquidity Protection module enables Liquidity Providers to coordinate profit taking for operations and maintenance expsenses. It is an on-chain maximum amount of non-Rowan liquidity (aka “external liquidity”) on Sifchain that can be sold at any given time duration. Three methods exist for implementing this liquidity protection: the MVP, a flat threshold, and a percentage-based daily threshold. The minimum viable product (MVP) is a simple yes-or-no governance decision from the SifDAO on whether to allow any additional external capital to be sold for a particular epoch. The flat threshold, as the name implies, is an amount of external capital that can be sold for a particular epoch. Once that limit is reached, no additional non-Rowan sales can be made. The final option, the percentage-based daily threshold carries forward the idea of the flat rate, but with a threshold that adjusts per epoch to maintain the desired liquidity threshold. Each of these options is described in greater detail in the following three sections.
### MVP
In the base case, SifDAO can simply allow or disallow external liquidity from leaving at all based on its view of market activity. Let $t$ be a binary toggle that is either TRUE or FALSE. Every swap of Rowan across all pools is subject to the following logic.
```
init() {
ALLOW_EXTERNAL_LIQUIDITY_OUT? = t
}
rowan_swap_threshold_checker(swap_type) {
if (swap_type == SELL_ROWAN and ALLOW_EXTERNAL_LIQUIDITY_OUT? == FALSE ){
reject_sale() // The swapper retains the Rowan they attempted to sell
} else {
approve_sale() // The swap proceeds as normal
}
}
```
These properties satisfy the goal for our original motivation. However, they put a lot of burden on SifDAO for manual governance. We can improve this with some simple logic.
### Flat Daily Threshold
With a flat threshold, SifDAO will be able to set the liquidity protection threshold in USD corresponding to the net amount of Rowan they'd like to be sellable in any given epoch (assumed to be roughly one day in block time).
Let $l$ be the liquidity protection threshold set by governance.
Every swap of Rowan across all pools is subject to the following logic.
```
init() {
max_rowan_liquidity_threshold = l
current_rowan_liquidity_threshold = max_rowan_liquidity_threshold
epoch_length = // number of blocks per epoch, presumably set to approximate day per epoch
}
lookup_rowan_oracle_price() {
// The current block's ratio price for Rowan:USDT cannot be used due to the risk of an oracle attack.
// We could use a block-based TWAP or some other solution, see here for further research
// https://blog.euler.finance/uniswap-oracle-attack-simulator-42d18adf65af
// https://smartcontentpublication.medium.com/twap-oracles-vs-chainlink-price-feeds-a-comparative-analysis-8155a3483cbd
}
rowan_swap_threshold_checker(rowan_swap_amount, swap_type) {
rowan_price = lookup_rowan_oracle_price()
if (swap_type == SELL_ROWAN){
if (current_rowan_liquidity_threshold - rowan_swap_amount * rowan_price < 0){
reject_sale() // The swapper retains the Rowan they attempted to sell
} else {
current_rowan_liquidity_threshold -= rowan_swap_amount * rowan_price
approve_sale() // The swap proceeds as normal
}
if (swap_type == BUY_ROWAN) {
current_rowan_liquidity_threshold = min(current_rowan_liquidity_threshold + rowan_swap_amount * rowan_price, max_rowan_liquidity_threshold)
}
}
begin_block() {
...
current_rowan_liquidity_threshold = min (current_rowan_liquidity_threshold + max_rowan_liquidity_threshold / epoch_length, max_rowan_liquidity_threshold)
...
}
```
With this logic, we expect the following properties to hold:
* Users can collectively sell Rowan so long as net sales do not exceed `max_rowan_liquidity_threshold` in any given epoch
* Users can collectively sell more than `max_rowan_liquidity_threshold` in an epoch so long as Rowan purchases during that epoch ensure that the net sales of Rowan to not exceed `max_rowan_liquidity_threshold`
* Users who commit double swaps (purchasing Rowan in one pool and then immediately selling it in another pool) will not be affected by this threshold so long as the second part of their double swap is not larger than `max_rowan_liquidity_threshold` by itself
* `current_rowan_liquidity_threshold` for any given user on any given swap will be `max_rowan_liquidity_threshold` if one epoch has elapsed and no net Rowan sales have occurred.
* Replenishment of `current_rowan_liquidity_threshold` will occur evenly on a per-block basis, encouraging an equal distribution of net Rowan sales
These properties reduce SifDAO's need to manually intervene. However, we can improve in this design with a percentage-based threshold.
### Percentage-Based Daily Threshold
The flat threshold requires governance to adjust `max_rowan_liquidity_threshold` from time to time depending on other market conditions, which may become tedious. Consider this more advanced version in which governance specifies the percentage of non-Rowan liquidity that can be purchased at any point.
Let $m$ be the liquidity protection threshold percentage set by governance.
Every swap of Rowan across all pools is subject to the following logic.
```
init() {
max_rowan_liquidity_threshold_percentage = m
max_rowan_liquidity_threshold = get_total_external_liquidity() * max_rowan_liquidity_threshold_percentage
current_rowan_liquidity_threshold = max_rowan_liquidity_threshold
epoch_length = // number of blocks per epoch, presumably set to approximate day per epoch
}
lookup_rowan_oracle_price() {
// The current block's ratio price for Rowan:USDT cannot be used due to the risk of an oracle attack.
// We could use a block-based TWAP or some other solution, see here for further research
// https://blog.euler.finance/uniswap-oracle-attack-simulator-42d18adf65af
// https://smartcontentpublication.medium.com/twap-oracles-vs-chainlink-price-feeds-a-comparative-analysis-8155a3483cbd
}
get_total_external_liquidity() {
// returns the USD value of all non-Rowan liquidity on Sifchain
// We can likely estimate this value if a precise value cannot easily be calculated frequently
}
rowan_swap_threshold_checker(rowan_swap_amount, swap_type) {
rowan_price = lookup_rowan_oracle_price()
max_rowan_liquidity_threshold = get_total_external_liquidity() * max_rowan_liquidity_threshold_percentage
if (swap_type == SELL_ROWAN){
if (current_rowan_liquidity_threshold - rowan_swap_amount * rowan_price < 0){
reject_sale() // The swapper retains the Rowan they attempted to sell
} else {
current_rowan_liquidity_threshold -= rowan_swap_amount * rowan_price
approve_sale() // The swap proceeds as normal
}
if (swap_type == BUY_ROWAN) {
current_rowan_liquidity_threshold = min(current_rowan_liquidity_threshold + rowan_swap_amount * rowan_price, max_rowan_liquidity_threshold)
}
}
begin_block() {
...
max_rowan_liquidity_threshold = get_total_external_liquidity() * max_rowan_liquidity_threshold_percentage
current_rowan_liquidity_threshold = min (current_rowan_liquidity_threshold + max_rowan_liquidity_threshold / epoch_length, max_rowan_liquidity_threshold)
...
}
```
With this logic, we expect the properties from the flash threshold to hold, as well as these additional properties:
* As LPs withdraw external liquidity from Sifchain, `max_rowan_liquidity_threshold` is reduced proportionately just in time to be updated for the next swap
* As swappers sell Rowan and remove external liquidity from Sifchain, `max_rowan_liquidity_threshold` is reduced proportionately just in time to be updated for the next swap
* As LPs add external liquidity from Sifchain, `max_rowan_liquidity_threshold` is increased proportionately just in time to be updated for the next swap
* As swappers buy Rowan and add external liquidity from Sifchain, `max_rowan_liquidity_threshold` is increased proportionately just in time to be updated for the next swap
* When `max_rowan_liquidity_threshold` is decreased below `current_rowan_liquidity_threshold`, `current_rowan_liquidity_threshold` is reset to equal `max_rowan_liquidity_threshold` as soon as the next block (nearly immediately)
* When `max_rowan_liquidity_threshold` is increased, `current_rowan_liquidity_threshold` does not immediately increase but does accelerate its per-block increases
This extra logic allows governance to simply set a percentage of total external liquidity that can be swapped away from Sifchain on a per-epoch basis without needing to track changes to liquidity on the DEX.
## Liquidity Provider Distribution
The Liquidity Provider Distribution module is a piece of the Protocol Monetary and Fiscal Policy suite that improves Rowan's purchasing power by removing a portion of it from all liquidity pools at every block and giving it to Liquidity Providers.
# Interaction Between Liquidity Provider Subsystem and Protocol Monetary and Fiscal Policy Governance

The Liquidity Provider Subsystem takes in governance decisions on monetary policy (formalized as $r_gov$; represented in the diagram above as $\omega$, and bounded by time in epochs as $l_policy$), user actions ($u$), and a transformed Oracle signal ($D_{\oslash}, P_{\oslash}$) to update the state of the system as a whole($S^+$). At present, the space of user actions ($u$) is limited to swaps. Future instantiations of the policy will expand it to add and remove liquidity, as well as the margin trading related actions.
# Mechanism Specifications

## Primitive Mechanisms
Primitive Mechanisms are modular components that may be called directly in some cases or may be restricted to be called only as a part of a larger [Composite Mechanism](#Composite_Mechanisms).
### Borrow
Agent $i$ has holdings $x_i$ and wants to open a margin trading position $mtp_i$.
#### Agent State Update
- Agent $i$ puts up collateral $\Delta x$
- Agent holdings of $x$ tokens resolve to: $x^+_i = x_i - \Delta x$
#### $mtp$ State Update
- Agent $i$ takes a liability position in $x$ according to the leverage the agent chooses to take within permissible limits.
- The values for an $mtp_i$ are initialized as:
- $x_A = \Delta x$
- $x_L^P = \eta_{mtp} \cdot \Delta x$
where: $\eta_{mtp} \le \eta_{max}(X)$
No interest liabilities have been accrued yet, so $x_L^I = 0$
The health of the $mtp$ only includes the principal liability at initialization (no interest liabilities accrued yet): $h(x) = \frac{x_A}{x_A + x^P_L}$.
#### Pool State Update
For the borrow mechanism the Pool State Updates on the $X$ side of the token pair:
- $X_A^+ = X_A + \Delta x$
- $X_L^{P+} = X_L^{P} + \eta_{mtp} \cdot \Delta x$
We expect this Pool State Update to be called in the [Pool Health Computation](#Pool_Health_Computation) as long as $X_A^+$ and $X_L^{P+}$ are used. But for completeness, the new health would be:
$H(X,Y)^+ = \frac{X_A^+}{X_A^+ + X_L^{P+}} * \frac{Y_A^+}{Y_A^+ + Y_L^{P+}}$
### Swap_Open_$mtp$
This section defines swaps in the context of the Open $mtp$ action.
As agent $i$ has opened an $mtp$ with $\Delta x$, this amount needs to be swapped to its equivalent amount in Y-tokens to create a long position in the opposite side of the trading pair.
#### $mtp$ State Update
The collateral and leveraged position $\Delta x_A + \Delta x_L$ is swapped to its equivalent amount in Y-tokens in the $mtp$, minus the swap fee.
Applying the parametrized swap fee function, the amount of Y-tokens $\Delta y$ obtained through swapping $\Delta x_A + \Delta x_L$ is: $$\frac{(\Delta x_A + \Delta x_L)\mathbf{Y}\mathbf{X}}{((\Delta x_A + \Delta x_L)+\mathbf{X})^2}$$
where
- $\mathbf{X} = X_A+X_L^P$ is the total amount of X-tokens as the state in the liquidity pool
- $\mathbf{Y}= Y_A+Y_L^P$ is the total amount of Y-tokens as the state in the liquidity pool
We are excluding $X^I_L$ and $Y^I_L$ from the swap computation because they are unrealized and will be accounted for when an account is updated.
We are excluding $X_C$ and $Y_C$ from the swap computation because the $mtp$ owner has an account of those tokens, while the pool maintains custodial rights.
<!--
The previous version implies that each time an mtp is opened, some amount of collateral is locked up, so there would be much less liqiuidity avaialble at any given time. This would be the version that includes margn trading, as it considers both custody amount as well as assets.
$$\Delta y =(1-\lambda_l) \frac{x_L (Y_A+Y_C)}{x_L+(X_A+X_C)} + \lambda_l\frac{x_L(Y_A+Y_C)(X_A+X_C)}{(x_L+(X_A+X_C))^2}$$
:::warning
May create an arbitrage opp as only x_A goes into the pool whereas \Delta y is based on x_L which is $\eta$ times larger
:::
-->
### Take_into_Custody
Expected to be used during opening an $mtp$ after the [Swap(Open $mtp$)](#Swap) computes a $\Delta y$:
#### $mtp$ State Update
The $mtp$ state accounts for $\Delta y$ as it's input to the custody
- $y_C^+ = \Delta y$
#### Pool State Update
Add $\Delta y$ to Pool's custody
- $Y_A^+ = Y_A - \Delta y$
- $Y_C^+ = Y_C + \Delta y$
### Take_out_of_Custody
Expected to be used during closing an $mtp$ before the [Swap(Close $mtp$)](#Swap) computes a $\Delta y$:
Set $\Delta y$ for input into swap logic
- $\Delta y = y_C$
#### $mtp$ State Update
Assertion: check if $mtp$'s custody $y_C$ has $\Delta y$
The $mtp$ state accounts for $\Delta y$ as it needs to be removed from the $mtp$ custody
- $y_C^+ = y_C - \Delta y = 0$
#### Pool State Update
Remove $\Delta y$ from Pool's custody
- $Y_A^+ = Y_A$
- $Y_C^+ = Y_C - \Delta y$
### Swap_Close_$mtp$
Assertion: check if $mtp$ has $\Delta y$
#### $mtp$ State Update
$\Delta y$ is swapped to its equivalent amount in X-tokens in the $mtp$, minus the swap fee.
Applying the parametrized swap fee function, the amount of X-tokens $\Delta x$ obtained through swapping $\Delta y$ is:
$$\Delta x =\frac{(\Delta y)\mathbf{Y}\mathbf{X}}{((\Delta y)+\mathbf{Y})^2}$$
where
- $\Delta x$ is the output amount from the swap
- $\mathbf{X} = X_A+X_L^P$ is the total amount of X-tokens as the state in the liquidity pool
- $\mathbf{Y}= Y_A+Y_L^P$ is the total amount of Y-tokens as the state in the liquidity pool
Excluding $X^I_L$ and $Y^I_L$ from the swap computation because they are unrealized and will be accounted for when an account is updated.
Excluding $X_C$ and $Y_C$ from the swap computation because the $mtp$ owner has an account of those tokens, while the pool maintains custodial rights.
### Repay
Agent $i$ has holdings $x_i$ and owns an $mtp$ with liabilities $\Delta x$ and $x_L = x^P_L + x^I_L$, and would like to close this $mtp$.
- Get $x^P_L$ from Chain State
- Get $x^I_L$ from *interest_Liability_Computation_on_$mtp$()*
#### Agent State Update
*Repay()*
NOTE: This function can only be used if the $mtp$ is healthy OR if it's coming from forced settlement.
- Extract principal liabilities first
- $mtp$ state update: $x_L^P = x_L^P - \Delta x$ while $\Delta x \leq x_L^P$
- Extract interest liabilities next
- $mtp$ state update: $x_L^I = x_L^I - \Delta x$ while $\Delta x \leq x_L^I - x_L^P$
- If there's still remainder tokens left, this amount goes to the agent
- Agent state update: $x_i^+ = x_i + (\Delta x - x_L^I - x_L^P)$
$mtp$ ceases to exist. If $x^{P+}_L$ and $x^{I+}_L$ are 0, then we return the collateral $x_A$.
#### Pool State Update
Considering that the $mtp$ has been successfully repaid, for the Repay mechanism, the Pool State Updates on the $X$ side of the token pair are:
If Repay() is called during Close $mtp$,
- Add back in principal liabilities first
- $X^+_A = X_A - \Delta x + x_L^P + x_L^I$ for $\Delta x > (x_L^P + x_L^I)$
- $X^{P+}_L = X^P_L - \Delta x$ while $\Delta x \leq x_L^P$
- Add interest liabilities next
- $X^+_A = X_A + \Delta x$ while $\Delta x \leq x_L^P - x_L^I$
We expect to be called in the [Pool Health Computation](#Pool_Health_Computation) as long as $X_A^+$ and $X_L^{P+}$ are used. But for completeness, the new health would be:
$H(X,Y)^+ = \frac{X_A^+}{X_A^+ + X_L^{P+}} * \frac{Y_A^+}{Y_A^+ + Y_L^{P+}}$
### Maintenance_Repay
Agent $i$ has holdings $x_i$ and owns an $mtp$ with liabilities $\Delta x$ and $x_L = x^P_L + x^I_L$, and would like to improve the health of their $mtp$ to lower their interest rate.
- Get $x^I_L$ from *Interest_Liability_Computation_on_$mtp$()*
The expectation is that the owner would reduce their interest liabilities, possibly to 0, but it is not necessary to reduce this to 0.
#### Agent State Update
*Maintenance_Repay()*
NOTE: This function can only be used if the $mtp$ is healthy OR at risk OR by the owner in a $h(x)<b$ state.
- Extract interest liabilities first
- $mtp$ state update: $x_L^I = x_L^I - \Delta x$ while $\Delta x \leq x_L^I$
- If the owner pays off more than their than their interest liabilities, then principal liabilities are paid next:
- $mtp$ state update: $x_L^P = x_L^P - \Delta x$ while $\Delta x \leq x_L^P - x_L^I$
- If there is still a remainder of tokens left, this amount goes to the agent
- Agent state update: $x_i^+ = x_i + (\Delta x - x_L^P - x_L^I)$
If $x^{P+}_L$ and $x^{I+}_L$ are 0, then the $mtp$ ceases to exist and we return the collateral $x_A$.
#### Pool State Update
While the Maintenance_Repay mechanism is expected to reduce an $mtp$'s interest liabilities, there exists the possibility of over-repaying. The series of Pool State Updates on the $X$ side of the token pair to reflect this are:
During Maintenance_Repay(),
- Add back in interest liabilities first
- $X^+_A = X_A + \Delta x$ while $\Delta x \leq x_L^I$
- Add principal liabilities next
- $X^+_A = X_A + \Delta x$ while $\Delta x \leq x_L^I - x_L^P$
- $X^{P+}_L = X^P_L - \Delta x$ while $\Delta x \leq x_L^I - x_L^P$
We expect to be called in the [Pool Health Computation](#Pool_Health_Computation) as long as $X_A^+$ and $X_L^{P+}$ are used. But for completeness, the new health would be:
$H(X,Y)^+ = \frac{X_A^+}{X_A^+ + X_L^{P+}} * \frac{Y_A^+}{Y_A^+ + Y_L^{P+}}$
### Interest_Liability_Computation_on_$mtp$
Between epochs, the interest rate $\beta$ is changing at each $t$:
$$\Delta \beta_t = (\beta^{\star}_T - \beta^{\star}_{T-1}) \cdot \frac{\ln(2)}{t \cdot \ln(T)}$$
for $T >1$, and where the term $\frac{\ln(2)}{\ln(T)}$ is a constant for any $T$.
Computing the interest liabilities on an $mtp$ during an epoch for a given $t$ since the last epoch, under the assumption of no compounding between epochs, and using the fact that the integral of $\frac{1}{t}dt$ is $\ln(t)$ :
$$x_{L, t}^{I+} = (\beta^{\star}_{T-1} + \ln(t) \cdot \frac{\ln(2)}{\ln(T)}) \cdot (x_{L, T-1}^{P} + x_{L, T-1}^{I})$$
for $T >1$ and $t >1$, and where the term $\frac{\ln(2)}{\ln(T)}$ is a constant for fixed values of $T$, eliminating the need the compute a transcendental function on-chain.
Further, $t$ is limited to discrete integer values, which means that the values for $\ln(t)$ may be pre-computed and referenced.
The above equation compounds every $T$. If compounding every $t$ is required, a discrete sum over a for loop could be used as an approximation:
$$x_{L, t}^{I+} = \sum_{n=1}^t \ln(n) \cdot (\beta^{\star}_T - \beta^{\star}_{T-1}) \cdot \frac{\ln(2)}{\ln(T)} \cdot \frac{(x_{L, T-1}^{P} + x_{L, T-1}^{I})}{T}$$
### Interest_Liability_Computation_on_$mtp$_at_Epoch
The chain state is updated at each epoch for all existing $mtp$ positions:
$$x_{L, T}^{I+} = \beta^{\star}_T \cdot (x_{L, T-1}^{P} + x_{L, T-1}^{I})+ x_{L, T-1}^{I}$$
### Pool_Health_Computation
Update on Stateful Metric on Global State of Pool Health:
$H(X,Y)^+ = \frac{X_A^+}{X_A^+ + X_L^{P+}} * \frac{Y_A^+}{Y_A^+ + Y_L^{P+}}$
### mtp_Health_Computation
Update on Stateful Metric on individual $mtp$ State:
- $h(x)^+ = \frac{x_A}{x_A + x_L^{P}+ x_L^{I}}$
## Composite_Mechanisms
### Open $mtp$
[Borrow](#Borrow) $\to$ [Pool Health Computation](#Pool_Health_Computation) $\to$ [Swap_Open_$mtp$](#Swap_Open_$mtp$) $\to$ [Take into Custody](#Take_into_Custody)

### Close $mtp$
[Take out of custody](#Take_out_of_custody) $\to$ [Swap Close $mtp$](#Swap_Close_$mtp$) $\to$ [Interest Liability Computation on $mtp$](#Interest_Liability_Computation_on_$mtp$) $\to$ [Repay](#Repay)

Handler checks $mtp$ health state
Check if $h(x) > a$ `# mtp is healthy`
- if $h(x) > a$
- proceed to *Repay()*
- else if $h(x) > b$
- Prompt margin maintenance to bring $mtp$ health up such that $h(x) > a$, `exit`
- else if $h(x) \leq b$
- check if $x_i \geq x_L$ `# Agent holds $x_L$`
- if $x_i \geq x_L$, proceed
- $mtp$ can be force closed by any address
- else if $x_i < x_L$, $mtp$ needs to be force closed
### Margin Maintenance- Pay off Interest Liabilities
An $mtp$ holder may need to reduce their leverage by reducing their liability position. The owner may pay that off with $x$ tokens in this composition:
[Interest Liability Computation on $mtp$](#Interest_Liability_Computation_on_$mtp$) $\to$ [Maintenance_Repay](#Maintenance_Repay) (Return some custodied tokens) $\to$ [mtp_Health_Computation](#mtp_Health_Computation)
Alternatively the owner could reduce their leverage position by returning some borrowed tokens, which would this expanded composition:
[Take out of custody](#Take_out_of_custody) $\to$ [Swap Close $mtp$](#Swap_Close_$mtp$) $\to$[Interest Liability Computation on $mtp$](#Interest_Liability_Computation_on_$mtp$) $\to$ [Maintenance_Repay](#Maintenance_Repay) (Return some custodied tokens) $\to$ [mtp_Health_Computation](#mtp_Health_Computation)

### Margin Maintenance- Add More Collateral
[Interest Liability Computation on $mtp$](#Interest_Liability_Computation_on_$mtp$)
$\to$ [Borrow](#Borrow) where the $mtp$ owner will Add Asset Collateral without Borrowing, i.e. leverage $\approx 0$. $\to$ [mtp_Health_Computation](#mtp_Health_Computation)

### Forced Global Settlement by Pool
[Pool_Health_Computation](Pool_Health_Computation) determines if the pool is unhealthy enough to undergo Forced Global Settlement by Pool.
If yes, close all outstanding $mtp$'s in the pool. Close the pool. All LPs will get their shares scaled down as shown below.
If the LP has provided liquidity in X tokens, they get $$\frac{\pi_X}{\Pi_X}*(X_A+X_C)$$
If the LP has provided liquidity in Y tokens, they get
$$\frac{\pi_Y}{\Pi_Y}*(Y_A+Y_C)$$
where
- $\pi_X$ and $\pi_Y$ are the LP's claims/shares on liquidity provided in X and Y denominations
- $\Pi_X$ and $\Pi_Y$ are the claims/shares on total liquidity provided by all LPs to the pool in X and Y denominations
### Forced Settlement by Keeper
This mechanism can be called only when $h(x) \leq c$.
This mechanism is composed of the following primitives:
[Interest Liability Computation](#Interest_Liability_Computation_on_$mtp$) $\to$ $mtp$ health computation $\to$ [Swap](#Swap) $\to$ [Repay](#Repay)
- Interest Liability Computation
- $mtp$ health computation
- The following check needs to be performed
- if $h(x) \leq c$
- check if $x_i \geq x_L$ `# Agent holds $x_L$`
- if $x_i \geq x_L$, proceed to Repay()
- $mtp$ can be force closed by any address
- else if $x_i < x_L$,
- $mtp$ needs to be force closed
- Swap $\Delta y = y_C$ to $\Delta x$
# Additional MTP Types (Shorts and Double Swaps)
The existing Mechanism Specification contains the sequence of primitive mechanism function calls and state updates to open a long position in a given liquidity pool. By calling the custody swap mechanism and changing which tokens are in custody for the associated $mtp$ account, we can extend margin position to include:
1. Swap into Y-Z Pool, long in Z
2. Short in X-Y Pool, short in Y
3. Swap into Y-Z Pool, short in Z
## Health Generalization Update
Maintaining a persistent computation of $mtp$ health over more than one token and more than pool requires an update to the previous $mtp$ health metric computation.
* Maintain invariant over pools
* Vector valued in custody
* Parent pool, with emulated in child pools
* Generalize health metric = Rowan (y) becomes the numeraire
* Parent pool-> asset collateral pool, health is critical
* Child pool any other swapped pool
Previous definition of health metric for an $mtp$:
$$ h(\mathbf x) = \frac{x_A}{x_A + x_L}$$
We want to get the value of the position in terms of $Y$.
The price of asset $x$ in terms of y is $\bar{p}^y_x$. The price is the realized price that a position of $x$ tokens would be swapped to $y$ tokens in the X-Y pool.
The same would be true for positions not held in the X-Y pool. For example, $z$ tokens would be valued in the Y-Z pool with a price of $\bar{p}^y_z$
For the non-double swap case, the metric can still be valued in $Y$ as:
$$ h(\mathbf x) = \frac{x_A \cdot \bar{p}^y_x}{x_A \cdot \bar{p}^y_x + x_L^I \cdot \bar{p}^y_x+ y_C}$$
In the general case, where one can open a position using collateral in one pool and holding custodied tokens in other pools, we can value positions in other pools as a vector sum over $q$ positions in $Y$:
$$\overrightarrow{y_C} = \sum_q^Q{q_C \cdot \bar{p}^y_q}$$ where $p^y_y =1$
OR:
$\overrightarrow{y_C} = y_C + \sum_q^Q{q_C \cdot \bar{p}^y_q}$, for $q \neq y$ and $y_C$ being tokens still held in the X-Y pool.
We now have a vector valued definition of health metric for an $mtp$ with a position opened in $x$:
$$ \overrightarrow{h(\mathbf x)} = \frac{x_A \cdot \bar{p}^y_x}{x_A \cdot \bar{p}^y_x + x_L^I \cdot \bar{p}^y_x+ \sum_q^Q{q_C \cdot \bar{p}^y_q}}$$
In the double-swap case, we can value the positions in the Y-Z pool using the above vector sum definition, now restricted to the implementation where only the entire position may be opened in $Y-Z$ pool:
$$ \overrightarrow{h(\mathbf x)} = \frac{x_A \cdot \bar{p}^y_x}{x_A \cdot \bar{p}^y_x + x_L^I \cdot \bar{p}^y_x+ z_C \cdot \bar{p}^y_z}$$
## Double Swap Long
**Goal: For two pools X-Y and Y-Z, derive mechanism that allows margin position to be opened in the X-Y pool and swapped into the Y-Z pool.**
### Global State
| Name | Description | Symbol |
|----|----|----|
| X Assets | Quantity of tokens of type X as an asset | $X_{A}$ |
| X Principal Liabilities | Quantity of tokens of type X as a principal liability| $X^P_{L}$ |
| X Custody | Quantity of tokens of type X held in custody|$X_{C}$ |
| Y Assets | Quantity of tokens of type Y as an asset| $Y^x_{A}$ |
| Y Principal Liabilities | Quantity of tokens of type Y as a liability| $Y^{Px}_{L}$ |
| Y Custody | Quantity of tokens of type Y held in custody|$Y^x_{C}$ |
| Name | Description | Symbol |
|----|----|----|
| Z Assets | Quantity of tokens of type X as an asset | $Z_{A}$ |
| Z Principal Liabilities | Quantity of tokens of type X as a principal liability| $Z^P_{L}$ |
| Z Custody | Quantity of tokens of type X held in custody|$Z_{C}$ |
| Y Assets | Quantity of tokens of type Y as an asset| $Y^z_{A}$ |
| Y Principal Liabilities | Quantity of tokens of type Y as a liability| $Y^{Pz}_{L}$ |
| Y Custody | Quantity of tokens of type Y held in custody|$Y^z_{C}$ |
### Local_State_mtp
Local state is the state necessary for having a legal and active account with a margin trading position ($mtp$). The local state also includes the information necessary for properly interacting with the margin trading system ($MTP$).
| Name | Description | Symbol |
|----|----|----|
| $mtp$ $id$ | Individual margin trading position address of an $mtp$ owner | $\mathcal{A}_{mtp}$ |
| MTP Health | Metric describing the health of an individual MTP | $\overrightarrow{h(X)}$ |
### Requirements
1. Both pools maintain custody in its global state.
2. Both pools maintain health in its global state.
3. Local mtp maintains state across all pools in which its position is in.
4. Local health metric must take into account its value across all pools its position is in.
* Implication: Call to get price signals from pools
5. Impose assertions to prevent detriment to Y-Z pool.

### Custody Swap Mechanism in Y-Z
The open composite is extended to allow for additional swap(s) into other liquidity pool. For a given input of $\Delta x$ from an agent to open an $mtp$ position, the output of the take_into_custody primitive is a $\Delta y_C$ of tokens locked in custody of an $mtp$ position. This output of $\Delta y_C$ is the input to the Custody Swap Mechanism to allow a margin position opened in $x$ and denominated in $z$.
#### $mtp$ State Update
$\Delta y_C$ are swapped in the Y-Z pool, where the pool state for swap is still assets plus liabilities ($Y_A + Y_L$) for each token in the pair:
$\Delta z_C = f_{swap}(\Delta y_C, Y^z, Z)$
for:
* Slippage within allowable range
If partial double swap:
- $y_C = y_C - \Delta y_C$
- If entire position is opened in $z$, then there is no $y_C$ associated with the $mtp$, but in Z:
- $y_C = 0$
- $z_C = \Delta z_C$
No interest liabilities have been accrued yet, so initialized at 0: $x_L^I = 0$
The health of the $mtp$ only includes the principal liability at initialization (no interest liabilities accrued yet):
$\overrightarrow{h(\mathbf x)} = \frac{x_A \cdot p^y_x}{x_A \cdot p^y_x + \sum_q^Q{q_C \cdot p^y_q}}$
#### Pool State Update
For the Custody Swap Mechanism the Pool State Updates in the $Y-Z$ token pair:
- $Z_A^+ = Z_A - \Delta z_C$
- $Z_C^+ = Z_C + \Delta z_C$
- $Y_A^{Z+} = Y_A^{Z} + \Delta y_C$
And in the $X-Y$ token pair: $Y_C^{X+} = Y_C^{X+} - \Delta y_C$
## Open Short
**Goal: Allow a short margin position to be opened in the X-Y pool.**

### Custody Swap Mechanism to Short in X-Y
The open composite is extended to allow a short in a given liquidity pool. For a given input of $\Delta x$ in collateral from an agent to open an $mtp$ position, the output of the take_into_custody primitive is a $\Delta y_C$ of tokens locked in custody of an $mtp$ position. This output of $\Delta y_C$ is the input to the Custody Swap Mechanism swapped back to $x$ to allow a margin short position in $y$.
#### $mtp$ State Update
$\Delta y_C$ are swapped back to $x$ in the X-Y pool, where the pool state for swap is still assets plus liabilities ($Y_A + Y_L$) for each token in the pair:
$\Delta x_C = f_{swap}(\Delta y_C, Y, X)$
for:
* $H(\mathbf Y)^+$ within allowable range
* Slippage within allowable range
If entire position is opened and shorted in $x$, then there is no $y_C$ associated with the $mtp$, but back in X:
- $y_C = 0$
- $x_C = \Delta X$
No interest liabilities have been accrued yet, so initialized at 0: $x_L^I = 0$
The health of the $mtp$ only includes the principal liability at initialization (no interest liabilities accrued yet):
$\overrightarrow{h(\mathbf x)} = \frac{x_A \cdot p^y_x}{x_A \cdot p^y_x + \sum_q^Q{q_C \cdot p^y_q}}$
#### Pool State Update
For the Custody Swap Mechanism the Pool State Updates on the X-Y pair, bearing in mind the pool state update from the previously called primitive mechanisms (such as take_into_custody), where these state variables are updated again as:
- $X_A^+ = X_A - \Delta x_C$
- $X_C^+ = X_C + \Delta x_C$
- $Y_A^{+} = Y_A + \Delta y_C$
- $Y_C^{+} = Y_C - \Delta y_C$
**Important that these may seem to cancel out, however tracing this event will properly account for slippage and costs**
## Double Swap Short

**The goal is for the $mtp$ holder to have a short position in $x$ relative to $z$, given $x$ in collateral.**
After calling the opening $mtp$ mechanism borrow, two swaps will take place: one in the Y-Z pool and another back in the X-Y pool swap. The amount to swap will be imputed in the opposite direction.
### Double Custody Swap Mechanism to Short
The open composite is extended to allow a short in a given liquidity pool. For a given input of $\Delta x$ in collateral from an agent to open an $mtp$ position, the output of the take_into_custody primitive is a $\Delta z_C$ of tokens locked in custody of an $mtp$ position. This output of $\Delta z_C$ is the input to the Custody Swap Mechanism swapped to $y$ then swapped back to $x$.
#### $mtp$ State Update
- $\Delta z_C$ are swapped to $y$ in the Y-Z pool
Then the $\Delta y_c$ is swapped :
- $\Delta x_C = f_{swap}(\Delta y, Y, X)$
Given:
* $H(\mathbf Y^x)^+$ within allowable range
<!-- * $H(\mathbf Z)^+$ within allowable range -->
* Slippage within allowable range
If entire position is opened and shorted in $x$, then there is no $y_C$ associated with the $mtp$, but:
- $y_C = 0$
- $z_C = 0$
- $x_C = \Delta x_C$
No interest liabilities have been accrued yet, so initialized at 0: $x_L^I = 0$
The health of the $mtp$ only includes the principal liability at initialization (no interest liabilities accrued yet):
$\overrightarrow{h(\mathbf x)} = \frac{x_A \cdot p^z_x}{x_A \cdot p^z_x + \sum_q^Q{q_C \cdot p^y_q}}$
#### Pool State Update
For the Custody Swap Mechanism the Pool State Updates on the X-Y pair, bearing in mind the pool state update from the previously called primitive mechanisms (such as take_into_custody), where these state variables are updated again. For the other two liquidity pools, we resolve the states.
In the X-Y Pair:
- $X_A^{+} = X_A - \Delta x_C$
- $X_C^{+} = X_C + \Delta x_C$
- $Y_A^{X+} = Y_A^X + \Delta y^z - \Delta y^x$
In the Y-Z Pair:
- $Y_A^{Z+} = Y_A^Z - \Delta y^z$
- $Z_A^{Y+} = Z_A^Y - \Delta z$
<!-- $Z_C^{Y+} = Z_C^Y - \Delta z_C$ -->
**Important to note that these may seem to cancel out, however tracing this event will properly account for slippage and costs**
## Appendix
#### Appendix 1: (Ratio Shifting) Deriving $r_{block}$
$$ (1+r_{block})^{h_F-h_s} = 1+r_{final} = (1 + r_{gov})^{l_{policy}}$$
$$ 1+r_{block} = (1 + r_{gov})^{{l_{policy}}/{(h_F-h_s)}}$$
$$ r_{block} = (1 + r_{gov})^{{l_{policy}}/{(h_F-h_s)}}-1$$
#### Appendix 2: (Ratio Shifting) Reference Spreadsheet for Rowan to TKN Swaps
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 3: (Ratio Shifting) 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 $y_x$ as above in the case of TKN to Rowan swaps, and the spreadsheet highlights the different calculations for the Ratio Shifting-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
## 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