Omniscia rain protocol Audit
MathOps Code Style Findings
MathOps Code Style Findings
MOS-01C: Unoptimized Stack Index Adjustment
Type | Severity | Location |
---|---|---|
Gas Optimization | MathOps.sol:L39, L130 |
Description:
The stackIndex
is adjusted twice within the applyOp
function's execution redundantly as the first subtraction can be offset by a single unit.
Example:
contracts/vm/ops/MathOps.sol
29function applyOp(30 bytes memory,31 State memory state_,32 uint256 opcode_,33 uint256 operand_34) internal pure {35 require(opcode_ < OPS_LENGTH, "MAX_OPCODE");36 uint256 top_;37 unchecked {38 top_ = state_.stackIndex - 1;39 state_.stackIndex -= operand_;40 }41 uint256 baseIndex_ = state_.stackIndex;42 uint256 cursor_ = baseIndex_;43 uint256 accumulator_ = state_.stack[cursor_];44
45 // Addition.46 if (opcode_ == ADD) {47 while (cursor_ < top_) {48 unchecked {49 cursor_++;50 }51 accumulator_ += state_.stack[cursor_];52 }53 }54 // Subtraction.55 else if (opcode_ == SUB) {56 while (cursor_ < top_) {57 unchecked {58 cursor_++;59 }60 accumulator_ -= state_.stack[cursor_];61 }62 }63 // Multiplication.64 // Slither false positive here complaining about dividing before65 // multiplying but both are mututally exclusive according to `opcode_`.66 else if (opcode_ == MUL) {67 while (cursor_ < top_) {68 unchecked {69 cursor_++;70 }71 accumulator_ *= state_.stack[cursor_];72 }73 }74 // Division.75 else if (opcode_ == DIV) {76 while (cursor_ < top_) {77 unchecked {78 cursor_++;79 }80 accumulator_ /= state_.stack[cursor_];81 }82 }83 // Modulo.84 else if (opcode_ == MOD) {85 while (cursor_ < top_) {86 unchecked {87 cursor_++;88 }89 accumulator_ %= state_.stack[cursor_];90 }91 }92 // Exponentiation.93 else if (opcode_ == EXP) {94 while (cursor_ < top_) {95 unchecked {96 cursor_++;97 }98 accumulator_**state_.stack[cursor_];99 }100 }101 // Minimum.102 else if (opcode_ == MIN) {103 uint256 item_;104 while (cursor_ < top_) {105 unchecked {106 cursor_++;107 }108 item_ = state_.stack[cursor_];109 if (item_ < accumulator_) {110 accumulator_ = item_;111 }112 }113 }114 // Maximum.115 else if (opcode_ == MAX) {116 uint256 item_;117 while (cursor_ < top_) {118 unchecked {119 cursor_++;120 }121 item_ = state_.stack[cursor_];122 if (item_ > accumulator_) {123 accumulator_ = item_;124 }125 }126 }127
128 unchecked {129 state_.stack[baseIndex_] = accumulator_;130 state_.stackIndex++;131 }132}
Recommendation:
We advise this to be done so to optimize the gas cost of the function.
Alleviation:
The Rain Protocol team has stated that they plan to address this in an upcoming pull request. Given that this is a finding planned to be fixed, we consider this exhibit acknowledged.