Olympus DAO contest - Tomo's results

Version 3 of Olympus protocol, a decentralized floating currency.

General Information

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

Olympus DAO

Findings Distribution

Researcher Performance

Rank: 53/147

Findings: 2

Award: $131.95

🌟 Selected for report: 0

🚀 Solo Findings: 0

QA Report

✅ L-1: Unsafe use of transfer()/transferFrom() with IERC20

📝 Description

Some tokens do not implement the ERC20 standard properly but are still accepted by most code that accepts ERC20 tokens. example Tether (USDT)'s transfer() and transferFrom() functions do not return booleans as the specification requires, and instead have no return value. When these sorts of tokens are cast to IERC20, their function signatures do not match and therefore the calls made, revert.

💡 Recommendation

Use OpenZeppelin's SafeERC20 safeTransfer()/safeTransferFrom() instead

🔍 Findings:

2022-08-olympus/blob/main/src/policies/Governance.sol#L259 VOTES.transferFrom(msg.sender, address(this), userVotes);

2022-08-olympus/blob/main/src/policies/Governance.sol#L312 VOTES.transferFrom(address(this), msg.sender, userVotes);

✅ L-2: _safeMint() should be used rather than _mint() wherever possible

📝 Description

_mint() is discouraged in favor of _safeMint() which ensures that the recipient is either an EOA or implements IERC721Receiver.

💡 Recommendation

You should change from _mint to _safeMint in terms of security.

🔍 Findings:

2022-08-olympus/blob/main/src/modules/VOTES.sol#L36 _mint(wallet_, amount_);

✅ N-1: Do not use Deprecated Library Functions

📝 Description

Deprecated in favor of safeIncreaseAllowance() and safeDecreaseAllowance(). If only setting the initial allowance to the value that means infinite, safeIncreaseAllowance() can be used instead

💡 Recommendation

Use safeIncreaseAllowance() and safeDecreaseAllowance() instead of safeApprove

🔍 Findings:

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L57 ohm.safeApprove(address(MINTR), type(uint256).max);

2022-08-olympus/blob/main/src/policies/Operator.sol#L167 ohm.safeApprove(address(MINTR), type(uint256).max);

✅ N-2: Non-assembly method available

📝 Description

You don't need to use assembly. assembly should be avoided as much as possible due to various risks

💡 Recommendation

You can change as follows. assembly{ id := chainid() } => uint256 id = block.chainid, assembly { size := extcodesize() } => uint256 size = address().code.length

🔍 Findings:

2022-08-olympus/blob/main/src/utils/KernelUtils.sol#L34 size := extcodesize(target_)

✅ N-3: Non-library/interface files should use fixed compiler versions, not floating ones

📝 Description

Non-library/interface files should use fixed compiler versions, not floating ones

💡 Recommendation

Delete the floating keyword ^.

🔍 Findings:

2022-08-olympus/blob/main/src/interfaces/IBondCallback.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IHeart.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IOperator.sol#L2 pragma solidity >=0.8.0;

✅ N-4: Variable names that consist of all capital letters should be reserved for constant/immutable variables

📝 Description

Variable names that consist of all capital letters should be reserved for constant/immutable variables

💡 Recommendation

Variables that are not constant/immutable should be declared in lower case

🔍 Findings:

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L29 OlympusTreasury public TRSRY;

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L30 OlympusMinter public MINTR;

2022-08-olympus/blob/main/src/policies/Governance.sol#L56 OlympusInstructions public INSTR;

2022-08-olympus/blob/main/src/policies/Governance.sol#L57 OlympusVotes public VOTES;

2022-08-olympus/blob/main/src/policies/VoterRegistration.sol#L10 OlympusVotes public VOTES;

✅ N-5: Open Todos

📝 Description

Code architecture, incentives, and error handling/reporting questions/issues should be resolved before deployment

💡 Recommendation

Delete TODO keyword

🔍 Findings:

2022-08-olympus/blob/main/src/policies/Operator.sol#L657 /// TODO determine if this should use the last price from the MA or recalculate the current price, ideally last price is ok since it should have been just updated and should include check against secondary?

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L51 // TODO Currently allows anyone to revoke any approval EXCEPT activated policies.

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L52 // TODO must reorg policy storage to be able to check for deactivated policies.

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L56 // TODO Make sure policy_ is an actual policy and not a random address.

✅ N-6: No use of two-phase ownership transfers

