Eché un vistazo a algunos contratos de crowdsale existentes:
A continuación se muestra un gráfico ASCII del código fuente de Aragón. En lugar de etapas, me gustaría encontrar un contrato que implemente una disminución lineal o logarítmica en la cantidad de tokens...
Supongamos que tenemos M
la cantidad máxima de tokens para vender, I
el precio inicial de cada token y F
el precio final de cada token. Llamemos a f
la función que da el precio de cada ficha, lo sabemos f(0) = I
y f(M) = F
. Si desea un precio lineal entonces f(x) = I + (F - I) * x / M
.
El problema es determinar cuántos tokens obtendremos cuando paguemos V
y ya haya K
tokens vendidos. Digamos que obtendremos D
tokens, sabemos que nuestro precio inicial será f(K)
y el premio final f(K + D)
, y el precio total será el que se muestra debajo del gráfico. ¡Sí matemáticas!
Entonces tendremos la ecuación
Para determinar la cantidad de tokens a vender por V
ethers tenemos que resolver la ecuación de segundo grado (F-I)D
2+ 2(MI + (F-I)K)D - 2MV = 0
. ¡Sí, más matemáticas!
Por ejemplo, en la trama que he I=100, F=225, M=500
. Luego cuando haya K=150
para 1000 ethers obtendremos:
D = (-2*(50000+125*k)+sqrt(4*(50000+125*k)**2 + 500000*v))/250 = 7.225268630201346
(la otra solución para D es negativa)
Si queremos comprar 10 fichas cuando ya se vendieron 150, tenemos que pagar (K=150, D=10)
V = ID + (F-I)*(2KD + D^2)/(2M)
V = 1000 + 125*(20*150 + 100)/1000
V = 1387.5
Para calcular la recaudacion total establecemos K=0, D=500
V = 100*500 + 125*(500^2)/(2*500)
V = 81250.0
Podemos verificar que esta es el área de la parcela.
Código de solidez basado en la solución de @Ismael, asume aumento lineal en el precio.
// 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;
}
}
Marte Robertson
rollback
la función para deshacer la edición: la URL completa a github es mucho más informativa que un enlace formateado .