all files / contracts/ Math.sol

100% Statements 18/18
100% Branches 6/6
100% Functions 4/4
100% Lines 20/20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                    950×                 18× 18× 100× 100× 100× 564× 374× 374×     100×   22× 22×       18×                 95×   95× 73×     22× 22× 22×         622×      
pragma solidity ^0.4.23;
 
 
/*
@type: Library
@name: Math
@purpose: To provide a library of math functions
*/
library Math {
 
    /*
      @purpose: To generate a weak random number between 0 and the specified maximum
      @param: uint seed = seed number for the generation of a random number
      @param: uint max = the max for the range of random numbers that can be made
      @returns: The random number
    */
    function getRandom(uint seed, uint max) public view returns(uint) {
        //Based on the function by alexvandesande
        return(uint(keccak256(abi.encodePacked(blockhash(block.number-1), seed)))%(max+1));
        //Hashes the seed number with the last blockhash to generate
        // a random number and shifts it into the desired range by using a modulus
    }
 
    // calculates possible clusters around all scores and returns the average score
    // and size of the biggest one.
    function getFinalScore(int[] data, uint consentRadius) public pure returns(int finalScore, uint largestClusterSize) {
        //get largest Cluster and its score
        int largestClusterScore;
        for (uint i = 0; i < data.length; i++) {
            uint clusterSize = 0;
            int clusterScore = 0;
            for (uint j = 0; j < data.length; j++) {
                if (abs(data[i] - data[j]) <= consentRadius) {
                    clusterScore += data[j];
                    clusterSize++;
                }
            }
            if (clusterSize > largestClusterSize ||
                (clusterSize == largestClusterSize && clusterScore < largestClusterScore)) {
                largestClusterSize = clusterSize;
                largestClusterScore = clusterScore;
 
            }
        }
        finalScore = largestClusterScore/int(largestClusterSize);
    }
 
    /*
      @purpose: To calculate the proportion of stake an assessors gets back and whether
      or not the remained should be distributed to the others or not (iff they are not in
      the biggest cluster)
    */
    function getPayout(uint distance, uint stake, uint consentRadius) public pure returns(uint payout, bool dissenting) {
        uint xOfRadius = (distance*10000) / consentRadius;
        // if in rewardCluster
        if (distance <= consentRadius) {
            payout = (stake * (10000 - xOfRadius)) / 10000 + stake;
        } else {
            // cap it to 20000 to prevent underflow
            uint xOf2RadiusCapped = xOfRadius > 20000 ? 20000 : xOfRadius;
            payout = (stake * (20000 - xOf2RadiusCapped)) / 20000;
            dissenting = true;
        }
    }
 
    function abs(int x) public pure returns(uint) {
        return uint(x < 0 ? -x : x);
    }
}