Platform: Code4rena
Start Date: 25/08/2022
Pot Size: $75,000 USDC
Total HM: 35
Participants: 147
Period: 7 days
Judge: 0xean
Total Solo HM: 15
Id: 156
League: ETH
Rank: 59/147
Findings: 2
Award: $95.72
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: zzzitron
Also found by: 0x040, 0x1f8b, 0x52, 0x85102, 0xDjango, 0xNazgul, 0xNineDec, 0xSky, 0xSmartContract, 0xkatana, 8olidity, Aymen0909, Bahurum, BipinSah, Bnke0x0, CRYP70, CertoraInc, Ch_301, Chandr, Chom, CodingNameKiki, Deivitto, DimSon, Diraco, ElKu, EthLedger, Funen, GalloDaSballo, Guardian, IllIllI, JansenC, Jeiwan, Lambda, LeoS, Margaret, MasterCookie, PPrieditis, PaludoX0, Picodes, PwnPatrol, RaymondFam, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, StevenL, The_GUILD, TomJ, Tomo, Trust, Waze, __141345__, ajtra, ak1, apostle0x01, aviggiano, bin2chen, bobirichman, brgltd, c3phas, cRat1st0s, carlitox477, cccz, ch13fd357r0y3r, cloudjunky, cryptphi, csanuragjain, d3e4, datapunk, delfin454000, devtooligan, dipp, djxploit, durianSausage, eierina, enckrish, erictee, fatherOfBlocks, gogo, grGred, hansfriese, hyh, ignacio, indijanc, itsmeSTYJ, ladboy233, lukris02, martin, medikko, mics, natzuu, ne0n, nxrblsrpr, okkothejawa, oyc_109, p_crypt0, pfapostol, prasantgupta52, rajatbeladiya, rbserver, reassor, ret2basic, robee, rokinot, rvierdiiev, shenwilly, sikorico, sorrynotsorry, tnevler, tonisives, w0Lfrum, yixxas
62.3811 DAI - $62.38
Severity: Low
Most contracts use an init pattern (instead of a constructor) to initialize contract parameters. Unless these are enforced to be atomic with contact deployment via deployment script or factory contracts, they are susceptible to front-running race conditions where an attacker/griefer can front-run (cannot access control because admin roles are not initialized) to initially with their own (malicious) parameters upon detecting (if an event is emitted) which the contract deployer has to redeploy wasting gas and risking other transactions from interacting with the attacker-initialized contract.
Many init functions do not have an explicit event emission which makes monitoring such scenarios harder. All of them have re-init checks; while many are explicit some (those in auction contracts) have implicit reinit checks in initAccessControls() which is better if converted to an explicit check in the main init function itself. (details credit to: code-423n4/2021-09-sushimiso-findings#64)
function initialize(uint256[] memory startObservations_, uint48 lastObservationTime_)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L205
function initialize() external onlyRole("operator_admin") {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L598
function initialize(uint256[] memory startObservations_, uint48 lastObservationTime_)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L45
Ensure atomic calls to init functions along with deployment via robust deployment scripts or factory contracts. Emit explicit events for initializations of contracts. Enfore prevention of re-initializations via explicit setting/checking of boolean initialized variables in the main init function instead of downstream function checks.
Severity: Low
According to openzepplin's ERC721, the use of _mint is discouraged, use _safeMint whenever possible. https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#ERC721-_mint-address-uint256-
_mint(wallet_, amount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L36
Use _safeMint whenever possible instead of _mint
Severity: Low
function _issueReward(address to_) internal {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L111
Consider adding zero-address checks in the mentioned codebase.
Severity: Low
Deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead
ohm.safeApprove(address(MINTR), type(uint256).max);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L57
ohm.safeApprove(address(MINTR), type(uint256).max);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L167
Consider using safeIncreaseAllowance() / safeDecreaseAllowance() instead.
Severity: Low
It is good to add a require() statement that checks the return value of token transfers or to use something like OpenZeppelin’s safeTransfer/safeTransferFrom unless one is sure the given token reverts in case of a failure. Failure to do so will cause silent failures of transfers and affect token accounting in contract.
Reference: This similar medium-severity (https://consensys.net/diligence/audits/2021/01/fei-protocol/#unchecked-return-value-for-iweth-transfer-call) finding from Consensys Diligence Audit of Fei Protocol.
VOTES.transferFrom(msg.sender, address(this), userVotes);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L259
VOTES.transferFrom(address(this), msg.sender, userVotes);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L312
Consider using safeTransfer/safeTransferFrom or require() consistently.
Severity: Non-Critical
If the variable needs to be different based on which class it comes from, a view/pure function should be used instead.
Keycode TRSRY_KEYCODE = TRSRY.KEYCODE();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L68
Keycode TRSRY_KEYCODE = TRSRY.KEYCODE();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/TreasuryCustodian.sol#L35
Severity: Non-Critical
wallSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L245
if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L264
(totalEndorsementsForProposal[proposalId_] * 100) <
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L217
while (price_ >= 10) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L486
if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L518
if (duration_ > uint256(7 days) || duration_ < uint256(1 days))
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L533
if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L550
if (wait_ < 1 hours || threshold_ > observe_ || observe_ == 0)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L565
Severity: Non-Critical
Each event should use three indexed fields if there are three or more fields. In addition, each event should have at least one indexed fields to allow easier filtering of logs.
event PermissionsUpdated( Keycode indexed keycode_, Policy indexed policy_, bytes4 funcSelector_, bool granted_ );
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L203
event NewObservation(uint256 timestamp_, uint256 price_, uint256 movingAverage_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L26
event WallUp(bool high_, uint256 timestamp_, uint256 capacity_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L20
event WallDown(bool high_, uint256 timestamp_, uint256 capacity_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L21
event CushionUp(bool high_, uint256 timestamp_, uint256 capacity_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L22
event CushionDown(bool high_, uint256 timestamp_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L23
event PricesChanged( uint256 wallLowPrice_, uint256 cushionLowPrice_, uint256 cushionHighPrice_, uint256 wallHighPrice_ );
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L24
event SpreadsChanged(uint256 cushionSpread_, uint256 wallSpread_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L30
event ApprovedForWithdrawal(address indexed policy_, ERC20 indexed token_, uint256 amount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L20
event DebtIncurred(ERC20 indexed token_, address indexed policy_, uint256 amount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L27
event DebtRepaid(ERC20 indexed token_, address indexed policy_, uint256 amount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L28
event DebtSet(ERC20 indexed token_, address indexed policy_, uint256 amount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L29
event ProposalEndorsed(uint256 proposalId, address voter, uint256 amount);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L87
event ProposalActivated(uint256 proposalId, uint256 timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L88
event WalletVoted(uint256 proposalId, address voter, bool for_, uint256 userVotes);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L89
event RewardIssued(address to_, uint256 rewardAmount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L29
event RewardUpdated(ERC20 token_, uint256 rewardAmount_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L30
event Swap( ERC20 indexed tokenIn_, ERC20 indexed tokenOut_, uint256 amountIn_, uint256 amountOut_ );
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L45
event CushionParamsChanged(uint32 duration_, uint32 debtBuffer_, uint32 depositInterval_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L52
event RegenParamsChanged(uint32 wait_, uint32 threshold_, uint32 observe_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L54
Severity: Non-Critical
When changing state variables events are not emitted. Emitting events allows monitoring activities with off-chain monitoring tools.
function changeKernel(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L76
function setActiveStatus(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L126
function setOperator(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L190
function setSpreads(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L498
function setThresholdFactor(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L510
function setBondContracts(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L586
function changeMovingAverageDuration(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L58
function changeObservationFrequency(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L69
OpenZeppelin recommends that the initializer modifier be applied to constructors. Per OZs Post implementation contract should be initialized to avoid potential griefs or exploits. https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680/5
Severity: Non-Critical
contract Kernel
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L149
contract OlympusInstructions is Module
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L10
contract OlympusMinter is Module
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L8
contract OlympusPrice is Module
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L22
contract OlympusRange is Module
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L16
contract OlympusTreasury is Module, ReentrancyGuard
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L17
contract OlympusVotes is Module, ERC20
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L11
contract BondCallback is Policy, ReentrancyGuard, IBondCallback
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L17
contract OlympusGovernance is Policy
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L51
contract OlympusHeart is IHeart, Policy, ReentrancyGuard
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L21
contract Operator is IOperator, Policy, ReentrancyGuard
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L30
contract OlympusPriceConfig is Policy
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L7
contract TreasuryCustodian is Policy
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/TreasuryCustodian.sol#L15
contract VoterRegistration is Policy
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/VoterRegistration.sol#L9
Severity: Non-Critical
Use a solidity version of at least 0.8.4 to get bytes.concat() instead of abi.encodePacked(<bytes>,<bytes>) Use a solidity version of at least 0.8.12 to get string.concat() instead of abi.encodePacked(<str>,<str>) Use a solidity version of at least 0.8.13 to get the ability to use using for with a list of free functions
Found old version 0.8.0 of Solidity
https://github.com/code-423n4/2022-08-olympus/tree/main/src/interfaces/IBondCallback.sol#L2
Found old version 0.8.0 of Solidity
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IHeart.sol#L2
Found old version 0.8.0 of Solidity
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L2
Found old version 0.8.0 of Solidity
Consider updating to a more recent solidity version.
Severity: Non-Critical
Contracts are allowed to override their parents’ functions and change the visibility from external to public.
function grantRole(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L439
function revokeRole(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L451
function mintOhm(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L33
function burnOhm(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L37
function updateMarket(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L215
function withdrawReserves(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L75
function transferFrom(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L51
Severity: Non-Critical
Use (e.g. 1e6) rather than decimal literals (e.g. 100000), for better code readability.
wallSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L245
cushionSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L247
if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L264
wallSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L245
cushionSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L247
if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L264
wallSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L245
cushionSpread_ > 10000 ||
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L247
if (thresholdFactor_ > 10000 || thresholdFactor_ < 100) revert RANGE_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L264
if (VOTES.balanceOf(msg.sender) * 10000 < VOTES.totalSupply() * SUBMISSION_REQUIREMENT)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L164
if (configParams[4] > 10000 || configParams[4] < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L111
if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L518
if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L550
if (configParams[4] > 10000 || configParams[4] < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L111
if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L518
if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L550
if (configParams[4] > 10000 || configParams[4] < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L111
if (cushionFactor_ > 10000 || cushionFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L518
if (reserveFactor_ > 10000 || reserveFactor_ < 100) revert Operator_InvalidParams();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L550
Severity: Non-Critical
Block timestamps have historically been used for a variety of applications, such as entropy for random numbers (see the Entropy Illusion for further details), locking funds for periods of time, and various state-changing conditional statements that are time-dependent. Miners have the ability to adjust timestamps slightly, which can prove to be dangerous if block timestamps are used incorrectly in smart contracts.
lastObservationTime = uint48(block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L143
if (updatedAt < block.timestamp - 3 * uint256(observationFrequency))
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L165
if (updatedAt < block.timestamp - uint256(observationFrequency))
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L171
if (startObservations_.length != numObs || lastObservationTime_ > uint48(block.timestamp))
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L215
lastActive: uint48(block.timestamp),
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L85
_range.high.lastActive = uint48(block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L136
_range.low.lastActive = uint48(block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L148
getProposalMetadata[proposalId] = ProposalMetadata( title_, msg.sender, block.timestamp, proposalURI_ );
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L168-L173
if (block.timestamp > proposal.submissionTimestamp + ACTIVATION_DEADLINE) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L212
if (block.timestamp < activeProposal.activationTimestamp + GRACE_PERIOD) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L227
activeProposal = ActivatedProposal(proposalId_, block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L231
if (block.timestamp < activeProposal.activationTimestamp + EXECUTION_TIMELOCK) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L272
lastBeat = block.timestamp;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L63
if (block.timestamp < lastBeat + frequency()) revert Heart_OutOfCycle();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L94
lastBeat = block.timestamp - frequency();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L131
lastRegen: uint48(block.timestamp),
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L128
uint48(block.timestamp) >= RANGE.lastActive(true) + uint48(config_.regenWait) &&
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L210
uint48(block.timestamp) >= RANGE.lastActive(false) + uint48(config_.regenWait) &&
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L216
conclusion: uint48(block.timestamp + config_.cushionDuration),
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L404
_status.high.lastRegen = uint48(block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L708
_status.low.lastRegen = uint48(block.timestamp);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L720
Block timestamps should not be used for entropy or generating random numbers—i.e., they should not be the deciding factor (either directly or through some derivation) for winning a game or changing an important state.
Time-sensitive logic is sometimes required; e.g., for unlocking contracts (time-locking), completing an ICO after a few weeks, or enforcing expiry dates. It is sometimes recommended to use block.number and an average block time to estimate times; with a 10 second block time, 1 week equates to approximately, 60480 blocks. Thus, specifying a block number at which to change a contract state can be more secure, as miners are unable to easily manipulate the block number.
🌟 Selected for report: pfapostol
Also found by: 0x040, 0x1f8b, 0x85102, 0xDjango, 0xNazgul, 0xNineDec, 0xSmartContract, 0xkatana, Amithuddar, Aymen0909, Bnke0x0, CertoraInc, Chandr, CodingNameKiki, Deivitto, Dionysus, Diraco, ElKu, Fitraldys, Funen, GalloDaSballo, Guardian, IllIllI, JC, JansenC, Jeiwan, LeoS, Metatron, Noah3o6, RaymondFam, ReyAdmirado, Rohan16, RoiEvenHaim, Rolezn, Ruhum, Saintcode_, Shishigami, Sm4rty, SooYa, StevenL, Tagir2003, The_GUILD, TomJ, Tomo, Waze, __141345__, ajtra, apostle0x01, aviggiano, bobirichman, brgltd, c3phas, cRat1st0s, carlitox477, cccz, ch0bu, chrisdior4, d3e4, delfin454000, djxploit, durianSausage, erictee, exolorkistis, fatherOfBlocks, gogo, grGred, hyh, ignacio, jag, karanctf, kris, ladboy233, lukris02, m_Rassska, martin, medikko, natzuu, ne0n, newfork01, oyc_109, peiw, rbserver, ret2basic, robee, rokinot, rvierdiiev, sikorico, simon135, tnevler, zishansami
33.3445 DAI - $33.34
Severity: Gas Optimizations
The overheads outlined below are PER LOOP, excluding the first loop
storage arrays incur a Gwarmaccess (100 gas) memory arrays use MLOAD (3 gas) calldata arrays use CALLDATALOAD (3 gas)
Caching the length changes each of these to a DUP<N> (3 gas), and gets rid of the extra DUP<N> needed to store the stack offset
for (uint256 step; step < instructions.length; ) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L278
Severity: Gas Optimizations
When a function with a memory array is called externally, the abi.decode() step has to use a for-loop to copy each index of the calldata to the memory index. Each iteration of this for-loop costs at least 60 gas (i.e. 60 * <mem_array>.length). Using calldata directly, obliviates the need for such a loop in the contract code and runtime execution. Structs have the same overhead as an array of length one
function configureDependencies() external virtual returns (Keycode[] memory dependencies) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L139
function requestPermissions() external view virtual returns (Permissions[] memory requests) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L143
function _setPolicyPermissions( Policy policy_, Permissions[] memory requests_, bool grant_ ) internal {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L391
function getInstructions(uint256 instructionsId_) public view returns (Instruction[] memory) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L37
function initialize(uint256[] memory startObservations_, uint48 lastObservationTime_)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L205
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L48
function requestPermissions() external view override onlyKernel returns (Permissions[] memory requests) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L61
function batchToTreasury(ERC20[] memory tokens_) external onlyRole("callback_admin") {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L152
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L61
function requestPermissions() external view override onlyKernel returns (Permissions[] memory requests) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L70
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L69
function requestPermissions() external view override returns (Permissions[] memory permissions) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L77
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L154
function requestPermissions() external view override returns (Permissions[] memory requests) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L171
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L18
function requestPermissions() external view override returns (Permissions[] memory permissions) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L25
function initialize(uint256[] memory startObservations_, uint48 lastObservationTime_)
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/PriceConfig.sol#L45
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/TreasuryCustodian.sol#L27
function requestPermissions() external view override returns (Permissions[] memory requests) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/TreasuryCustodian.sol#L34
function revokePolicyApprovals(address policy_, ERC20[] memory tokens_) external {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/TreasuryCustodian.sol#L53
function configureDependencies() external override returns (Keycode[] memory dependencies) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/VoterRegistration.sol#L19
function requestPermissions() external view override returns (Permissions[] memory permissions) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/VoterRegistration.sol#L27
Severity: Gas Optimizations
The code should be refactored such that they no longer exist, or the block should do something useful, such as emitting an event or reverting. If the contract is meant to be extended, the contract should be abstract and the function signatures be added without any default implementation. If the block is an empty if-statement block to avoid doing subsequent checks in the else-if/else conditions, the else-if/else conditions should be nested under the negation of the if-statement, because they involve different classes of checks, which may lead to the introduction of errors when the code is later modified (if(x){}else if(y){...}else{...} => if(!x){if(y){...}else{...}})
constructor(Kernel kernel_) KernelAdapter(kernel_) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L85
function KEYCODE() public pure virtual returns (Keycode) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L95
function VERSION() external pure virtual returns (uint8 major, uint8 minor) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L100
function INIT() external virtual onlyKernel {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L105
function configureDependencies() external virtual returns (Keycode[] memory dependencies) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L139
function requestPermissions() external view virtual returns (Permissions[] memory requests) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L143
Severity: Gas Optimizations
for (uint256 i = 0; i < reqLength; ) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L397
Severity: Gas Optimizations
Saves a storage slot for the mapping. Depending on the circumstances and sizes of types, can avoid a Gsset (20000 gas) per mapping combined. Reads and subsequent writes can also be cheaper when a function requires both values and they both fit in the same storage slot.
mapping(address => mapping(ERC20 => uint256)) public withdrawApproval; mapping(address => uint256)) public reserveDebt;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L33
mapping(address => uint256)) public userEndorsementsForProposal; mapping(address => uint256)) public userVotesForProposal; mapping(address => bool)) public tokenClaimsForProposal;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L102
Severity: Gas Optimizations
<x> * 2 is equivalent to <x> << 1 and <x> / 2 is the same as <x> >> 1. The MUL and DIV opcodes cost 5 gas, whereas SHL and SHR only cost 3 gas
int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L372
uint256 invCushionPrice = 10**(oracleDecimals * 2) / range.cushion.low.price;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L419
uint256 invWallPrice = 10**(oracleDecimals * 2) / range.wall.low.price;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L420
int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L427
) * (FACTOR_SCALE + RANGE.spread(true) * 2)) /
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L786
Severity: Gas Optimizations
function amountsForMarket(uint256 id_) external view override returns (uint256 in_, uint256 out_) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L173
Severity: Gas Optimizations
_movingAverage += (currentPrice - earliestPrice) / numObs;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L136
_movingAverage -= (earliestPrice - currentPrice) / numObs;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L138
total += startObservations_[i];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L222
reserveDebt[token_][msg.sender] += amount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L96
totalDebt[token_] += amount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L97
reserveDebt[token_][msg.sender] -= received;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L115
totalDebt[token_] -= received;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L116
if (oldDebt < amount_) totalDebt[token_] += amount_ - oldDebt;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L131
else totalDebt[token_] -= oldDebt - amount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L132
balanceOf[from_] -= amount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L56
balanceOf[to_] += amount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L58
_amountsPerMarket[id_][0] += inputAmount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L143
_amountsPerMarket[id_][1] += outputAmount_;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L144
totalEndorsementsForProposal[proposalId_] -= previousEndorsement;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L194
totalEndorsementsForProposal[proposalId_] += userVotes;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L198
yesVotesForProposal[activeProposal.proposalId] += userVotes;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L252
noVotesForProposal[activeProposal.proposalId] += userVotes;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L254
lastBeat += frequency();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L103
Severity: Gas Optimizations
If needed, the value can be read from the verified contract source code. Savings are due to the compiler not having to create non-payable getter functions for deployment calldata, and not adding another entry to the method ID table
uint8 public constant decimals = 18;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L59
uint256 public constant FACTOR_SCALE = 1e4;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L65
uint256 public constant SUBMISSION_REQUIREMENT = 100; uint256 public constant ACTIVATION_DEADLINE = 2 weeks; uint256 public constant GRACE_PERIOD = 1 weeks; uint256 public constant ENDORSEMENT_THRESHOLD = 20; uint256 public constant EXECUTION_THRESHOLD = 33; uint256 public constant EXECUTION_TIMELOCK = 3 days;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L121-L137
uint32 public constant FACTOR_SCALE = 1e4;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L89
Set variable to private.
Severity: Gas Optimizations
The following functions could be set external to save gas and improve code quality. External call cost is less expensive than of public functions.
function KEYCODE() public pure virtual returns (Keycode) {}
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L95
function grantRole(Role role_, address addr_) public onlyAdmin {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L439
function revokeRole(Role role_, address addr_) public onlyAdmin {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L451
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L23
function VERSION() public pure override returns (uint8 major, uint8 minor) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L28
function getInstructions(uint256 instructionsId_) public view returns (Instruction[] memory) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L37
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L20
function mintOhm(address to_, uint256 amount_) public permissioned {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L33
function burnOhm(address from_, uint256 amount_) public permissioned {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/MINTR.sol#L37
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L108
function getCurrentPrice() public view returns (uint256) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L154
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L110
function updateMarket(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L215
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L47
function withdrawReserves(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/TRSRY.sol#L75
function KEYCODE() public pure override returns (Keycode) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L22
function transfer(address to_, uint256 amount_) public pure override returns (bool) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L45
function transferFrom(
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/VOTES.sol#L51
function getMetadata(uint256 proposalId_) public view returns (ProposalMetadata memory) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L145
function getActiveProposal() public view returns (ActivatedProposal memory) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L151
function frequency() public view returns (uint256) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L121
function getAmountOut(ERC20 tokenIn_, uint256 amountIn_) public view returns (uint256) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L749
function fullCapacity(bool high_) public view override returns (uint256) {
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L778
Severity: Gas Optimizations
To help the optimizer, declare a storage type variable and use it instead of repeatedly fetching the reference in a map or an array. The effect can be quite significant. As an example, instead of repeatedly calling someMap[someIndex], save its reference like this: SomeStruct storage someStruct = someMap[someIndex] and use it.
if (address(getModuleForKeycode[keycode]) != address(0))
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L269
Module oldModule = getModuleForKeycode[keycode];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L281
moduleDependents[keycode].push(policy_);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L309
getDependentIndex[keycode][policy_] = moduleDependents[keycode].length - 1;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L310
Policy[] storage dependents = moduleDependents[keycode];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L415
uint256 origIndex = getDependentIndex[keycode][policy_];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L417
delete getDependentIndex[keycode][policy_];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L426
Instruction[] storage instructions = storedInstructions[instructionsId];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/INSTR.sol#L46
uint256 earliestPrice = observations[nextObsIndex];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L130
return observations[lastIndex];
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L186
kernel.executeAction(instructions[step].action, instructions[step].target);
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L279
Severity: Gas Optimizations
Lower than uint256 size storage variables are less gas efficient. Using uint64 does not give any efficiency, actually, it is the opposite as EVM operates on default of 256-bit values so uint64 is more expensive in this case as it needs a conversion. It only gives improvements in cases where you can pack variables together, e.g. structs.
uint32 public nextObsIndex;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L44
uint32 public numObservations;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L47
uint48 public observationFrequency;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L50
uint48 public movingAverageDuration;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L53
uint48 public lastObservationTime;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L56
uint8 public constant decimals = 18;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L59
uint8 ohmEthDecimals = _ohmEthPriceFeed.decimals();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L84
uint8 reserveEthDecimals = _reserveEthPriceFeed.decimals();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L87
uint32 numObs = numObservations;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L127
uint32 lastIndex = nextObsIndex == 0 ? numObservations - 1 : nextObsIndex - 1;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L185
uint48 lastActive;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/RANGE.sol#L45
uint8 public immutable ohmDecimals;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L83
uint8 public immutable reserveDecimals;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L86
uint32 public constant FACTOR_SCALE = 1e4;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L89
uint8 oracleDecimals = PRICE.decimals();
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L418
uint32 observe = _config.regenObserve;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L665
uint32 cushionFactor;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L13
uint32 cushionDuration;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L14
uint32 cushionDebtBuffer;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L15
uint32 cushionDepositInterval;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L16
uint32 reserveFactor;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L17
uint32 regenWait;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L18
uint32 regenThreshold;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L19
uint32 regenObserve;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L20
uint32 count;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L31
uint48 lastRegen;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L32
uint32 nextObservation;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/interfaces/IOperator.sol#L33
Severity: Gas Optimizations
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.
bool public isActive;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L113
mapping(Keycode => mapping(Policy => mapping(bytes4 => bool))) public modulePermissions;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L181
mapping(address => mapping(Role => bool)) public hasRole;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L194
mapping(Role => bool) public isRole;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/Kernel.sol#L197
bool public initialized;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/modules/PRICE.sol#L62
mapping(address => mapping(uint256 => bool)) public approvedMarkets;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/BondCallback.sol#L24
mapping(uint256 => bool) public proposalHasBeenActivated;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L105
mapping(uint256 => mapping(address => bool)) public tokenClaimsForProposal;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Governance.sol#L117
bool public active;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Heart.sol#L33
bool public initialized;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L63
bool public active;
https://github.com/code-423n4/2022-08-olympus/tree/main/src/policies/Operator.sol#L66