The Moving Average
A moving average is utilized as a security measure, where sudden changes in the pool reserves can be detected, and prevent abuse of the protocol’s features. The moving average (ema) is updated with the first trade of the block, for any asset according to the following formula:
where r is the spot rate in units of BNT/TKN as determined by the trading liquidity balances of the pool, and α is an arbitrary constant that determines the responsiveness of the moving average. The α term is a global variable, set at 0.2 (or 20%) at launch of Bancor 3, and is intended to provide a consensus rate for the pool that is resistant to virtual price manipulation attacks. The following chart is an arbitrary depiction of the ema behavior relative to the spot price on a per-block basis. The ema is measured and updated before an action is executed; therefore, the ema response is delayed by a minimum of one action (e.g. a trade or add/remove liquidity event). Further, the ema is only adjusted once per pool, per block.
At genesis, the ema rate is set equal to the spot rate. Therefore, in the above scenario each of the liquidity pools began with the following rates:
However, the trading situations do have an effect. To demonstrate, assume that the trades described above happen on consecutive blocks. For the LINK trading pool, both the spot rate and the ema begin at 6, as set at the genesis of the pool. Since the ema is adjusted before the trade is executed, the first trade has no effect on the ema; the spot price changes as expected. The new spot price becomes relevant in the next block, as the ema is updated prior to performing the second trade. First, the ema is updated using the new spot rate, then the second trade is processed. In this example, the lag of the ema means there is a significant gap between it and the spot price after the first block; however, the adjustment in the second block, prior to executing the second trade, results in a close agreement thereafter.
Since only one trade has been executed on both the ETH and wBTC pools, the moving average for both remains at the genesis rate (i.e. the ema will update to the during the next trade).
Staking TKN
The ema serves as a detection mechanism for unusual spikes in the price of an asset against BNT, and prevents changes to the depth of the trading pools to protect the system from harm. To illustrate the effects of the ema, the current state of the system in the present narrative will be carried forward, with each of Alice, Bob, and Charlie providing one additional TKN to the system. Unlike the prior examples where liquidity is added, both the ema, and the pool token valuation need to be taken under consideration.
Before the demonstration continues, recall that each of the pools have a preset 4,000 BNT funding limit at this point in the narrative, and up to this point in time all three have only exhausted half of that amount. Further, recall that the ability to increase the available trading liquidity is determined by the vault balance of the TKN in question, and the current depth of the pool, rather than the amount being contributed by a user during any deposit event.
Alice now deposits 1 ETH. Since no fees have yet accrued to the bnETH pool tokens (i.e. ETH has not yet been the target of any particular trade), the value of the bnETH pool token remains unchanged. Her 1 ETH is added to the vault, the staking ledger is updated, and a new pool token is created for Alice.
Assume that this deposit is occurring on a block wherein no actions have taken place on the ETH pool. Therefore, the ema has not been updated in this block, and it remains where it was. This allows for the effective price quoted by the pool to be evaluated with a view to detecting artificial price manipulation. The protocol’s confidence is determined by the relative deviation between the ema and spot prices; the protocol will only allow the pool’s trading liquidity to be changed if the difference between these values is small.
In this instance, the addition of Alice’s 1 ETH occurs when the ema on ETH remains at 1,000, whereas its spot rate is 907.26. The deviation between the spot rate and the ema is measured relative to the ema, as follows:
Since Δ is fixed at 0.01, the equation above can be expressed as the following boolean:
where r is the spot rate. In this case, Δ is 0.0927; the tolerance of the protocol is 0.01. Therefore, the protocol will not allow the trading liquidity to be changed on this block. However, Alice’s 1 ETH is still accepted into the vault, and she is issued bnETH pool tokens as normal. Since there is no change to the trading liquidity, the protocol will not mint BNT, and will not issue itself bnBNT.
Bob now deposits 1 wBTC. In contrast to Alice’s situation, fees have accumulated on the wBTC pool token. Therefore, the rate of pool token issuance is affected. The staking ledger is reporting a staked amount of wBTC of 11.00004502, and the supply of bnwBTC is 11. Therefore, the rate of bnwBTC to wBTC is 0.999996, and this quotient determines the number of bnwBTC pool tokens Bob will receive.
Assume that this deposit is occurring on the same block as Alice’s deposit, where the trade between ETH and wBTC had been executed on the prior block. Therefore, the wBTC ema has not been updated in this block, and also remains at the genesis rate.
In this instance, the addition of Bob’s 1 wBTC coccurs when the ema on wBTC remains at 16,000, whereas its spot rate is at 17,534. The deviation (Δ) between the spot rate and the ema is 0.0959, and as before, the protocol will not allow the trading liquidity to be changed on this block. Regardless, the vault still accepts Bob’s wBTC, and issues him bnwBTC as normal.
Charlie now deposits 1 LINK. As was the case for Bob, the fee accrual on bnLINK will affect the issuance of pool tokens. The staking ledger is reporting a staked amount of LINK of 1,001.2424, and the supply of bnLINK is 1,001. Therefore, the rate of bnLINK to LINK is 0.9998, and the issuance of bnLINK to Charlie is determined by this number.
Assume that this deposit occurs on the block following the two LINK trades previously discussed. In this instance, the addition of Charlie’s 1 LINK occurs when the ema on LINK is 5.9998, whereas its spot rate is at 5.9988. The deviation (Δ) between the spot rate and the ema is 0.00017, which is inside the tolerance levels of the protocol, and the protocol will allow the trading liquidity to update.
Trading liquidity always updates according to a strict set of criteria. In simple terms, the protocol will always try to increase the liquidity by as much as possible, up to a maximum BNT liquidity increase of 2× relative to the current depth, and without exceeding the preset funding limit. In this example, the current BNT depth on the LINK pool is 2,094.0883. Therefore, with a sufficient funding limit, the pool could double in size, up to a maximum BNT depth of 4,188.1766 BNT. However, the protocol has previously contributed 2,000 BNT of its 4,000 BNT funding limit - it can only increase the trading liquidity by a maximum of 2,000 BNT. The protocol will always default to the smallest of these two values.
By convention, the protocol trusts the ema rate over the spot price. Therefore, in this example, the BNT/LINK quotient is treated as 5.9998. The maximum allowed increase is the BNT funding limit, 2,000 BNT. Therefore, 333.34444 LINK and 2,000 BNT are added to the trading liquidity. As the protocol is minting BNT, it is simultaneously issuing new bnBNT pool tokens for itself. Since the bnBNT pool token has appreciated in value, this will need to be taken into account. The
The staking ledger is reporting a staked amount of BNT of 6,002.3599, and the supply of bnBNT is 6,000. Therefore, the rate of bnBNT to BNT is 0.9996. As the protocol mints 2,000 BNT to increase the trading liquidity, this amount is added to the BNT staking ledger, and the protocol issues itself 1999.2137 bnBNT pool tokens.
Unstaking TKN
Withdrawals are predicated on two equally important concepts:
- Liquidity providers should be able to withdraw their stake entirely in the token they provided.
- Any withdrawal should not affect the stakes of other users.
The challenge to meeting these criteria is that the staked amounts will rarely be in agreement with the vault balances. The scale of the problem is also dependent on the proportion of the overall staked amounts being withdrawn by the user, and the relative deficit or surplus for the same TKN. Bancor 3 introduces a novel algorithm for processing withdrawals, which has been constructed specifically for use with the new architecture. This aspect of the protocol’s activities is the most technically challenging to understand. To help structure this part of the discussion, the examples will diverge from the narrative presented up to this point, and will instead use arbitrary cases to demonstrate the logic and consequences of the algorithm.
The state of the system is described using the following variables, and each is a discrete input in the withdrawal algorithm:
a, the BNT balance of the trading liquidity, as judged from the spot rate.
b, the TKN balance of the trading liquidity, as judged from the spot rate.
c, the difference between the TKN balance of the vault, and the TKN trading liquidity.
e, the TKN balance of the staking ledger.
m, the associated pool fee for the TKN being unstaked.
n, the exit fee of the system.
w, the TKN balance of the external protection wallet.
x, the precise TKN value of the bnTKN tokens being withdrawn.
The role of the moving average in unstaking actions is slightly different to staking actions. First and foremost, if the deviation (Δ) exceeds the protocol tolerance, the transaction is simply reverted; it is not possible to calculate a ‘default’ withdrawal if there is strong disagreement between the moving average and the spot rate. For the rest of this discussion, it is assumed that this tolerance check has passed.
Committing to the Cooldown
As described above, users commit to a 7-day cooldown period before their withdrawal is processed. Importantly, the value of the pool token is frozen at the commencement of the cooldown period. Therefore, any value appreciation on the pool token during the cooldown period is forfeited. However, the user may elect to cancel their withdrawal at any time, at which point the forfeited value is returned.
Consider the following situation. A user has 1,000 bnTKN tokens, valued at 2,000 TKN. After deciding to withdraw, they commit their bnTKN to the cooldown contract, and their value is recorded (x).
After 7 days have passed, the user will be entitled to receive the value associated with their stake, at the time the cooldown process was started. Imagine that during this time, the accumulation of rewards and/or trading revenue caused the bnTKN valuation to appreciate.
At any point during, or after the cooldown, the user may elect to cancel the withdrawal process. Moreover, once the cooldown process has completed, the user has unlimited time to make a decision. However, the value of their withdrawal (x), will persist; if the user commits to the cooldown and then waits a century before confirming the withdrawal following the cooldown, the value of their withdrawal remains the same as it was when they started the process. However, the moment they cancel the withdrawal, the x value is erased, and the bnTKN tokens are returned to their wallet. The action of re-committing to the cooldown then generates a new x value, and thus the user can easily retrieve any lost fees and rewards, assuming their cooldown period was poorly timed. In the example above, the user can improve their withdrawal valuation by 4.095% if they cancel, and then begin the cooldown again.
Introduction to the Withdrawal Algorithm
After a withdrawal has been confirmed by the user, the protocol’s task is to deliver the withdrawal value back to the user, either entirely in TKN, or as a combination of TKN and BNT. The design of Bancor 3 assumes that users prefer to receive their withdrawal denominated entirely in TKN. Naively, it seems impossible to return all funds denominated in TKN to the user, if the total TKN in the vault is less than the staked balance, without exacerbating the deficit further. Therefore, in cases where the vault balance of TKN is less than the amount staked, the protocol has an obligation to cover the deficit via BNT minting. While true, one could argue that the user is likely to use the BNT they are issued to perform a swap for the TKN that was withheld. In doing so, the user indeed removes additional funds from the protocol; however, such an action also opens an opportunity wherein an arbitrageur will return the pool to balance, and restore the relative deficit of the system.
The opposite is also true. Imagine the antithetical case where users provide BNT exclusively, and the protocol mints the TKN side of the pool. During a BNT deficit, a user’s withdrawal may be partially reimbursed in TKN, which they may immediately swap back for BNT. As they perform the swap, the relative price of BNT is increased vs TKN, then rebalanced with external markets through the actions of arbitrageurs.
This is an important realization. The assertion that BNT must be used to compensate TKN liquidity providers directly, (and by extension, TKN to BNT providers in an imaginary version) becomes weak. Rather than give the user BNT for them to swap, the swap can be made an implicit component of the withdrawal. Further, TKN in excess can be used to recover lost BNT, and help to maintain a healthy equilibrium between the protocol and its environment.
While this reasoning is good, it is also incomplete. The value of a swap is impacted by slippage, and therefore the depth of the pool, as well as its swap fee. Moreover, the fact that a BNT minting event could be coupled with an implicit swap opens the protocol to potential abuse through withdrawal back running attacks, which artificially increases the value of a user’s withdrawal. As alluded to in an earlier section, a withdrawal fee of 0.25% is introduced, and is used to evaluate the explicit exploitability of the method. In short, so long as the back running profit margin is equal to or less than the value represented by the withdrawal fee, then the protocol will allow the user to withdraw the totality of their position exclusively in TKN, regardless of the deficit. Similarly, the protocol will attempt to recover BNT by quoting it at a higher price when withdrawals are performed during a TKN surplus state, only if the arbitrage value is less than the withdrawal fee.
In addition to these considerations, the protocol also maintains an awareness of the current pool depth, and the TKN available in the vault which are not presently available as trading liquidity on the pool. The withdrawal algorithm simultaneously handles these considerations, such that the user’s withdrawal is taken exclusively from non-trading vault reserves where possible, and the anticipated, rebalanced state of the pool returns to its prior depth level. One way to visualize this behavior is to imagine the continuum of both the available trading liquidity, and non-trading liquidity as a proportion of the balance on the staking ledger. Let these proportions be the x and y axes of a three-dimensional plot, where the z axis represents the relative size of any withdrawal, relative to the total balance of the staking ledger. The resulting plot describes a surface, the volume under which defines all possible withdrawals where the protocol can exercise the logic above without causing itself financial disadvantage. Importantly, the exit fee and swap fee for the specific asset undergoing withdrawal change the shape of the surface. The plot below assumes a swap fee of 0.2% and a withdrawal fee of 0.25%.