Platform: Code4rena
Start Date: 29/03/2024
Pot Size: $36,500 USDC
Total HM: 5
Participants: 72
Period: 5 days
Judge: 3docSec
Total Solo HM: 1
Id: 357
League: ETH
Rank: 27/72
Findings: 1
Award: $8.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: immeas
Also found by: 0xAkira, 0xCiphky, 0xGreyWolf, 0xJaeger, 0xMosh, 0xabhay, 0xlemon, 0xmystery, 0xweb3boy, Aamir, Abdessamed, Aymen0909, Breeje, DanielArmstrong, DarkTower, Dots, EaglesSecurity, FastChecker, HChang26, Honour, IceBear, JC, K42, Krace, MaslarovK, Omik, OxTenma, SAQ, Shubham, Stormreckson, Tigerfrake, Tychai0s, VAD37, ZanyBonzy, albahaca, arnie, ast3ros, asui, b0g0, bareli, baz1ka, btk, caglankaan, carrotsmuggler, cheatc0d3, dd0x7e8, grearlake, igbinosuneric, jaydhales, kaden, kartik_giri_47538, m4ttm, ni8mare, niser93, nonn_ac, oualidpro, pfapostol, pkqs90, popeye, radev_sw, samuraii77, slvDev, zabihullahazadzoi
8.2807 USDC - $8.28
Low/QA/NC
ROUSGFactory
declares a DEFAULT\_ADMIN\_ROLE
but this is never used and the contract does not use role based access control at all. Consider removing this.
bytes32 public constant DEFAULT_ADMIN_ROLE = bytes32(0);
When ROUSG
is being burned with burn
, a Transfer
event with incorrect parameters is emitted. Currently the code is:
emit Transfer(address(0), msg.sender, getROUSGByShares(ousgSharesAmount));
However, this should be:
emit Transfer(_account, address(0), getROUSGByShares(ousgSharesAmount));
ROUSG
currently has a permissioned function for a burner to burn any account's tokens, however since the balance is represented internally by shares it is not possible to fully clear a balance due to precision errors. Consider adding a burnShares
function to allow a users shares to be fully burned.
ROUSGFactory
uses the Transparent Proxy Pattern but OpenZeppelin's current recommendation is UUPS over the Transparent Proxy Pattern which is an older design.
__rOUSG_init
not __rOUSG_init_unchained
When using upgradable contracts, calls to the parent initialisers should go in the _init method with only the contract specific logic going in the _init_unchained method. These two methods are supposed to separate the logic which would usually go in the constructor header and constructor body.
function __rOUSG_init_unchained( address _kycRegistry, uint256 _requirementGroup, address _ousg, address guardian, address _oracle ) internal onlyInitializing { __KYCRegistryClientInitializable_init(_kycRegistry, _requirementGroup); ousg = IERC20(_ousg); oracle = IRWAOracle(_oracle); _grantRole(DEFAULT_ADMIN_ROLE, guardian); _grantRole(PAUSER_ROLE, guardian); _grantRole(BURNER_ROLE, guardian); _grantRole(CONFIGURER_ROLE, guardian); }
Redudant require statements are abundant throughout the codebase, where the code would revert further along its path and no new cases are caught. Consider removing these:
whenNotPaused
modifierThe use of whenNotPaused
on wrap
and unwrap
is redundant since they call _mintShares
and _burnShares
respectively, which also use this modifier.
totalShares
is a private variable and has a public getter getTotalShares
. Consider making totalShares
public and removing the getter.
Prefer the use of y+=x
over y=y+x
due to readability.
Decimals are checked on USDC
and BUIDL
before every redemption, this should not be necessary because these are not intended to change.
OUSGInstantManager
has a retrieveTokens
for the admin to rescue any ERC20 functions from the contract but since the admin can already perform any arbitrary external calls with multiexcall
this is redundant. Consider removing this.
Duplicated code exists in several places, this could be refactored to only exist in a single place.
ROUSG
, totalSupply
and balanceOf
could make use of getROUSGByShares
instead of reimplementing calculation logic.ROUSG
, burn
duplicates logic from unwrap
which could go in a single _unwrap function
.OUSG_TO_ROUSG_SHARES_MULTIPLIER
is a constant used twice, this could be declared in a single contract which is inherited from.multiexcall
is a function written twice, this could be inherited from a single contract#0 - c4-pre-sort
2024-04-05T03:48:49Z
0xRobocop marked the issue as sufficient quality report
#1 - c4-judge
2024-04-11T09:44:05Z
3docSec marked the issue as grade-b