📝 Description

Consider adding a two-phase transfer, where the current owner nominates the next owner, and the next owner has to call accept*() to become the new owner. This prevents passing the ownership to an account that is unable to use it.

💡 Recommendation

Consider implementing a two step process where the admin nominates an account and the nominated account needs to call an acceptOwnership() function for the transfer of admin to fully succeed. This ensures the nominated EOA account is a valid and active account.

🔍 Findings:

2022-08-olympus/blob/main/src/Kernel.sol#L253 admin = target_;

✅ N-7: Use a more recent version of solidity

📝 Description

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

💡 Recommendation

Use more recent version of solidity.

🔍 Findings:

2022-08-olympus/blob/main/src/interfaces/IBondCallback.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IHeart.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IOperator.sol#L2 pragma solidity >=0.8.0;

Gas Optimization

📋 Executive Summary

The attention to gas savings throughout the project is excellent. The use of custom-error and the using the latest version were so impressive.

There are 9 gas optimization tips identified. I would be happy to help you with your project.

Gas SavedInstancesTotal
G-18324
G-2?6
G-3224
G-4?3
G-5?12
G-62034680
G-7257175
G-83517595
G-980282240

✅ G-1: Don't Initialize Variables with Default Value

📝 Description

Uninitialized variables are assigned with the type's default value. Explicitly initializing a variable with it's default value costs unnecessary gas. Not overwriting the default for stack variables saves 8 gas. Storage and memory variables have larger savings

💡 Recommendation

Delete useless variable declarations to save gas.

🔍 Findings:

2022-08-olympus/blob/main/src/Kernel.sol#L397 for (uint256 i = 0; i < reqLength; ) {

2022-08-olympus/blob/main/src/utils/KernelUtils.sol#L43 for (uint256 i = 0; i < 5; ) {

2022-08-olympus/blob/main/src/utils/KernelUtils.sol#L58 for (uint256 i = 0; i < 32; ) {

✅ G-2: Use uint256 instead of bool

📝 Description

Booleans are more expensive than uint256 or any type that takes up a full word because each writes 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.

💡 Recommendation

You should change from bool to uint256 to save gas

🔍 Findings:

2022-08-olympus/blob/main/src/Kernel.sol#L113 bool public isActive;

2022-08-olympus/blob/main/src/modules/PRICE.sol#L62 bool public initialized;

2022-08-olympus/blob/main/src/policies/Heart.sol#L33 bool public active;

2022-08-olympus/blob/main/src/policies/Operator.sol#L63 bool public initialized;

2022-08-olympus/blob/main/src/policies/Operator.sol#L66 bool public active;

2022-08-olympus/blob/main/src/policies/Operator.sol#L735 bool sideActive = RANGE.active(high_);

✅ G-3: Use Shift Right/Left instead of Division/Multiplication if possible

📝 Description

A division/multiplication by any number x being a power of 2 can be calculated by shifting log2(x) to the right/left. While the DIV opcode uses 5 gas, the SHR opcode only uses 3 gas. Furthermore, Solidity's division operation also includes division-by-0 prevention which is bypassed using shifting.

💡 Recommendation

You should change multiplication and division by powers of two to bit shift.

🔍 Findings:

2022-08-olympus/blob/main/src/policies/Operator.sol#L372 int8 scaleAdjustment = int8(ohmDecimals) - int8(reserveDecimals) + (priceDecimals / 2);

2022-08-olympus/blob/main/src/policies/Operator.sol#L427 int8 scaleAdjustment = int8(reserveDecimals) - int8(ohmDecimals) + (priceDecimals / 2);

✅ G-4: Solidity Version should be the latest

📝 Description

Use a solidity version of at least 0.8.0 to get overflow protection without SafeMath 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

💡 Recommendation

You should consider with your team members whether you should choose the latest version. The latest version has its advantages, but also it has disadvantages, such as the possibility of unknown bugs.

🔍 Findings:

2022-08-olympus/blob/main/src/interfaces/IBondCallback.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IHeart.sol#L2 pragma solidity >=0.8.0;

2022-08-olympus/blob/main/src/policies/interfaces/IOperator.sol#L2 pragma solidity >=0.8.0;

✅ G-5: Empty blocks should be removed or emit something

📝 Description

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.

💡 Recommendation

