Proposing Carbon - DRAFT (DEPRECATED)

Clarification - Carbon Vortex Contract:

For clarity - this section of the proposal discusses adapting the Bancor Vortex contract for use with Carbon, where the destination token is BNT, not vBNT, in alignment with the unambiguous precedent already established.



Standardizing Bancor Vortex Contract:

The Bancor Vortex is now 2 years old, and the underlying concept has already been subject to substantial revisions. Notably, the advantages of its dependence on vBNT is no longer a clear advantage as the paradigms on which this system was founded are no longer in effect, and the BNT vBNT pair is essentially at parity.

To maintain a clean implementation, this proposal asks for the vBNT burning actions of the legacy products (V2.1 and V3) to be superseded with direct destruction of BNT. Thus, the Bancor Vortex contracts will be general, and equally applicable in all contexts involving the recovery of BNT from the market, and returning all instances of deficit back to surplus.



Clarification - Carbon Vortex Contract:

For clarity - this section of the proposal proposes to bring the implementation of the Bancor Vortex on V2.1 and V3 in-line with the proposed implementation on Carbon. Therefore, there will be one universal Vortex contract, which exchanges protocol fees for BNT, and burns it.


BNT Burning:

BNT Burning Mechanism on Carbon:

  • The protocol’s accumulated token balances from taker and maker fees will be prominently displayed on Carbon’s complement analytics dashboard.
  • The Bancor Vortex contract will be modified for use with Carbon, and will offer 2% of the exchanged value in BNT, up to a maximum of 100 BNT, back to the caller as an incentive.
  • Therefore a revision to the existing precedent is required: “no less than 98%, and up to 100% of the protocol fees from Carbon should be used to recover BNT from the market, and destroy it”, where the difference is attributed exclusively to the effective cost of incentivizing the Vortex contract’s caller.
  • Therefore, any protocol fees denominated in a token that is paired with BNT on V2.1 or V3 can be serviced easily by the community.
  • Tokens not paired with BNT on V2.1 or V3 will be held in the protocol wallet until an alternative mechanism is proposed that does not have this limitation.


Standardization of Bancor Vortex Modifications:

  • With this proposal, the changes to the Bancor Vortex contract are proposed to be made standard.
  • The standardization means that on Bancor V2.1 and V.3, as on Carbon, protocol fees are used to recover BNT and destroy it directly.
  • Approval of this part of the proposal signals that the BancorDAO understands that vBNT will no longer serve a use case as part of the Vortex mechanism.

Voting Instructions:

BIP 23 - BancorDAO Authorization of Carbon Deployment on Ethereum Mainnet:

This decision relates to Carbon, as described in the litepaper, white paper, and its ancillary simulation and research materials as they appear on GitHub and JupyLite .

  • Vote FOR to agree to the deployment of Carbon on Ethereum mainnet.

  • Vote AGAINST to disagree to the deployment of Carbon on Ethereum mainnet.

BIP 24 - Taker Fee Implementation and Initial Settings:

This decision relates to the initial value of the taker fee on Carbon, and is contingent on the authorization of the BancorDAO to deploy the proposed Carbon protocol on Ethereum mainnet.

  • Vote FOR to agree to the proposed taker fee implementation, and initial value of 0.2% (20 bps), applied protocol-wide to all tokens and token pairs.

  • Vote AGAINST to defeat the proposal, requiring either a future proposal for a new taker fee concept, quantity, or to indicate you would prefer no taker fee at all.

BIP 25 - Maker Fee Implementation and Initial Settings:

This decision relates to the tentative maker fee implementation, where fees are collected in the gas token of the chain Carbon is deployed on, and targets an approximate $1 value (0.0005 ETH) at the time of writing, with its initial deployment on Ethereum.

  • Vote FOR to agree to the five proposed maker fee categories, and initial settings of 0.0005 ETH (approx. $1 at the time of writing) for each, which is applied equally to all maker actions, regardless of the position size.

  • Vote AGAINST to defeat the proposal, requiring either a future proposal for a new maker fee concept, quantity, or to indicate you would prefer no maker fee at all.

BIP 26 - BancorDAO Authorization of Carbon Deployment on Ethereum Mainnet in Lieu of Maker Fee Implementation:

This decision relates to the approval of Carbon’s deployment at its soonest available date, with or without a finalized maker fee implementation.

  • Vote FOR to agree to an initial Carbon deployment, with or without a maker fee implementation.

  • Vote AGAINST to require a maker fee implementation prior to the initial release of Carbon.

BIP 27 - Protocol Fee Maintenance Policy:

