Omniscia fetchai Audit
InterestCalculator Manual Review Findings
InterestCalculator Manual Review Findings
ICO-01M: Inexistent Usage of Safe Arithmetics
Type | Severity | Location |
---|---|---|
Mathematical Operations | Major | InterestCalculator.sol:L209, L211 |
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:
201function hockeyStickTransform(202 uint256 ur,203 uint256 minAPR,204 uint256 maxAPR,205 uint256 marketAPR,206 uint256 targetUR207) 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
Type | Severity | Location |
---|---|---|
Mathematical Operations | Minor | InterestCalculator.sol:L33-L55 |
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:
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 precision52 // Similar approach to MakerDAO rates module53 // https://docs.makerdao.com/smart-contract-modules/rates-module54 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.