Ich habe mir einige bestehende Crowdsale-Verträge angesehen:
Unten sehen Sie ein ASCII-Diagramm aus dem Aragon-Quellcode. Anstatt Stufen würde ich gerne einen Vertrag finden, der eine lineare oder logarithmische Abnahme der Token-Menge umsetzt ...
Nehmen wir an, wir haben M
die maximale Menge an zu verkaufenden Token, I
den Anfangspreis für jeden Token und F
den Endpreis für jeden Token. Rufen wir f
die Funktion auf, die den Preis jedes Tokens angibt, das wissen wir f(0) = I
und f(M) = F
. Wenn Sie einen linearen Preis wünschen, dann f(x) = I + (F - I) * x / M
.
Das Problem besteht darin, zu bestimmen, wie viele Token wir erhalten, wenn wir bezahlen V
und bereits K
verkaufte Token vorhanden sind. Nehmen wir an, wir erhalten D
Token, wir wissen, dass unser Anfangspreis f(K)
und f(K + D)
der Endpreis sein werden, und der Gesamtpreis wird unter dem Diagramm liegen. Ja Mathe!
Wir werden also die Gleichung haben
Um die Menge an Token zu bestimmen, die für V
Ether verkauft werden sollen, müssen wir die Gleichung 2. Grades (F-I)D
2+ 2(MI + (F-I)K)D - 2MV = 0
lösen . Ja, mehr Mathe!
Zum Beispiel in der Handlung habe ich I=100, F=225, M=500
. Wenn es dann K=150
1000 Ether gibt, erhalten wir:
D = (-2*(50000+125*k)+sqrt(4*(50000+125*k)**2 + 500000*v))/250 = 7.225268630201346
(die andere Lösung für D ist negativ)
Wenn wir 10 Token kaufen wollen, obwohl bereits 150 verkauft wurden, müssen wir bezahlen (K=150, D=10)
V = ID + (F-I)*(2KD + D^2)/(2M)
V = 1000 + 125*(20*150 + 100)/1000
V = 1387.5
Zur Berechnung der Gesamtreaudation setzen wir K=0, D=500
V = 100*500 + 125*(500^2)/(2*500)
V = 81250.0
Wir können überprüfen, ob dies der Bereich des Grundstücks ist.
Solidity-Code basierend auf der Lösung von @Ismael, geht von einer linearen Preissteigerung aus.
// 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;
}
}
Mars Robertson
rollback
Funktion verwendet, um die Bearbeitung rückgängig zu machen - die vollständige URL zu Github ist viel informativer als ein formatierter Link.