# Where to find ICO contract with linear / logarithmic decrease?

I had a look at some existing crowdsale contracts:

Below is an ASCII graph from Aragon source code. Rather than stages, I'd like to find a contract that implements linear or logarithmic decrease in the amount of tokens...

• For the first time I've used rollback function to undo the edit - full URL to github is much more informative than some formatted link. Jul 26, 2017 at 14:59

Let's suppose we have M the maximum amount of tokens to sell, I the initial price of each token and F the final price of each token. Let's call f the function that gives the price of each token, we know that f(0) = I and f(M) = F. If you want a linear price then f(x) = I + (F - I) * x / M.

The problem is to determine how many token we will get when we pay V and there's already K tokens sold. Let's say we will get D tokens, we know our initial price will be f(K) and the final prize f(K + D), and the total price will be the are under the graph. Yeah math!

So we will have the equation

To determine the amount of tokens to sell for V ethers we have to solve the 2nd degree equation (F-I)D2+ 2(MI + (F-I)K)D - 2MV = 0. Yeah, more math!

For example in the plot I've I=100, F=225, M=500. Then when there are K=150 for 1000 ethers we will get:

D = (-2*(50000+125*k)+sqrt(4*(50000+125*k)**2 + 500000*v))/250 = 7.225268630201346

(the other solution for D is negative)

If we want to purchase 10 token when 150 were sold already we have to pay (K=150, D=10)

V = ID + (F-I)*(2KD + D^2)/(2M)
V = 1000 + 125*(20*150 + 100)/1000
V = 1387.5

To calculate the total recaudation we set K=0, D=500

V = 100*500 + 125*(500^2)/(2*500)
V = 81250.0

We can verify this is the area of the plot.

Solidity code based on the solution by @Ismael, assumes linear increase in price.

// 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;
}
}