This decision relates to the proposed constancy requirement and DAO process for maintaining reasonable fee values for Carbon, wherever it is deployed.

  • Vote FOR to agree that a maximum 180 day period between proposal submissions to review protocol fee settings for Carbon, wherever it is deployed, should become part of the DAO canon.

  • Vote AGAINST to disagree to the fee review policy, requiring either a future proposal for a different policy, or no policy at all.

BIP 28 - BNT Burning Policy and Procedures on Carbon:

This decision relates to the proposed use of the Bancor Vortex to perform exchange between the protocol’s accumulated tokens and BNT for the purpose of returning token balances on Bancor’s legacy protocols to surplus.

  • Vote FOR to agree to the proposed Vortex implementation, and the following revision to a prior vote: “no less than 98% and up to 100% of the protocol fees from Carbon should be used to recover BNT for the express purpose of burning it, where the difference between the burning efficiency and 100% is attributable to the cost of incentivizing the contract’s caller”.

  • Vote AGAINST to disagree with the proposed use of the Bancor Vortex, and/or the provided revisions to the prior vote, requiring a future proposal.


BIP 29 - Standardization of the Vortex contracts:

This decision relates to the proposed changes to the Bancor Vortex contracts, where BNT becomes the exclusive target of the Vortex, rather than vBNT, for the purpose of returning token balances on Bancor’s legacy protocols to surplus.

  • Vote FOR to agree to the proposed standards, thus removing Vortex dependence on vBNT.

  • Vote AGAINST to indicate that two separate procedures should be maintained (one for Carbon, and one for Bancor’s legacy products V2.1 and V3) where the procedure on Carbon results in the destruction of BNT directly, and the procedure on V2.1 and V3 results in the destruction of vBNT via an intermediate swap.



Taker Fees Discussion Section Generator:

from tabulate import tabulate
from decimal import Decimal, getcontext
import textwrap
getcontext().prec = 100

ONE = Decimal("1")
TWO = Decimal("2")

# Curve Parameters
P_a = Decimal("2.3456")
P_b = Decimal("1.2345")
B = Decimal.sqrt(P_b)
S = Decimal.sqrt(P_a) - Decimal.sqrt(P_b)
y_int = Decimal("1000")
y = Decimal("500")
fee = Decimal("0.002")

def print_parameter_table():
    table = (("Curve Parameter", "Value", "Notes"),
             ("$B$", f"{B:.6f}", "The highest ask (y = BASE), or lowest bid (y = QUOTE) boundary metric, depending on context."),
             ("$S$", f"{S:.6f}", "The range width parameter."),
             ("$y_{int}$", f"{y_int:.6f}", "The curve capacity metric."),
             ("$y$", f"{y:.6f}", "The remaining token balance"),
             ("$fee$", f"{fee:.6f}", "The protocol fee setting."))
    print(tabulate(table, headers = "firstrow", tablefmt = "pipe", floatfmt = ".6f", numalign = "right", stralign = "left"))

def print_summary_table(scenario_1, scenario_2):
    table = (("Scenario", "Taker Sent", "Taker Received", "Maker Sent", "Maker Received", "Protocol Fee Collected"), scenario_1, scenario_2)
    print(tabulate(table, headers = "firstrow", tablefmt = "pipe", floatfmt = ".6f", numalign = "right", stralign = "right"))

def print_trade_by_target_text(taker_sends_1, maker_sends_1, taker_receives_1, protocol_receives_1):
    text = (f"The taker requests to send exactly {taker_sends_1:.6f} QUOTE tokens to the protocol, all of which is swapped against the maker's order, and returns a value of {maker_sends_1:.6f} BASE tokens. Of the {maker_sends_1:.6f} BASE tokens relinquished by the maker's order, the taker keeps {taker_receives_1:.6f} BASE, and the protocol keeps {protocol_receives_1:.6f} BASE.")
    print(textwrap.fill(text, width = 132))

def print_trade_by_source_text(taker_receives_2, maker_receives_2, taker_sends_2, protocol_receives_2):
    text = (f"The taker requests to receive exactly {taker_receives_2:.6f} BASE tokens from the protocol. To satisfy the requirements of the maker's order, exactly {maker_receives_2:.6f} QUOTE tokens must be exchanged (ignoring the fee). After adjusting for the protocol fee, the taker must send a total of {taker_sends_2:.6f} QUOTE tokens to the protocol. The protocol keeps {protocol_receives_2:.6f} QUOTE tokens, and the remaining {maker_receives_2:.6f} QUOTE tokens are exchanged with the maker's order for {taker_receives_2:.6f} BASE tokens, which are sent from the protocol to the taker.")
    print(textwrap.fill(text, width = 132))

text_functions = [print_trade_by_target_text, print_trade_by_source_text]

