Tokens
哪裡可以找到線性/對數減少的 ICO 合約?
我查看了一些現有的眾籌合約:
- https://github.com/aragon/aragon-network-token/blob/master/contracts/AragonTokenSale.sol
- https://github.com/sonm-io/presale-token/blob/master/contracts/PresaleToken.sol
- https://github.com/ConsenSys/Tokens/tree/master/Token_Contracts/contracts
- https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts/crowdsale
- https://github.com/Giveth/minime/blob/master/contracts/MiniMeToken.sol
- https://github.com/TokenMarketNet/ico/tree/master/contracts
- 乙太輥: https ://etherscan.io/address/0xa9a8108994bb704261567e53b49607a73876ddf1#code
下面是來自 Aragon 原始碼的 ASCII 圖。而不是階段,我想找到一個實現代幣數量線性或對數減少的合約……
假設我們有
M
最大數量的代幣要出售,每個代幣I
的初始價格和每個代幣F
的最終價格。讓我們呼叫f
給出每個代幣價格的函式,我們知道f(0) = I
和f(M) = F
。如果你想要一個線性價格,那麼f(x) = I + (F - I) * x / M
。
V
問題是確定當我們付款並且已經售出代幣時我們將獲得多少K
代幣。假設我們將獲得D
代幣,我們知道我們的初始價格將是f(K)
和最終獎品f(K + D)
,總價格將是圖表下方的。是的數學!所以我們會有等式
要確定出售
V
乙太幣的代幣數量,我們必須求解二次方程(F-I)D
2+ 2(MI + (F-I)K)D - 2MV = 0
。是的,更多的數學!例如在我的情節中
I=100, F=225, M=500
。然後當有K=150
1000 個乙太幣時,我們將得到:D = (-2*(50000+125*k)+sqrt(4*(50000+125*k)**2 + 500000*v))/250 = 7.225268630201346
(D 的另一個解是否定的)
如果我們想在已經售出 150 個代幣時購買 10 個代幣,我們必須支付 (K=150, D=10)
V = ID + (F-I)*(2KD + D^2)/(2M) V = 1000 + 125*(20*150 + 100)/1000 V = 1387.5
為了計算我們設置 K=0, D=500 的總reaudation
V = 100*500 + 125*(500^2)/(2*500) V = 81250.0
我們可以驗證這是情節的面積。
基於@Ismael 解決方案的 Solidity 程式碼假設價格呈線性增長。
// tokens sold uint256 tokensSold; // tokens to be sold in total uint tokensToBeSold = 100000000*(10**18); uint ip = 5000; uint fp = 10000; // final price - initial price uint256 pd = fp - ip; // total supply * initial price uint256 tsip = tokensToBeSold * ip; // helper token emission functions function howMany(uint256 value) public returns (uint256){ uint256 a = sqrt(4 * ((tsip + pd * tokensSold) ** 2) + value.mul(8 * pd * tokensToBeSold)); uint256 b = 2 * (tsip + pd* tokensSold); uint256 c = 2 * pd; // get a result with return round(((a - b)* 10) / c); } // Rounding function for the first decimal function round(uint x) internal returns (uint y) { uint z = x % 10; if (z < 5) { return x / 10; } else { return (x / 10) + 1; } } // Squareroot implementation function sqrt(uint x) internal returns (uint y) { uint z = (x + 1) / 2; y = x; while (z < y) { y = z; z = (x / z + z) / 2; } }