(* This pulls on the following posts: - https://blog.relevant.community/bonding-curves-in-depth-intuition-parametrization-d3905a681e0a - https://medium.com/@aventus/token-bonding-curves-547f3a04914 - *) dS[dB_,S0_,B0_,RR_]:=S0 * ((1 + dB / B0) ^ (RR) - 1) dB[dS_,S0_,B0_,RR_]:= B0 * (1 - (1 - dS / S0)^(1/RR)) RR := 1/3 s0 := 1 b0 := 1 b1 := 2 s1 := s0+dS[b1-b0,s0,b0,RR] If[ dB[s1-s0,s1,b1,RR] == b0, "SUCCESS: Buying 1 BitClout worth of creator coin and then selling works", "ERROR: Buying 1 BitClout worth of creator coin and selling *DOES NOT* work" ] In[1]:= (*Someone buys db0 worth of creator coin*) vs1 := s_start+dS[db0,s_start,b_start,RR] vb1 := b_start+db0 ds0 := vs1-s_start (*We add subsidy to the pool without modifying anything else*) vb1 = vb1+subsidy; (*Now the user sells their initial amount and gets some new bitclout*) dbFinal := dB[ds0,vs1,vb1,RR] Simplify[dbFinal]; (*Can dbFinal ever be more than db0+subsidy?*) Print["The diff below should be >0 for all possible values of subsidy, db0, and b_start:"] Print["db0+subsidy - dbFinal = ", Simplify[db0+subsidy-dbFinal]] (*Nice properties of the quantity that results from the above: - As long as subsidy, b_start, and db0 are all >0 then this quantity should always be >0 as desired. - If subsidy is zero then the diff is zero. This makes sense because what you put in (=db0) should equal what you get out (=dbFinal) when there isn't a subsidy. - If b_start is small then this quantity will be small, meaning the amount the user loses due to "slippage" from our fudging factor should also be small. *) (*Follow-up: Is there a way to make it so that the slippage from this bullshit is zero?*) (*Working out formulas for the polynomial version to make them match Bancor*) polyPriceWithSlope[m_,s_,RR_]:=m*s^(1/RR-1) polyBitcloutWithSlope[m_,s_,RR_]:=m/(1/RR)*s^(1/RR) polyDb[dS_,m_,s_,RR_]:=polyBitcloutWithSlope[m,s+dS,RR]-polyBitcloutWithSlope[m,s,RR] (*This formula assumes you know b, the amount of BitClout purchased*) simplePolyDb[dS_,m_,s_,b_,RR_]:= b*((dS/s+1)^(1/RR)-1) (*The simplified formula should equal the full formula*) If[ (Simplify[Simplify[polyDb[kk, mm,ss,rr]]/Simplify[simplePolyDb[kk,mm,ss,polyBitcloutWithSlope[mm,ss,rr], rr]]]/.ss->3) == 1, Print["SUCCESS: The simplified formula for polynomial dB equals the full formula"], Print["ERROR: The simplified formula for polynomial dB is *NOT EQUAL* to the full formula"]] RR=. dsVar /.Solve[polyDb[dsVar,m,s,RR]==dB,dsVar][[1]] polyDs[dB_,m_,s_,RR_]:=-s + (-((-dB - m RR s^(1/RR))/(m RR)))^RR (*This formula assumes you know b, the amount of BitClout purchased*) simplePolyDs[db_,m_,s_,b_,RR_]:=s*((db/b+1)^(RR)-1) If[Simplify[polyDs[dB,m,s,rr]/simplePolyDs[dB,m,s,polyBitcloutWithSlope[m,s,rr],rr] /.{s->3,dB->5,rr->7,m->11}]==1, Print["SUCCESS: The simplied formula for polynomial dS equals the full formula"], Print["ERROR: The simplied formula for polynomial dS *DOES NOT* equal the full formula"]] (*This agrees with what you get when you solve: c0 x^(1/RR-1) = b/(s*RR) *) slopeInTermsOfVars=. slopeInTermsOfVars[s_,b_,RR_]:=b*1/RR/s^(1/RR) If[slopeInTermsOfVars[1,1,1/3.]==3, Print["SUCCESS: Formula for m in terms of (s,b,RR) is working!"], Print["ERROR: Formula for m in terms of (s,b,RR) is NOT working"]] If[polyDs[1,slopeInTermsOfVars[1,1,1/3.],1,1/3.]==0.2599210498948732`, "SUCCESS: Polynomial formulas match Bancor formulas!", "ERROR: Polynomial formulas do *NOT* match Bancor formulas!"] If[(Simplify[polyDb[s,m,0,RR]]/.RR->1/3)==m*s^3/3, "SUCCESS: Formula for Db at zero is correct", "ERROR: Formula for Db at zero is WRONG"] If[(Simplify[polyDs[p,m,0,RR]]/.RR->1/3)==3^(1/3)*(p/m)^(1/3), "SUCCESS: Formula for Ds at zero is correct", "ERROR: Formula for Ds at zero is WRONG"] In[122]:= (*How do our price curves change as BitClout price increases?*) (**) (*This is the price in USD given some amount of USD has been put into a profile*) priceUSDGivenUSDPurchased[usdPurchased_, bitcloutPriceUSD_]:=polyPriceWithSlope[mm,polyDs[usdPurchased/bitcloutPriceUSD,mm,0,rr],rr] (*Compute the above function for two different values of bitcloutPriceUSD and divide them*) xxx[usdPurchased_,bitcloutPriceUSD_]:=Simplify[priceUSDGivenUSDPurchased[usdPurchased,bitcloutPriceUSD,mm,rr]/priceUSDGivenUSDPurchased[usdPurchased,bitcloutPriceUSD * p,mm,rr]] (*The result should be p^1/3*) If[(Simplify[xxx[usdPurchased,bitcloutPriceUSD]/.{mm->5,rr->1/3,usdPurchased->7,bitcloutPriceUSD->11}]/p^(1/3)/.p->13) == 13^(1/3), "SUCCESS: The USD price of a profile given a certain amount of USD purchased is scaled by bitcloutPriceUSD^(1/3)", "ERROR: The USD price of a profile is *NOT* scaled by bitcloutPriceUSD^(1/3)" ] In[19]:= (*Scratch below this point*) (*Start with a Bancor pool with some amount of BitClout and zero creator coin*) bStart = 3; sStart = 0; rr=1/3; bitcloutPutIn = 5; m = slopeInTermsOfVars[1,1,rr]; (*Buy some coins initially using the polynomial model*) coinPurchased =polyDs[bitcloutPutIn,m,0,rr]; (*Get the polynomial price after buying some coins using the polynomial model*) N[polyPriceWithSlope[m,coinPurchased,rr]] (*Get the Bancor price after buying some coins using the polynomial model*) N[(bStart+bitcloutPutIn)/(coinPurchased * rr)] (*Now sell this creator coin for $BitClout using the Bancor formula*) (*db0 = dB[coinPurchased, sStart+coinPurchased,bStart+bitcloutPutIn,rr]*) m=. Print[-s + (-((-dB - m RR s^(1/RR))/(m RR)))^RR /.s->0]