Omniscia fetchai Audit

InterestCalculator Manual Review Findings

InterestCalculator Manual Review Findings

ICO-01M: Inexistent Usage of Safe Arithmetics

Description:

The hockeyStickTransform function does not apply safe arithmetics and is as such fully prone to overflows that can occur for its internim calculations.

Example:

contracts/ALP/InterestCalculator.sol
201function hockeyStickTransform(
202 uint256 ur,
203 uint256 minAPR,
204 uint256 maxAPR,
205 uint256 marketAPR,
206 uint256 targetUR
207) public pure returns (uint256) {
208 if (ur < targetUR) {
209 return minAPR + (ur * (marketAPR - minAPR)) / targetUR;
210 } else {
211 return marketAPR + ((ur - targetUR) * (maxAPR - marketAPR)) / (ONE_UNIT - targetUR);
212 }
213}

Recommendation:

We advise the SafeMath library to be utilized here to ensure no such overflows / underflows can occur.

Alleviation:

Safe arithmetics are now properly applied to the statements within the hockeyStickTransform function.

ICO-02M: Over Complicated Exponent Approximation

Description:

The statements within exp contain redundant parenthesis, contain loss of precision due to ordering divisions prior to multiplications and ultimately are redundant as well given that the inc value is carried over via multiplication to the next member calculation which is not necessary.

Example:

contracts/ALP/InterestCalculator.sol
33function exp(uint256 x) public pure returns (uint256) {
34 uint256 numerator = A0;
35 uint256 denominator = A0;
36 uint256 inc = (x.mul(A1)).div(A0);
37 numerator = numerator.add(inc);
38 denominator = denominator.sub(inc);
39 inc = (((inc.mul(x)).div(A0)).mul(A2)).div(A1);
40 numerator = numerator.add(inc);
41 denominator = denominator.add(inc);
42 inc = (((inc.mul(x)).div(A0)).mul(A3)).div(A2);
43 numerator = numerator.add(inc);
44 denominator = denominator.sub(inc);
45 inc = (((inc.mul(x)).div(A0)).mul(A4)).div(A3);
46 numerator = numerator.add(inc);
47 denominator = denominator.add(inc);
48 inc = (((inc.mul(x)).div(A0)).mul(A5)).div(A4);
49 numerator = numerator.add(inc);
50 denominator = denominator.sub(inc);
51 // Return a ray with 27 decimal point precision
52 // Similar approach to MakerDAO rates module
53 // https://docs.makerdao.com/smart-contract-modules/rates-module
54 return (A0.mul(numerator)).div(denominator);
55}

Recommendation:

We advise this segment to instead recalculate inc each time and with the maximum precision as possible since currently, the terms do not appear to be efficiently calculated. As an example, the second inc calculation performs (inc * x * A2) / (A0 * A1) and is meant to represent (1/9)x^2 but instead conducts redundant normalizations as the equation can be simplified to (x * A0 * x * A0 * 2) / (2 * A0 * 9 * A0). Instead, the calculation could simply perform x.mul(x).mul(A2).div(A0) and calculate the term in three actions instead of four.

Alleviation:

The function was refactored to a great degree, significantly increasing its readability, reducing its gas cost and increasing the range of values over which it can safely operate.