def trade_by_target(maker_receives):
    maker_sends = maker_receives*(B*y_int + S*y)**TWO/(maker_receives*S*(B*y_int + S*y) + y_int**TWO)

def trade_by_source(maker_sends):
    maker_receives = (maker_sends*y_int**TWO)/((S*y + B*y_int)*(B*y_int + S*(y - maker_sends)))

swap_functions = [trade_by_target, trade_by_source]

def apply_fee_trade_by_target(maker_sends):
    taker_receives = maker_sends*(ONE - fee)
    protocol_receives = maker_sends*fee
    return(taker_receives, protocol_receives)

def apply_fee_trade_by_source(maker_receives):
    taker_sends = maker_receives/(ONE - fee)
    protocol_receives = taker_sends - maker_receives
    return(taker_sends, protocol_receives)

fee_functions = [apply_fee_trade_by_target, apply_fee_trade_by_source]
protocol_fees = ["BASE", "QUOTE"]

def perform_swap(input_array):
    scenarios = []
    for i, j in enumerate(input_array):
        print(f"##### *Scenario {i + 1}:*")
        output = swap_functions[i](j)
        fee_adjusted_outputs = fee_functions[i](output)
        scenario_template = [f"{i + 1}", f"{j:.6f} QUOTE", f"{j:.6f} BASE", f"{j:.6f} BASE", f"{j:.6f} QUOTE", f"{fee_adjusted_outputs[1]:.6f} {'BASE' if i == 0 else 'QUOTE'}"]
        scenario_template[2 - i] = f"{fee_adjusted_outputs[0]:.6f} {'BASE' if i == 0 else 'QUOTE'}"
        scenario_template[3 + i] = f"{output:.6f} {'BASE' if i == 0 else 'QUOTE'}"
        text_functions[i](j, output, fee_adjusted_outputs[0], fee_adjusted_outputs[1])

def numerator(seed_input, fee_multiplier):
    return(seed_input*fee_multiplier*(B*y_int + S*y)**TWO)

def denominator(seed_input, fee_multiplier):
    return(S*seed_input*fee_multiplier*(B*y_int + S*y) + y_int**TWO)

def create_examples(seed_input):
    example_1_scenario_1 = example_2_scenario_1 = example_3_scenario_1 = seed_input
    example_1_scenario_2 = numerator(seed_input, ONE)/denominator(seed_input, ONE)
    example_2_scenario_2 = numerator(seed_input, ONE - fee)/denominator(seed_input, ONE)
    example_3_scenario_2 = numerator(seed_input, ONE - fee)/denominator(seed_input, ONE - fee)
    return((example_1_scenario_1, example_1_scenario_2),
           (example_2_scenario_1, example_2_scenario_2),
           (example_3_scenario_1, example_3_scenario_2))

def write_taker_fees_proposal_section(seed_input = Decimal('10')):
    swaps = create_examples(seed_input)
    subheadings = ("Constant Maker Send and Receive Amounts.",
                   "Constant Taker Receive Amount.",
                   "Constant Taker Send Amount.")
    for i, input_array in enumerate(swaps):
        print(f"#### Example {i + 1}: {subheadings[i]}")
        scenario_1, scenario_2 =  perform_swap(input_array)
        print(f"##### *Example {i + 1} Summary:*")
        print_summary_table(scenario_1, scenario_2)


Re: BIP28. Not impressed with how quickly commitment to the recovery percentage has dropped from 100% to (no less than) 90%. Is there no way for the protocol to just eat the cost and automate the conversion procedure, rather than requiring manual intervention every time?

Re: BIP29. In a recent proposal about adjusting the vortex fee share, we were told that we can’t reduce the vortex to 10% on the DAI pool; “since the vortex is a global parameter, if changed, it affects all pools in the same way”. That means that no individual pool can be adjusted according to its deficit state, and all v2/v3 LPs keep giving virtually all their fees to the protocol, gaining no benefit from remaining as LPs. So if the v2/v3 vortex is superceded by a universal Carbon+v2/v3 vortex, doesn’t that mean there’s even less chance of v2/v3 LPs ever having the fee share adjusted to a beneficial ratio again? So there’ll be even less incentivisation for any existing LPs to remain LPs as soon as their deficit reaches tolerable levels.

It sounds like if the universal/standardised vortex takes over, existing LPs lose 100% of all their fees earned (bringing v3 LPs in line with v2), and the only person who benefits from fees is the manual function caller, who wouldn’t earn the fees in their choice of TKN even if its an existing LP calling the function. If that’s the case, then I don’t see the net benefit in forcing v2/v3s into the Carbon vortex under a standardisation, rather than maintaining as is and having Carbon run its own separate vortex.


Easily voting “For” on all of these.


