Platform: Code4rena
Start Date: 21/04/2022
Pot Size: $100,000 USDC
Total HM: 18
Participants: 60
Period: 7 days
Judge: gzeon
Total Solo HM: 10
Id: 112
League: ETH
Rank: 27/60
Findings: 2
Award: $351.93
🌟 Selected for report: 0
🚀 Solo Findings: 0
293.0606 USDC - $293.06
Revoke role functionality does not remove account from _roleMembers
mapping which makes following functions return incorrect data:
getRoleMember
getRoleMemberCount
Function renounceGovernance
is directly using getRoleMemberCount
as a check if it should be possible to remove governance role from the account.
require(getRoleMemberCount(Roles.GOVERNANCE) > 1, Error.CANNOT_REVOKE_ROLE);
Since getRoleMemberCount
does not update _roleMembers
incorrect data is being returned.
Scenario:
renounceGovernance
renounceGovernance
Manual Review / VSCode
It is recommended to remove specified account from _roleMembers
mapping in _revokeRole
internal function.
#0 - chase-manning
2022-04-28T11:48:39Z
Duplicate of #164
🌟 Selected for report: cccz
Also found by: 0x1f8b, 0xDjango, 0xkatana, Dravee, IllIllI, WatchPug, berndartmueller, defsec, horsefacts, hyh, kenta, rayn, reassor, sorrynotsorry
58.8714 USDC - $58.87
https://github.com/code-423n4/2022-04-backd/blob/c856714a50437cb33240a5964b63687c9876275b/backd/contracts/oracles/ChainlinkUsdWrapper.sol#L64 https://github.com/code-423n4/2022-04-backd/blob/c856714a50437cb33240a5964b63687c9876275b/backd/contracts/oracles/ChainlinkOracleProvider.sol#L58
Protocol uses Chainlink as an oracle for retrieving prices for the assets.
ChainlinkUserWrapper
contract in _ethPrice
function retrieves ETH price using latestRoundData
but the implementation is missing essential security checks that can result in stale and incorrect prices being returned.
ChainlinkOracleProvider
contract in getPriceUSD
is incorrectly checking price by comparing it with 0
value:
require(answer >= 0, Error.NEGATIVE_PRICE);
Instead of >=
it should use >
to make sure that the price is bigger than 0
.
Manual Review / VSCode
It is recommended to add checks on the returned data of latestRoundData
with proper revert messages if the price is stale or the round is incomplete, for example:
( roundId, rawPrice, , updateTime, answeredInRound ) = baseAggregator.latestRoundData(); require(rawPrice > 0, "price <= 0"); require(updateTime != 0, "incomplete round"); require(answeredInRound >= roundId, "stale price");
#0 - chase-manning
2022-04-28T11:28:50Z
Duplicate of #17