# CW20 Bonding

Source code is at cw20-bonding.

## Design​

There are two variants - accepting native tokens and accepting cw20 tokens as the reserve token (this is the token that is input to the bonding curve).

Minting: When the input is sent to the contract (either via `ExecuteMsg::Buy{}` with native tokens, or via `ExecuteMsg::Receive{}` with cw20 tokens), those tokens remain on the contract and it issues it's own token to the sender's account (known as supply token).

Burning: We override the burn function to not only burn the requested tokens, but also release a proper number of the input tokens to the account that burnt the custom token

Curves: `handle` specifies a bonding function, which is sent to parameterize `handle_fn` (which does all the work). The curve is set when compiling the contract. In fact many contracts can just wrap `cw20-bonding` and specify the custom curve parameter.

Read more about bonding curve math here

Note: the first version only accepts native tokens as the

### Math​

Given a price curve `f(x)` = price of the `x`th token, we want to figure out how to buy into and sell from the bonding curve. In fact we can look at the total supply issued. let `F(x)` be the integral of `f(x)`. We have issued `x` tokens for `F(x)` sent to the contract. Or, in reverse, if we send `x` tokens to the contract, it will mint `F^-1(x)` tokens.

From this we can create some formulas. Assume we currently have issued `S` tokens in exchange for `N = F(S)` input tokens. If someone sends us `x` tokens, how much will we issue?

`F^-1(N+x) - F^-1(N)` = `F^-1(N+x) - S`

And if we sell `x` tokens, how much we will get out:

`F(S) - F(S-x)` = `N - F(S-x)`

Just one calculation each side. To be safe, make sure to round down and always check against `F(S)` when using `F^-1(S)` to estimate how much should be issued. This will also safely give us how many tokens to return.

There is built in support for safely raising i128 to an integer power. There is also a crate to provide nth-root of for all integers. With these two, we can handle most math except for logs/exponents.

Compare this to writing it all in solidity

Examples:

Price Constant: `f(x) = k` and `F(x) = kx` and `F^-1(x) = x/k`

Price Linear: `f(x) = kx` and `F(x) = kx^2/2` and `F^-1(x) = (2x/k)^(0.5)`

Price Square Root: `f(x) = x^0.5` and `F(x) = x^1.5/1.5` and `F^-1(x) = (1.5*x)^(2/3)`

We will only implement these curves to start with, and leave it to others to import this with more complex curves,