Platform: Code4rena
Start Date: 03/05/2022
Pot Size: $50,000 USDC
Total HM: 4
Participants: 46
Period: 5 days
Judge: gzeon
Total Solo HM: 2
Id: 117
League: ETH
Rank: 20/46
Findings: 2
Award: $208.72
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: BowTiedWardens
Also found by: 0x1337, 0x1f8b, 0x4non, 0xDjango, David_, Funen, GimelSec, IllIllI, Picodes, TerrierLover, WatchPug, bobi, cryptphi, csanuragjain, delfin454000, dirk_y, ellahi, fatherOfBlocks, hyh, ilan, jayjonah8, kebabsec, leastwood, oyc_109, robee, samruna, simon135, sorrynotsorry, throttle
161.1611 USDC - $161.16
When using an upgradeable proxy over an implementation it is important to ensure the underlying implementation is initialised in addition to the proxied contract.
Consider the following example where we have a TransparentUpgradeableProxy as contractA and a Implementation as contractB . As a parameter to the constructor of contractA the data is provided to make a delegate call to contractB.initialize() which updates the storage as required in contractA .
Thus, contractB has not been initialized, only contractA has had its state updated. As a result any user is able to call initialize() on contractB , giving themselves full permissions over the contract. There are two reasons why it is not desirable for malicious users to have full control over a contract:
Ensure that the initialize() function is called on all underlying implementations during deployment. This could easily be done by adding in the implementation:
// @custom:oz-upgrades-unsafe-allow constructor constructor() initializer {}
siezeAllowedResult
-> seizeAllowedResult
Here looks like there is a typo: https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/CNft.sol#L89
Although the contracts are forked from compound, they should still be properly commented and you should use https://docs.soliditylang.org/en/v0.8.13/natspec-format.html. As stated: "It is recommended that Solidity contracts are fully annotated using NatSpec for all public interfaces (everything in the ABI)."
1 - It would make code more readable for any dev
2 - There is now some powerful integrations using NatSpec: for example etherscan when checking public functions: https://etherscan.io/token/0x39aa39c021dfbae8fac545936693ac917d5e7563#writeContract
virtual
keywords if contract is intended as finalCNft
is not supposed to be inherited or to be abstract so virtual
keywords should be removed.
Reference:
https://docs.soliditylang.org/en/v0.8.13/contracts.html#function-overriding
Example:
Remove useless commented lines such as https://github.com/bunkerfinance/bunker-protocol/blob/752126094691e7457d08fc62a6a5006df59bd2fe/contracts/Comptroller.sol#L241
#0 - bunkerfinance-dev
2022-05-18T06:42:21Z
This report was useful to us.
🌟 Selected for report: BowTiedWardens
Also found by: 0v3rf10w, 0x1f8b, 0x4non, 0xDjango, 0xNazgul, 0xkatana, Cityscape, Fitraldys, Funen, GimelSec, IllIllI, MaratCerby, Picodes, TerrierLover, Tomio, delfin454000, ellahi, fatherOfBlocks, hansfriese, ilan, joestakey, oyc_109, rfa, robee, samruna, simon135, slywaters, throttle
47.5594 USDC - $47.56
CNft
Although the idea of having only one CNft
contract is nice, why don't you do 3 versions: CNft-721
, CNft-1155
and CNft-Punk
. Deployment of implementations would be more costly (but just 2 contracts) and it would save your users gas as a lot of SLOAD and if else instructions could be avoided.
comptroller
Assuming you'll be using the same Comptroller
across your markets, gas could be saved by passing it as a constant in your CNft` implementation. It is not settable anyway.