Olympus DAO contest - rvierdiiev'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: 12/147

Findings: 4

Award: $2,107.81

🌟 Selected for report: 2

πŸš€ Solo Findings: 1

Findings Information

🌟 Selected for report: rvierdiiev

Labels

bug
2 (Med Risk)
sponsor acknowledged

Awards

1905.4132 DAI - $1,905.41

External Links

Lines of code

https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L548 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L711 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L133 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L145 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L185 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L780

Vulnerability details

Impact

Operator::setReserveFactor sets new reserveFactor value. This parameter is used in fullCapacity function to calculate how much capacity is available by high/low side. Then calculated capacity is used by Range module inside regenerate function to set the threshold of capacity for both sides of market. Then in Range::updateCapacity function this threshold is checked to understand if the wall should be down and the bond market should be closed.

Changing this value means that the capacity of sides has changed and the sides should be regenarated to include this changes.

Proof of Concept

https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L548 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L711 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L133 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L145 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L185 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Operator.sol#L780

Tools Used

Call this after the param updating. _regenerate(true); _regenerate(false;

#0 - Oighty

2022-09-08T18:04:14Z

Forcing a regeneration when the reserveFactor is updated could cause unintended regeneration if a wall is currently down. A better approach may be to conditionally regenerate each side if they are active.

#1 - Oighty

2022-09-12T18:23:57Z

After discussing with the team more, we are going to leave this as-is. It is more flexible to not regenerate the side in this function. With the current implementation, the guardian can determine if the change should go into effect on the next regen, or if it should happen immediately. To enable immediately, they can manually call regenerate.

Findings Information

🌟 Selected for report: rvierdiiev

Also found by: Jeiwan, Lambda, Trust, datapunk, devtooligan, itsmeSTYJ, zzzitron

Labels

bug
2 (Med Risk)
sponsor confirmed

Awards

113.9192 DAI - $113.92

External Links

Lines of code

https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L92 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L103

Vulnerability details

Impact

beat() function is allowed to be called by anyone once in frequency() period. The purpose of it is to update the prices and do another operations related to bond market. User who ran it are rewarded. There is no need to run this function more then 1 time in frequency() period. However if beat() was last time called more then frequency() time ago then user can execute beat() function (block.timestamp - lastBeat)/frequency() times in a row in same block and get rewards.

Proof of Concept

https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L92 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L103

https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L103 Change this line to lastBeat = block.timestamp - (block.timestamp - lastBeat) % frequency(); So no matter how much time the beat() was no called, it is possible to call it only once per frequency().

#0 - Oighty

2022-09-07T21:06:18Z

See comment on #405. This approach actually solves both of our issues though.

#1 - 0xean

2022-09-19T13:25:29Z

going to use this issue as the primary since the solution is elegant and solves the problem.

  1. Check if instructionsId_ exists. Better revert with message then return zeroes. https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/INSTR.sol#L38
  2. Check address for 0 to not burn tokens. https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/MINTR.sol#L34 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/VOTES.sol#L36 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/VOTES.sol#L58 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/VoterRegistration.sol#L47
  3. FullMath lib is not used. Remove dependency. https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/PRICE.sol#L9 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/PRICE.sol#L23 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L5 https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L18
  4. Check address params if not 0 before setting. https://github.com/code-423n4/2022-08-olympus/blob/main/src/modules/RANGE.sol#L102-L103 https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Heart.sol#L144
  5. Check if proposalId_ exists. Better revert with message then return zeroes. https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Governance.sol#L146
  6. Check if instructions_ is empty on top of the function. Save user’s gas. https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Governance.sol#L160
  7. Better make check if yesVotesForProposal[activeProposal.proposalId] is bigger then noVotesForProposal[activeProposal.proposalId] and revert special error, than do underflow error. https://github.com/code-423n4/2022-08-olympus/blob/main/src/policies/Governance.sol#L266
  8. Make KERNEL::configureDependencies function use modifier onlyKernel as this should be called by kernel. https://github.com/code-423n4/2022-08-olympus/blob/main/src/Kernel.sol#L139

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