gas optimization
G01: COMPARISONS WITH ZERO FOR UNSIGNED INTEGERS
problem
0 is less gas efficient than !0 if you enable the optimizer at 10k AND you’re in a require statement. Detailed explanation with the opcodes https://twitter.com/gzeon/status/1485428085885640706
prof
policies/Governance.sol, 247, b' if (userVotesForProposal[activeProposal.proposalId][msg.sender] > 0) {\r'
G02: PREFIX INCREMENT SAVE MORE GAS
problem
prefix increment ++i is more cheaper than postfix i++
prof
policies/Operator.sol, 488, b' decimals++;\r'
policies/Operator.sol, 675, b' _status.low.count--;\r'
policies/Operator.sol, 670, b' _status.low.count++;\r'
policies/Operator.sol, 691, b' _status.high.count--;\r'
policies/Operator.sol, 686, b' _status.high.count++;\r'
G03: X += Y COSTS MORE GAS THAN X = X + Y FOR STATE VARIABLES
prof
policies/BondCallback.sol, 143, b' amountsPerMarket[id][0] += inputAmount_;\r'
policies/BondCallback.sol, 144, b' amountsPerMarket[id][1] += outputAmount_;\r'
policies/Governance.sol, 194, b' totalEndorsementsForProposal[proposalId_] -= previousEndorsement;\r'
policies/Governance.sol, 198, b' totalEndorsementsForProposal[proposalId_] += userVotes;\r'
policies/Governance.sol, 254, b' noVotesForProposal[activeProposal.proposalId] += userVotes;\r'
policies/Governance.sol, 252, b' yesVotesForProposal[activeProposal.proposalId] += userVotes;\r'
policies/Heart.sol, 103, b' lastBeat += frequency();\r'
modules/PRICE.sol, 138, b' movingAverage -= (earliestPrice - currentPrice) / numObs;'
modules/PRICE.sol, 136, b' movingAverage += (currentPrice - earliestPrice) / numObs;'
modules/TRSRY.sol, 96, b' reserveDebt[token][msg.sender] += amount;\r'
modules/TRSRY.sol, 97, b' totalDebt[token_] += amount_;\r'
modules/TRSRY.sol, 115, b' reserveDebt[token_][msg.sender] -= received;\r'
modules/TRSRY.sol, 116, b' totalDebt[token_] -= received;\r'
modules/TRSRY.sol, 132, b' else totalDebt[token_] -= oldDebt - amount_;\r'
modules/TRSRY.sol, 131, b' if (oldDebt < amount_) totalDebt[token_] += amount_ - oldDebt;\r'
G04: USING BOOLS FOR STORAGE INCURS OVERHEAD
problem
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
prof
policies/Governance.sol, 105, b' mapping(uint256 => bool) public proposalHasBeenActivated;\r'
policies/Governance.sol, 117, b' mapping(uint256 => mapping(address => bool)) public tokenClaimsForProposal;\r'
Kernel.sol, 181, b' mapping(Keycode => mapping(Policy => mapping(bytes4 => bool))) public modulePermissions;\r'
Kernel.sol, 194, b' mapping(address => mapping(Role => bool)) public hasRole;\r'
Kernel.sol, 197, b' mapping(Role => bool) public isRole;\r'
G05: resign the default value to the variables.
problem
resign the default value to the variables will cost more gas.
prof
Kernel.sol, 397, b' for (uint256 i = 0; i < reqLength; ) {\r'
G06: ++I/I++ SHOULD BE UNCHECKED{++I}/UNCHECKED{I++} WHEN IT IS NOT POSSIBLE FOR THEM TO OVERFLOW, AS IS THE CASE WHEN USED IN FOR- AND WHILE-LOOPS
problem
The unchecked keyword is new in solidity version 0.8.0, so this only applies to that version or higher, which these instances are. This saves 30-40 gas per loop
prof
modules/INSTR.sol, 44, b' uint256 instructionsId = ++totalInstructions;\r'
policies/Operator.sol, 488, b' decimals++;\r'
policies/Operator.sol, 675, b' _status.low.count--;\r'
policies/Operator.sol, 670, b' _status.low.count++;\r'
policies/Operator.sol, 691, b' _status.high.count--;\r'
policies/Operator.sol, 686, b' _status.high.count++;\r'
G07: FUNCTIONS GUARANTEED TO REVERT WHEN CALLED BY NORMAL USERS CAN BE MARKED PAYABLE
problem
If a function modifier such as onlyOwner is used, the function will revert if a normal user tries to pay the function. Marking the function as payable will lower the gas cost for legitimate callers because the compiler will not include checks for whether a payment was provided. The extra opcodes avoided are CALLVALUE(2),DUP1(3),ISZERO(3),PUSH2(3),JUMPI(10),PUSH1(3),DUP1(3),REVERT(0),JUMPDEST(1),POP(2), which costs an average of about 21 gas per call to the function, in addition to the extra deployment cost
prof
policies/Heart.sol, 132, b' function resetBeat() external onlyRole("heart_admin") '
policies/Heart.sol, 132, b' function resetBeat() external onlyRole("heart_admin") '
policies/Heart.sol, 137, b' function toggleBeat() external onlyRole("heart_admin") '
policies/Heart.sol, 137, b' function toggleBeat() external onlyRole("heart_admin") '
policies/Heart.sol, 147, b' function setRewardTokenAndAmount(ERC20 token_, uint256 reward_)\r\n external\r\n onlyRole("heart_admin")\r\n '
policies/Heart.sol, 152, b' function withdrawUnspentRewards(ERC20 token_) external onlyRole("heart_admin") '
policies/Heart.sol, 152, b' function withdrawUnspentRewards(ERC20 token_) external onlyRole("heart_admin") '
Kernel.sol, 260, b' function executeAction(Actions action_, address target_) external onlyExecutor '
Kernel.sol, 448, b' function grantRole(Role role_, address addr_) public onlyAdmin '
Kernel.sol, 448, b' function grantRole(Role role_, address addr_) public onlyAdmin '
Kernel.sol, 458, b' function revokeRole(Role role_, address addr_) public onlyAdmin '
Kernel.sol, 458, b' function revokeRole(Role role_, address addr_) public onlyAdmin '
policies/Operator.sol, 595, b' function setBondContracts(IBondAuctioneer auctioneer_, IBondCallback callback_)\r\n external\r\n onlyRole("operator_admin")\r\n '
policies/Operator.sol, 615, b' function initialize() external onlyRole("operator_admin") '
policies/Operator.sol, 615, b' function initialize() external onlyRole("operator_admin") '
policies/Operator.sol, 621, b' function regenerate(bool high_) external onlyRole("operator_admin") '
policies/Operator.sol, 621, b' function regenerate(bool high_) external onlyRole("operator_admin") '
policies/Operator.sol, 627, b' function toggleActive() external onlyRole("operator_admin") '
policies/Operator.sol, 627, b' function toggleActive() external onlyRole("operator_admin") '
policies/PriceConfig.sol, 50, b' function initialize(uint256[] memory startObservations_, uint48 lastObservationTime_)\r\n external\r\n onlyRole("price_admin")\r\n '
policies/PriceConfig.sol, 63, b' function changeMovingAverageDuration(uint48 movingAverageDuration_)\r\n external\r\n onlyRole("price_admin")\r\n '
policies/PriceConfig.sol, 74, b' function changeObservationFrequency(uint48 observationFrequency_)\r\n external\r\n onlyRole("price_admin")\r\n '
policies/VoterRegistration.sol, 48, b' function issueVotesTo(address wallet_, uint256 amount_) external onlyRole("voter_admin") '
policies/VoterRegistration.sol, 48, b' function issueVotesTo(address wallet_, uint256 amount_) external onlyRole("voter_admin") '
policies/VoterRegistration.sol, 56, b' function revokeVotesFrom(address wallet_, uint256 amount_) external onlyRole("voter_admin") '
policies/VoterRegistration.sol, 56, b' function revokeVotesFrom(address wallet_, uint256 amount_) external onlyRole("voter_admin") '
G08: USING PRIVATE RATHER THAN PUBLIC FOR CONSTANTS, SAVES GAS
problem:
We can save getter function of public constants.
prof:
policies/Governance.sol, 121, b' uint256 public constant SUBMISSION_REQUIREMENT = 100;\r'
policies/Governance.sol, 124, b' uint256 public constant ACTIVATION_DEADLINE = 2 weeks;\r'
policies/Governance.sol, 127, b' uint256 public constant GRACE_PERIOD = 1 weeks;\r'
policies/Governance.sol, 130, b' uint256 public constant ENDORSEMENT_THRESHOLD = 20;\r'
policies/Governance.sol, 133, b' uint256 public constant EXECUTION_THRESHOLD = 33;\r'
policies/Governance.sol, 137, b' uint256 public constant EXECUTION_TIMELOCK = 3 days;\r'
modules/MINTR.sol, 9, b' OHM public immutable ohm;\r'
policies/Operator.sol, 82, b' ERC20 public immutable ohm;\r'
policies/Operator.sol, 83, b' uint8 public immutable ohmDecimals;\r'
policies/Operator.sol, 85, b' ERC20 public immutable reserve;\r'
policies/Operator.sol, 86, b' uint8 public immutable reserveDecimals;\r'
policies/Operator.sol, 89, b' uint32 public constant FACTOR_SCALE = 1e4;\r'
modules/PRICE.sol, 59, b' uint8 public constant decimals = 18;'
modules/RANGE.sol, 65, b' uint256 public constant FACTOR_SCALE = 1e4;\r'
modules/RANGE.sol, 68, b' ERC20 public immutable ohm;\r'
modules/RANGE.sol, 71, b' ERC20 public immutable reserve;\r'
G09: USAGE OF UINTS/INTS SMALLER THAN 32 BYTES (256 BITS) INCURS OVERHEAD
problem
When using elements that are smaller than 32 bytes, your contract’s gas usage may be higher. This is because the EVM operates on 32 bytes at a time. Therefore, if the element is smaller than that, the EVM must use more operations in order to reduce the size of the element from 32 bytes to the desired size.
prof
policies/Governance.sol, 164, b' if (VOTES.balanceOf(msg.sender) * 10000 < VOTES.totalSupply() * SUBMISSION_REQUIREMENT)\r'
policies/Governance.sol, 183, b' if (proposalId_ == 0) {\r'
policies/Governance.sol, 188, b' if (instructions.length == 0) {\r'
policies/Governance.sol, 243, b' if (activeProposal.proposalId == 0) {\r'
policies/Governance.sol, 247, b' if (userVotesForProposal[activeProposal.proposalId][msg.sender] > 0) {\r'
policies/Governance.sol, 268, b' if (netVotes * 100 < VOTES.totalSupply() * EXECUTION_THRESHOLD) {\r'
policies/Governance.sol, 298, b' if (userVotes == 0) {\r'
policies/Heart.sol, 122, b' return uint256(PRICE.observationFrequency());\r'
policies/Heart.sol, 122, b' return uint256(PRICE.observationFrequency());\r'
modules/INSTR.sol, 29, b' return (1, 0);\r'
modules/INSTR.sol, 48, b' if (length == 0) revert INSTR_InstructionsCannotBeEmpty();\r'
modules/INSTR.sol, 61, b' } else if (instruction.action == Actions.ChangeExecutor && i != length - 1) {\r'
modules/INSTR.sol, 70, b' instructions.push(instructions_[i]);\r'
modules/INSTR.sol, 70, b' instructions.push(instructions_[i]);\r'
Kernel.sol, 133, b' if (moduleForKeycode == address(0)) revert Policy_ModuleDoesNotExist(keycode_);\r'
Kernel.sol, 269, b' if (address(getModuleForKeycode[keycode]) != address(0))\r'
Kernel.sol, 274, b' allKeycodes.push(keycode);\r'
Kernel.sol, 283, b' if (address(oldModule) == address(0) || oldModule == newModule_)\r'
Kernel.sol, 299, b' activePolicies.push(policy_);\r'
Kernel.sol, 309, b' moduleDependents[keycode].push(policy_);\r'
Kernel.sol, 337, b' activePolicies.pop();\r'
Kernel.sol, 397, b' for (uint256 i = 0; i < reqLength; ) {\r'
Kernel.sol, 422, b' dependents.pop();\r'
Kernel.sol, 422, b' dependents.pop();\r'
modules/MINTR.sol, 26, b' return (1, 0);\r'
policies/Operator.sol, 72, b' OlympusMinter internal MINTR;\r'
policies/Operator.sol, 83, b' uint8 public immutable ohmDecimals;\r'
policies/Operator.sol, 86, b' uint8 public immutable reserveDecimals;\r'
policies/Operator.sol, 89, b' uint32 public constant FACTOR_SCALE = 1e4;\r'
policies/Operator.sol, 164, b' MINTR = OlympusMinter(getModuleAddress(dependencies[3]));\r'
policies/Operator.sol, 167, b' ohm.safeApprove(address(MINTR), type(uint256).max);\r'
policies/Operator.sol, 174, b' Keycode MINTR_KEYCODE = MINTR.KEYCODE();\r'
policies/Operator.sol, 202, b' updateCapacity(true, 0);\r'
policies/Operator.sol, 203, b' updateCapacity(false, 0);\r'
policies/Operator.sol, 210, b' uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config.regenWait) &&\r'
policies/Operator.sol, 210, b' uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config.regenWait) &&\r'
policies/Operator.sol, 210, b' uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 210, b' uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 210, b' uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 211, b' status.high.count >= config.regenThreshold\r'
policies/Operator.sol, 211, b' status.high.count >= config.regenThreshold\r'
policies/Operator.sol, 216, b' uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 216, b' uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 216, b' uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 216, b' uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 216, b' uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&\r'
policies/Operator.sol, 217, b' status.low.count >= config.regenThreshold\r'
policies/Operator.sol, 217, b' status.low.count >= config.regenThreshold\r'
policies/Operator.sol, 333, b' MINTR.mintOhm(msg.sender, amountOut);\r'
policies/Operator.sol, 302, b' MINTR.burnOhm(address(this), amountIn_);\r'
policies/Operator.sol, 418, b' uint8 oracleDecimals = PRICE.decimals();\r'
policies/Operator.sol, 418, b' uint8 oracleDecimals = PRICE.decimals();\r'
policies/Operator.sol, 418, b' uint8 oracleDecimals = PRICE.decimals();\r'
policies/Operator.sol, 419, b' uint256 invCushionPrice = 10**(oracleDecimals * 2) / range.cushion.low.price;\r'
policies/Operator.sol, 419, b' uint256 invCushionPrice = 10**(oracleDecimals * 2) / range.cushion.low.price;\r'
policies/Operator.sol, 420, b' uint256 invWallPrice = 10**(oracleDecimals * 2) / range.wall.low.price;\r'
policies/Operator.sol, 420, b' uint256 invWallPrice = 10**(oracleDecimals * 2) / range.wall.low.price;\r'
policies/Operator.sol, 426, b' int8 priceDecimals = getPriceDecimals(invCushionPrice);\r'
policies/Operator.sol, 426, b' int8 priceDecimals = getPriceDecimals(invCushionPrice);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 427, b' int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 430, b' uint256 oracleScale = 10uint8(int8(oracleDecimals) - priceDecimals);\r'
policies/Operator.sol, 431, b' uint256 bondScale = 10 **\r'
policies/Operator.sol, 434, b' uint8(\r\n 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r\n );\r'
policies/Operator.sol, 432, b' uint8(\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 433, b' 36 + scaleAdjustment + int8(ohmDecimals) - int8(reserveDecimals) - priceDecimals\r'
policies/Operator.sol, 443, b' uint256 marketCapacity = range.low.capacity.mulDiv(config.cushionFactor, FACTOR_SCALE);\r'
policies/Operator.sol, 443, b' uint256 marketCapacity = range.low.capacity.mulDiv(config.cushionFactor, FACTOR_SCALE);\r'
policies/Operator.sol, 446, b' IBondAuctioneer.MarketParams memory params = IBondAuctioneer.MarketParams({\r'
policies/Operator.sol, 454, b' debtBuffer: config_.cushionDebtBuffer,\r'
policies/Operator.sol, 455, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 455, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 455, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 456, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 456, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 456, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 457, b' depositInterval: config_.cushionDepositInterval,\r'
policies/Operator.sol, 458, b' scaleAdjustment: scaleAdjustment\r'
policies/Operator.sol, 371, b' int8 priceDecimals = getPriceDecimals(range.cushion.high.price);\r'
policies/Operator.sol, 371, b' int8 priceDecimals = getPriceDecimals(range.cushion.high.price);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 372, b' int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 375, b' uint256 oracleScale = 10**uint8(int8(PRICE.decimals()) - priceDecimals);\r'
policies/Operator.sol, 376, b' uint256 bondScale = 10 **\r'
policies/Operator.sol, 379, b' uint8(\r\n 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r\n );\r'
policies/Operator.sol, 377, b' uint8(\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 378, b' 36 + scaleAdjustment + int8(reserveDecimals) - int8(ohmDecimals) - priceDecimals\r'
policies/Operator.sol, 389, b' config.cushionFactor,\r'
policies/Operator.sol, 390, b' FACTOR_SCALE\r'
policies/Operator.sol, 394, b' IBondAuctioneer.MarketParams memory params = IBondAuctioneer.MarketParams({\r'
policies/Operator.sol, 402, b' debtBuffer: config.cushionDebtBuffer,\r'
policies/Operator.sol, 403, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 403, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 403, b' vesting: uint48(0), // Instant swaps\r'
policies/Operator.sol, 404, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 404, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 404, b' conclusion: uint48(block.timestamp + config_.cushionDuration),\r'
policies/Operator.sol, 405, b' depositInterval: config_.cushionDepositInterval,\r'
policies/Operator.sol, 406, b' scaleAdjustment: scaleAdjustment\r'
policies/Operator.sol, 477, b' RANGE.updateMarket(high_, type(uint256).max, 0);\r'
policies/Operator.sol, 485, b' int8 decimals;\r'
policies/Operator.sol, 486, b' while (price_ >= 10) {\r'
policies/Operator.sol, 488, b' decimals++;\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 493, b' return decimals - int8(PRICE.decimals());\r'
policies/Operator.sol, 518, b' if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 518, b' if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 518, b' if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 518, b' if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 521, b' config.cushionFactor = cushionFactor;\r'
policies/Operator.sol, 533, b' if (duration_ > uint256(7 days) || duration_ < uint256(1 days))\r'
policies/Operator.sol, 533, b' if (duration_ > uint256(7 days) || duration_ < uint256(1 days))\r'
policies/Operator.sol, 533, b' if (duration_ > uint256(7 days) || duration_ < uint256(1 days))\r'
policies/Operator.sol, 533, b' if (duration_ > uint256(7 days) || duration_ < uint256(1 days))\r'
policies/Operator.sol, 535, b' if (debtBuffer_ < uint32(10_000)) revert Operator_InvalidParams();\r'
policies/Operator.sol, 535, b' if (debtBuffer_ < uint32(10_000)) revert Operator_InvalidParams();\r'
policies/Operator.sol, 535, b' if (debtBuffer_ < uint32(10_000)) revert Operator_InvalidParams();\r'
policies/Operator.sol, 535, b' if (debtBuffer_ < uint32(10_000)) revert Operator_InvalidParams();\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 536, b' if (depositInterval_ < uint32(1 hours) || depositInterval_ > duration_)\r'
policies/Operator.sol, 540, b' config.cushionDuration = duration;\r'
policies/Operator.sol, 541, b' config.cushionDebtBuffer = debtBuffer;\r'
policies/Operator.sol, 542, b' config.cushionDepositInterval = depositInterval;\r'
policies/Operator.sol, 550, b' if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 550, b' if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 550, b' if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 550, b' if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();\r'
policies/Operator.sol, 553, b' config.reserveFactor = reserveFactor;\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 565, b' if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)\r'
policies/Operator.sol, 569, b' config.regenWait = wait;\r'
policies/Operator.sol, 570, b' config.regenThreshold = threshold;\r'
policies/Operator.sol, 571, b' config.regenObserve = observe;\r'
policies/Operator.sol, 574, b' status.high.count = 0;\r'
policies/Operator.sol, 575, b' status.high.nextObservation = 0;\r'
policies/Operator.sol, 578, b' status.low.count = 0;\r'
policies/Operator.sol, 579, b' status.low.nextObservation = 0;\r'
policies/Operator.sol, 590, b' if (address(auctioneer) == address(0) || address(callback) == address(0))\r'
policies/Operator.sol, 590, b' if (address(auctioneer) == address(0) || address(callback) == address(0))\r'
policies/Operator.sol, 665, b' uint32 observe = config.regenObserve;\r'
policies/Operator.sol, 665, b' uint32 observe = config.regenObserve;\r'
policies/Operator.sol, 675, b' status.low.count--;\r'
policies/Operator.sol, 670, b' status.low.count++;\r'
policies/Operator.sol, 678, b' status.low.nextObservation = (regen.nextObservation + 1) % observe;\r'
policies/Operator.sol, 691, b' status.high.count--;\r'
policies/Operator.sol, 686, b' status.high.count++;\r'
policies/Operator.sol, 694, b' status.high.nextObservation = (regen.nextObservation + 1) % observe;\r'
policies/Operator.sol, 717, b' status.low.count = uint32(0);\r'
policies/Operator.sol, 719, b' status.low.nextObservation = uint32(0);\r'
policies/Operator.sol, 720, b' status.low.lastRegen = uint48(block.timestamp);\r'
policies/Operator.sol, 705, b' status.high.count = uint32(0);\r'
policies/Operator.sol, 707, b' status.high.nextObservation = uint32(0);\r'
policies/Operator.sol, 708, b' status.high.lastRegen = uint48(block.timestamp);\r'
policies/Operator.sol, 764, b' 10ohmDecimals * 10PRICE.decimals(),\r'
policies/Operator.sol, 764, b' 10ohmDecimals * 10PRICE.decimals(),\r'
policies/Operator.sol, 764, b' 10ohmDecimals * 10PRICE.decimals(),\r'
policies/Operator.sol, 764, b' 10ohmDecimals * 10PRICE.decimals(),\r'
policies/Operator.sol, 764, b' 10ohmDecimals * 10PRICE.decimals(),\r'
policies/Operator.sol, 765, b' 10reserveDecimals * RANGE.price(true, true)\r'
policies/Operator.sol, 765, b' 10reserveDecimals * RANGE.price(true, true)\r'
policies/Operator.sol, 753, b' 10reserveDecimals * RANGE.price(true, false),\r'
policies/Operator.sol, 753, b' 10reserveDecimals * RANGE.price(true, false),\r'
policies/Operator.sol, 754, b' 10ohmDecimals * 10PRICE.decimals()\r'
policies/Operator.sol, 754, b' 10ohmDecimals * 10PRICE.decimals()\r'
policies/Operator.sol, 754, b' 10ohmDecimals * 10PRICE.decimals()\r'
policies/Operator.sol, 754, b' 10ohmDecimals * 10PRICE.decimals()\r'
policies/Operator.sol, 754, b' 10ohmDecimals * 10PRICE.decimals()\r'
policies/Operator.sol, 780, b' uint256 capacity = (reservesInTreasury * config.reserveFactor) / FACTOR_SCALE;\r'
modules/PRICE.sol, 44, b' uint32 public nextObsIndex;'
modules/PRICE.sol, 47, b' uint32 public numObservations;'
modules/PRICE.sol, 50, b' uint48 public observationFrequency;'
modules/PRICE.sol, 53, b' uint48 public movingAverageDuration;'
modules/PRICE.sol, 56, b' uint48 public lastObservationTime;'
modules/PRICE.sol, 59, b' uint8 public constant decimals = 18;'
modules/PRICE.sol, 114, b' return (1, 0);'
modules/PRICE.sol, 127, b' uint32 numObs = numObservations;'
modules/PRICE.sol, 127, b' uint32 numObs = numObservations;'
modules/PRICE.sol, 143, b' lastObservationTime = uint48(block.timestamp);'
modules/PRICE.sol, 144, b' nextObsIndex = (nextObsIndex + 1) % numObs;'
modules/PRICE.sol, 165, b' if (updatedAt < block.timestamp - 3 * uint256(observationFrequency))'
modules/PRICE.sol, 165, b' if (updatedAt < block.timestamp - 3 * uint256(observationFrequency))'
modules/PRICE.sol, 171, b' if (updatedAt < block.timestamp - uint256(observationFrequency))'
modules/PRICE.sol, 185, b' uint32 lastIndex = nextObsIndex == 0 ? numObservations - 1 : nextObsIndex - 1;'
modules/PRICE.sol, 185, b' uint32 lastIndex = nextObsIndex == 0 ? numObservations - 1 : nextObsIndex - 1;'
modules/PRICE.sol, 185, b' uint32 lastIndex = nextObsIndex == 0 ? numObservations - 1 : nextObsIndex - 1;'
modules/PRICE.sol, 185, b' uint32 lastIndex = nextObsIndex == 0 ? numObservations - 1 : nextObsIndex - 1;'
modules/PRICE.sol, 215, b' if (startObservations.length != numObs || lastObservationTime > uint48(block.timestamp))'
modules/PRICE.sol, 215, b' if (startObservations.length != numObs || lastObservationTime > uint48(block.timestamp))'
modules/PRICE.sol, 215, b' if (startObservations.length != numObs || lastObservationTime > uint48(block.timestamp))'
modules/PRICE.sol, 221, b' if (startObservations[i] == 0) revert Price_InvalidParams();'
modules/PRICE.sol, 231, b' lastObservationTime = lastObservationTime;'
modules/PRICE.sol, 242, b' if (movingAverageDuration == 0 || movingAverageDuration % observationFrequency != 0)'
modules/PRICE.sol, 242, b' if (movingAverageDuration == 0 || movingAverageDuration % observationFrequency != 0)'
modules/PRICE.sol, 242, b' if (movingAverageDuration == 0 || movingAverageDuration % observationFrequency != 0)'
modules/PRICE.sol, 242, b' if (movingAverageDuration == 0 || movingAverageDuration_ % observationFrequency != 0)'
modules/PRICE.sol, 242, b' if (movingAverageDuration_ == 0 || movingAverageDuration_ % observationFrequency != 0)'
modules/PRICE.sol, 242, b' if (movingAverageDuration_ == 0 || movingAverageDuration_ % observationFrequency != 0)'
modules/PRICE.sol, 246, b' uint256 newObservations = uint256(movingAverageDuration_ / observationFrequency);'
modules/PRICE.sol, 246, b' uint256 newObservations = uint256(movingAverageDuration_ / observationFrequency);'
modules/PRICE.sol, 246, b' uint256 newObservations = uint256(movingAverageDuration_ / observationFrequency);'
modules/PRICE.sol, 253, b' lastObservationTime = 0;'
modules/PRICE.sol, 255, b' nextObsIndex = 0;'
modules/PRICE.sol, 256, b' movingAverageDuration = movingAverageDuration_;'
modules/PRICE.sol, 257, b' numObservations = uint32(newObservations);'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 268, b' if (observationFrequency_ == 0 || movingAverageDuration % observationFrequency_ != 0)'
modules/PRICE.sol, 272, b' uint256 newObservations = uint256(movingAverageDuration / observationFrequency_);'
modules/PRICE.sol, 272, b' uint256 newObservations = uint256(movingAverageDuration / observationFrequency_);'
modules/PRICE.sol, 272, b' uint256 newObservations = uint256(movingAverageDuration / observationFrequency_);'
modules/PRICE.sol, 285, b' lastObservationTime = 0;'
modules/PRICE.sol, 287, b' nextObsIndex = 0;'
modules/PRICE.sol, 288, b' observationFrequency = observationFrequency_;'
modules/PRICE.sol, 289, b' numObservations = uint32(newObservations);'
policies/PriceConfig.sol, 49, b' PRICE.initialize(startObservations_, lastObservationTime_);\r'
policies/PriceConfig.sol, 62, b' PRICE.changeMovingAverageDuration(movingAverageDuration_);\r'
policies/PriceConfig.sol, 62, b' PRICE.changeMovingAverageDuration(movingAverageDuration_);\r'
policies/PriceConfig.sol, 73, b' PRICE.changeObservationFrequency(observationFrequency_);\r'
policies/PriceConfig.sol, 73, b' PRICE.changeObservationFrequency(observationFrequency_);\r'
modules/RANGE.sol, 116, b' return (1, 0);\r'
modules/RANGE.sol, 148, b' range.low.lastActive = uint48(block.timestamp);\r'
modules/RANGE.sol, 136, b' range.high.lastActive = uint48(block.timestamp);\r'
modules/RANGE.sol, 221, b' if (market == type(uint256).max && marketCapacity != 0) revert RANGE_InvalidParams();\r'
modules/RANGE.sol, 245, b' wallSpread_ > 10000 ||\r'
modules/RANGE.sol, 246, b' wallSpread_ < 100 ||\r'
modules/RANGE.sol, 247, b' cushionSpread_ > 10000 ||\r'
modules/RANGE.sol, 248, b' cushionSpread_ < 100 ||\r'
modules/RANGE.sol, 264, b' if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();\r'
modules/RANGE.sol, 264, b' if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();\r'
modules/RANGE.sol, 344, b' return range.low.lastActive;\r'
modules/RANGE.sol, 342, b' return range.high.lastActive;\r'
policies/TreasuryCustodian.sol, 60, b' TRSRY.setApprovalFor(policy, tokens[j], 0);\r'
modules/TRSRY.sol, 52, b' return (1, 0);\r'
modules/TRSRY.sol, 106, b' if (reserveDebt[token_][msg.sender] == 0) revert TRSRY_NoDebtOutstanding();\r'
modules/VOTES.sol, 28, b' return (1, 0);\r'
G10:USE A MORE RECENT VERSION OF SOLIDITY
Use a solidity version of at least 0.8.2 to get simple compiler automatic inlining Use a solidity version of at least 0.8.3 to get better struct packing and cheaper multiple storage reads Use a solidity version of at least 0.8.4 to get custom errors, which are cheaper at deployment than revert()/require() strings Use a solidity version of at least 0.8.10 to have external calls skip contract existence checks if the external call has a return value