I wish there was an easy way. Not to worry - that 10% number is arbitrary. I would support a lower incentive, and happy to edit the proposal. What number would you think reasonable, keeping in mind that the caller must foot the gas cost. Maybe 5%?

I would much prefer to write that no less than 95% and up to 100% of the fees result in burning BNT. We could go lower. Even a 2% incentive is tenable, it just means the burns will be less frequent. I don’t think that is too big a concern, though.


It is true that the Vortex contracts use global values - they do not have a per-token setting. However, nothing proposed here affects that limitation. Its not clear (to me) how the burning of BNT directly (instead of vBNT) impacts the liklihood of a future beneficial ratio proposal. Having said that, I would prefer that users do withdraw when their liquidity pools are back in surplus. My only ambition for the past year (feels like a lifetime now) is to recover the state of V2.1 and V3, with the target being that every LP can withdraw everything in entirety. I am not afraid of everyone pulling their liquidity when it is back in surplus. On the contrary - that is the goal.


I am going to be AFK for about 9-10 hours. I will be back to respond to any comments/questions that may have accumulated during that time ASAP.


I believe the impact on likelihood of a future beneficial ratio proposal there is that people invested in the success of Carbon (and thereby adjustments to its parameters) will only care about BNT buying/burning mechanisms, since they’ll never have existed in a context of earning fees from the protocol. The higher that is, the better for them. Their primary source of benefit is either meant to be use of Carbon for automated trading, or speculation on BNT appreciation due to Carbon’s pro-BNT buy/burn mechanics.

Meanwhile, v2/v3 LPs were supposed to benefit from protocol use through fees accrued in TKN. So if the vortex is universal, it seems that the goals of the two groups will not be aligned if we get to a point where deficit is reduced; Carbon natives will want to preserve system that maximises return for BNT, whilst Bancor TKN LPs would like to finally earn some actual TKN fees again. But if we acknowledge (as you and other contributors seem to have done) that v2 and v3 are essentially abandonware and LPs are actively encouraged to leave Bancor as soon as their deficit is tenable, then I suppose the thought of them earning fees for LPing (and thus adjusting the ratio in a universal vortex) doesn’t really matter.



I think a good approach would be to write a proposal, that explicitly addresses what should happen as the protocol returns to surplus. I would be very happy to work on it with you.

For example, we could start with V3 on a per-token basis. Once a token is back to surplus, we can propose that the trading liquidity be reduced, and the off-curve liquidity increased to be precisely the number required to cover all deposits.

Unfortunately we dont have that kind of flexibility on V2.1, but we can work on something.

Then, we can mandate that once every single token on V2.1 and V3 is back to surplus (these can be done separately), that the Vortex contract is retired completely on these legacy protocols.

If you like, I could draft something? I would prefer we work together on it, but I can at least get the process started.


Imo, Mark’s reply below is a good concession. But I think in reality the DAO would almost always vote to keep the vortex burning.
There is a lot of Protocol Owned liquidity that can earn fees and burn more BNT for us, while users withdrawing their LP will just burn more BNT.
We have seen that more TVL doesn’t correlate with the same increase in fees, even more, so more TVL can actually be more damaging as the IL can rack up more.

I think we should incentivize users to go to Carbon as much as possible and just let Bancor be an arbitrage protocol.
Carbon will just be that much more efficient at managing liquidity and with the dev manpower being as stretched as it is, deploying too many hours on a semi-death (no offense) protocol seems like a waste.


  • DAO will probably always vote to keep the vortex burning as there will be cases of POL outweighing lps anyway
  • We don’t necessarily need more TVL, probably need to actually disable trading liquidity in a lot of pools cause of IL
  • Focus should be as much as possible to incentivize users to go to Carbon as it’s much more efficient
  • Limited manpower makes our resources stretched thin thus we need to make hard choices in what to support and whatnot.

To also add, will probably be voting yes on all proposals, but we should maybe take a look at the vortex payment fee. We shouldn’t fall into the same trap as what we had at the beginning when we were paying vortex initiators way too much money. So much money that even with the reduction we implemented it still was more than profitable enough.

Tagging Mark also.


Yep, agreed.

Let’s roll it back to something like 2%? I can edit the proposal later today.


would this mean that all these BIPs will go live on snapshot together at the same time and votes would have to vote on each one separately?


Yes, a 2% drop versus a 10% drop on the protocol fees is definitely a much more palatable shift; if Carbon drives trading volume, then callers should still be able to make profit off that.


Yep, 2% seems good. We can always adjust it afterward if it’s still too much or not enough.



This document is designed to have all the relevent information in one place. However, each decision is specifically itemized.


Done. I have changed all of the “90%” to “98%” and all “10%” to “2%”. Let me know if you find any parts where I missed one of these numbers.