Я посмотрел на некоторые существующие контракты на краудсейл:
Ниже приведен график ASCII из исходного кода Aragon. Вместо этапов я хотел бы найти контракт, который реализует линейное или логарифмическое уменьшение количества токенов...
Предположим, у нас есть 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
эфиры, мы должны решить уравнение 2-й степени (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 отрицательно)
Если мы хотим купить 10 токенов, когда уже продано 150, мы должны заплатить (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
V = 100*500 + 125*(500^2)/(2*500)
V = 81250.0
Мы можем убедиться, что это площадь участка.
Код Solidity, основанный на решении @Ismael, предполагает линейный рост цены.
// 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;
}
}
Марс Робертсон
rollback
функцию отмены редактирования - полный URL-адрес на github намного информативнее, чем какая -то отформатированная ссылка.