# 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. – Mars Robertson Jul 26 '17 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)D`2`+ 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;
}
}
``````