Empty blocks should be removed or emit something (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.

🔍 Findings:

2022-08-olympus/blob/main/src/Kernel.sol#L85 constructor(Kernel kernel*) KernelAdapter(kernel*) {}

2022-08-olympus/blob/main/src/Kernel.sol#L95 function KEYCODE() public pure virtual returns (Keycode) {}

2022-08-olympus/blob/main/src/Kernel.sol#L100 function VERSION() external pure virtual returns (uint8 major, uint8 minor) {}

2022-08-olympus/blob/main/src/Kernel.sol#L105 function INIT() external virtual onlyKernel {}

2022-08-olympus/blob/main/src/Kernel.sol#L115 constructor(Kernel kernel*) KernelAdapter(kernel*) {}

2022-08-olympus/blob/main/src/Kernel.sol#L143 function requestPermissions() external view virtual returns (Permissions[] memory requests) {}

2022-08-olympus/blob/main/src/modules/INSTR.sol#L20 constructor(Kernel kernel*) Module(kernel*) {}

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L45 constructor(Kernel kernel*) Module(kernel*) {}

2022-08-olympus/blob/main/src/policies/Governance.sol#L59 constructor(Kernel kernel*) Policy(kernel*) {}

2022-08-olympus/blob/main/src/policies/PriceConfig.sol#L15 constructor(Kernel kernel*) Policy(kernel*) {}

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L24 constructor(Kernel kernel*) Policy(kernel*) {}

2022-08-olympus/blob/main/src/policies/VoterRegistration.sol#L16 constructor(Kernel kernel*) Policy(kernel*) {}

✅ G-6: Functions guaranteed to revert when called by normal users can be marked payable

📝 Description

See this issue 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 Saves 2400 gas per instance in deploying contract. Saves about 20 gas per instance if using assembly to execute the function.

💡 Recommendation

You should add the keyword payable to those functions.

🔍 Findings:

2022-08-olympus/blob/main/src/Kernel.sol#L76 function changeKernel(Kernel newKernel_) external onlyKernel {

2022-08-olympus/blob/main/src/Kernel.sol#L105 function INIT() external virtual onlyKernel {}

2022-08-olympus/blob/main/src/Kernel.sol#L126 function setActiveStatus(bool activate_) external onlyKernel {

2022-08-olympus/blob/main/src/Kernel.sol#L235 function executeAction(Actions action*, address target*) external onlyExecutor {

2022-08-olympus/blob/main/src/Kernel.sol#L439 function grantRole(Role role*, address addr*) public onlyAdmin {

2022-08-olympus/blob/main/src/Kernel.sol#L451 function revokeRole(Role role*, address addr*) public onlyAdmin {

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L86 onlyRole("callback_whitelist")

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L152 function batchToTreasury(ERC20[] memory tokens_) external onlyRole("callback_admin") {

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L190 function setOperator(Operator operator_) external onlyRole("callback_admin") {

2022-08-olympus/blob/main/src/policies/Heart.sol#L130 function resetBeat() external onlyRole("heart_admin") {

2022-08-olympus/blob/main/src/policies/Heart.sol#L135 function toggleBeat() external onlyRole("heart_admin") {

2022-08-olympus/blob/main/src/policies/Heart.sol#L142 onlyRole("heart_admin")

2022-08-olympus/blob/main/src/policies/Heart.sol#L150 function withdrawUnspentRewards(ERC20 token_) external onlyRole("heart_admin") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L195 function operate() external override onlyWhileActive onlyRole("operator_operate") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L276 ) external override onlyWhileActive nonReentrant returns (uint256 amountOut) {

2022-08-olympus/blob/main/src/policies/Operator.sol#L349 onlyRole("operator_reporter")

2022-08-olympus/blob/main/src/policies/Operator.sol#L500 onlyRole("operator_policy")

2022-08-olympus/blob/main/src/policies/Operator.sol#L510 function setThresholdFactor(uint256 thresholdFactor_) external onlyRole("operator_policy") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L516 function setCushionFactor(uint32 cushionFactor_) external onlyRole("operator_policy") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L531 ) external onlyRole("operator_policy") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L548 function setReserveFactor(uint32 reserveFactor_) external onlyRole("operator_policy") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L563 ) external onlyRole("operator_policy") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L588 onlyRole("operator_admin")

2022-08-olympus/blob/main/src/policies/Operator.sol#L598 function initialize() external onlyRole("operator_admin") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L618 function regenerate(bool high_) external onlyRole("operator_admin") {

2022-08-olympus/blob/main/src/policies/Operator.sol#L624 function toggleActive() external onlyRole("operator_admin") {

2022-08-olympus/blob/main/src/policies/PriceConfig.sol#L47 onlyRole("price_admin")

2022-08-olympus/blob/main/src/policies/PriceConfig.sol#L60 onlyRole("price_admin")

2022-08-olympus/blob/main/src/policies/PriceConfig.sol#L71 onlyRole("price_admin")

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L46 ) external onlyRole("custodian") {

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L75 ) external onlyRole("custodian") {

2022-08-olympus/blob/main/src/policies/TreasuryCustodian.sol#L84 ) external onlyRole("custodian") {

2022-08-olympus/blob/main/src/policies/VoterRegistration.sol#L45 function issueVotesTo(address wallet*, uint256 amount*) external onlyRole("voter_admin") {

2022-08-olympus/blob/main/src/policies/VoterRegistration.sol#L53 function revokeVotesFrom(address wallet*, uint256 amount*) external onlyRole("voter_admin") {

✅ G-7: Use ++i instead of i++

📝 Description

You can get cheaper for loops (at least 25 gas, however, can be up to 80 gas under certain conditions), by rewriting The post-increment operation (i++) boils down to saving the original value of i, incrementing it and saving that to a temporary place in memory, and then returning the original value; only after that value is returned is the value of i actually updated (4 operations).On the other hand, in pre-increment doesn't need to store temporary(2 operations) so, the pre-increment operation uses fewer opcodes and is thus more gas efficient.

💡 Recommendation

You should change from i++ to ++i.

🔍 Findings:

2022-08-olympus/blob/main/src/policies/Operator.sol#L488 decimals++;

2022-08-olympus/blob/main/src/policies/Operator.sol#L670 _status.low.count++;

2022-08-olympus/blob/main/src/policies/Operator.sol#L675 _status.low.count--;

2022-08-olympus/blob/main/src/policies/Operator.sol#L686 _status.high.count++;

2022-08-olympus/blob/main/src/policies/Operator.sol#L691 _status.high.count--;

2022-08-olympus/blob/main/src/utils/KernelUtils.sol#L49 i++;

2022-08-olympus/blob/main/src/utils/KernelUtils.sol#L64 i++;

✅ G-8: Use x=x+y instad of x+=y

📝 Description

You can save about 35 gas per instance if you change from x+=y to x=x+y This works equally well for subtraction, multiplication and division.

💡 Recommendation

You should change from x+=y to x=x+y.

🔍 Findings:

2022-08-olympus/blob/main/src/modules/PRICE.sol#L136 _movingAverage += (currentPrice - earliestPrice) / numObs;

2022-08-olympus/blob/main/src/modules/PRICE.sol#L138 _movingAverage -= (earliestPrice - currentPrice) / numObs;

2022-08-olympus/blob/main/src/modules/PRICE.sol#L222 total += startObservations_[i];

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L96 reserveDebt[token*][msg.sender] += amount*;

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L97 totalDebt[token*] += amount*;

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L115 reserveDebt[token_][msg.sender] -= received;

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L116 totalDebt[token_] -= received;

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L131 if (oldDebt < amount*) totalDebt[token*] += amount_ - oldDebt;

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L132 else totalDebt[token*] -= oldDebt - amount*;

2022-08-olympus/blob/main/src/modules/VOTES.sol#L56 balanceOf[from*] -= amount*;

2022-08-olympus/blob/main/src/modules/VOTES.sol#L58 balanceOf[to*] += amount*;

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L143 amountsPerMarket[id][0] += inputAmount_;

2022-08-olympus/blob/main/src/policies/BondCallback.sol#L144 amountsPerMarket[id][1] += outputAmount_;

2022-08-olympus/blob/main/src/policies/Governance.sol#L194 totalEndorsementsForProposal[proposalId_] -= previousEndorsement;

2022-08-olympus/blob/main/src/policies/Governance.sol#L198 totalEndorsementsForProposal[proposalId_] += userVotes;

2022-08-olympus/blob/main/src/policies/Governance.sol#L252 yesVotesForProposal[activeProposal.proposalId] += userVotes;

2022-08-olympus/blob/main/src/policies/Governance.sol#L254 noVotesForProposal[activeProposal.proposalId] += userVotes;

2022-08-olympus/blob/main/src/policies/Heart.sol#L103 lastBeat += frequency();

✅ G-9: Use indexed for uint, bool, and address

📝 Description

Using the indexed keyword for value types such as uint, bool, and address saves gas costs, as seen in the example below. However, this is only the case for value types, whereas indexing bytes and strings are more expensive than their unindexed version. If you add indexed keyword, you can save gas at least 80 gas in emitting event. Please read this document. Also indexed keyword has more merits. It can be useful to have a way to monitor the contract's activity after it was deployed. One way to accomplish this is to look at all transactions of the contract, however that may be insufficient, as message calls between contracts are not recorded in the blockchain. Moreover, it shows only the input parameters, not the actual changes being made to the state. Also events could be used to trigger functions in the user interface.

💡 Recommendation

Up to three indexed can be used per event and should be added.

🔍 Findings:

2022-08-olympus/blob/main/src/modules/INSTR.sol#L11 event InstructionsStored(uint256 instructionsId);

2022-08-olympus/blob/main/src/modules/PRICE.sol#L26 event NewObservation(uint256 timestamp_, uint256 price_, uint256 movingAverage_);

2022-08-olympus/blob/main/src/modules/PRICE.sol#L27 event MovingAverageDurationChanged(uint48 movingAverageDuration_);

2022-08-olympus/blob/main/src/modules/PRICE.sol#L28 event ObservationFrequencyChanged(uint48 observationFrequency_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L20 event WallUp(bool high_, uint256 timestamp_, uint256 capacity_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L21 event WallDown(bool high_, uint256 timestamp_, uint256 capacity_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L22 event CushionUp(bool high_, uint256 timestamp_, uint256 capacity_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L23 event CushionDown(bool high_, uint256 timestamp_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L24 event PricesChanged(

2022-08-olympus/blob/main/src/modules/RANGE.sol#L30 event SpreadsChanged(uint256 cushionSpread_, uint256 wallSpread_);

2022-08-olympus/blob/main/src/modules/RANGE.sol#L31 event ThresholdFactorChanged(uint256 thresholdFactor_);

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L20 event ApprovedForWithdrawal(address indexed policy_, ERC20 indexed token_, uint256 amount_);

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L27 event DebtIncurred(ERC20 indexed token_, address indexed policy_, uint256 amount_);

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L28 event DebtRepaid(ERC20 indexed token_, address indexed policy_, uint256 amount_);

2022-08-olympus/blob/main/src/modules/TRSRY.sol#L29 event DebtSet(ERC20 indexed token_, address indexed policy_, uint256 amount_);

2022-08-olympus/blob/main/src/policies/Governance.sol#L86 event ProposalSubmitted(uint256 proposalId);

2022-08-olympus/blob/main/src/policies/Governance.sol#L87 event ProposalEndorsed(uint256 proposalId, address voter, uint256 amount);

2022-08-olympus/blob/main/src/policies/Governance.sol#L88 event ProposalActivated(uint256 proposalId, uint256 timestamp);

2022-08-olympus/blob/main/src/policies/Governance.sol#L89 event WalletVoted(uint256 proposalId, address voter, bool for_, uint256 userVotes);

2022-08-olympus/blob/main/src/policies/Governance.sol#L90 event ProposalExecuted(uint256 proposalId);

2022-08-olympus/blob/main/src/policies/Heart.sol#L28 event Beat(uint256 timestamp_);

2022-08-olympus/blob/main/src/policies/Heart.sol#L29 event RewardIssued(address to_, uint256 rewardAmount_);

2022-08-olympus/blob/main/src/policies/Heart.sol#L30 event RewardUpdated(ERC20 token_, uint256 rewardAmount_);

2022-08-olympus/blob/main/src/policies/Operator.sol#L45 event Swap(

2022-08-olympus/blob/main/src/policies/Operator.sol#L51 event CushionFactorChanged(uint32 cushionFactor_);

2022-08-olympus/blob/main/src/policies/Operator.sol#L52 event CushionParamsChanged(uint32 duration_, uint32 debtBuffer_, uint32 depositInterval_);

2022-08-olympus/blob/main/src/policies/Operator.sol#L53 event ReserveFactorChanged(uint32 reserveFactor_);

2022-08-olympus/blob/main/src/policies/Operator.sol#L54 event RegenParamsChanged(uint32 wait_, uint32 threshold_, uint32 observe_);

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter