Platform: Code4rena
Start Date: 07/06/2022
Pot Size: $75,000 USDC
Total HM: 11
Participants: 77
Period: 7 days
Judge: gzeon
Total Solo HM: 7
Id: 124
League: ETH
Rank: 21/77
Findings: 2
Award: $157.48
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: berndartmueller
Also found by: 0x1f8b, 0x29A, 0xDjango, 0xNazgul, 0xNineDec, 0xf15ers, 0xkatana, 0xmint, Bronicle, Chom, Cityscape, Deivitto, Funen, GimelSec, GreyArt, IllIllI, JC, Lambda, Meera, Nethermind, Picodes, PierrickGT, Ruhum, Sm4rty, Tadashi, TerrierLover, TomJ, Trumpero, Waze, _Adam, antonttc, ayeslick, c3phas, catchup, cccz, cloudjunky, cryptphi, csanuragjain, delfin454000, dipp, ellahi, fatherOfBlocks, hake, hansfriese, hyh, joestakey, jonah1005, kenzo, minhquanym, oyc_109, sach1r0, saian, simon135, slywaters, sorrynotsorry, sseefried, unforgiven, xiaoming90, z3s, zzzitron
110.0473 USDC - $110.05
pragma abicoder V2
Since wfCashLogic.sol
was using pragma experimental ABIEncoderV2
and used pragma ^0.7.6, it because the ABI coder v2 is not considered experimental anymore, it can be selected via pragma abicoder v2 instead since Solidity 0.7.4.
Manual Review
you can change it into pragma abicoder v2;
ABIEncoderV2
The standart used for pragma ABIEncoder for pragma solidity 0.6.10;
pragma experimental ABIEncoderV2;
Since it was good to use for usually for good readibility and code as well.
Manual Review
1.) File : wfCashLogic.sol Line.98
Since this was only used in function _mintInternal() and unclear what was operatorAck
does to be used since cause it was one comment, that means operator Acknowledge (operatorAck). This was uncleared as an information. what was operatorAck
does. if would be not do an operatorAck, comment can be deleted instead.
2.) File : NotionalTradeModule.sol
416 : * @dev Alo adjust the components / position of the set token accordingly
455 : * @dev Alo adjust the components / position of the set token accordingly
This Alo
was confusing since didn't know what it is stand for. It is typo? or it can be cleared as well.
Manual Review
The pragma declared at wfCashERC4626.sol was used ^0.8.0. As the compiler can be use as 0.8.11 and consider locking at this version the same as another.
Manual Review
The following maps
, it can be grouped in structs.
mapping(ISetToken => bool) public redeemToUnderlying; mapping(ISetToken => bool) public allowedSetTokens; bool public anySetAllowed;
Manual Review
returns a value to the main program when exiting a function. You can do further operations on the returned value. This implementation below can be used to simplify code and good readibility.
1.) File : contracts/protocol/modules/v1/NotionalTradeModule.sol Line 172
return _mintFCashPosition(_setToken, wrappedfCash, IERC20(_sendToken), _mintAmount, _maxSendAmount);
into :
return _mintFCashPosition;
2.) File : contracts/protocol/modules/v1/NotionalTradeModule.sol Line 201
return _redeemFCashPosition(_setToken, wrappedfCash, IERC20(_receiveToken), _redeemAmount, _minReceiveAmount);
into :
return _redeemFCashPosition;
1.) File : contracts/protocol/modules/v1/NotionalTradeModule.sol Line 215
MNGER
change to MANAGER
1.) File : contracts/wfCashERC4626.sol Line. 42
require(pvExternal >= 0);
2.) File : contracts/wfCashERC4626.sol Line. 245
require(int256(type(int88).min) <= y);
3.) File : contracts/wfCashLogic.sol Line. 316
require(x <= uint256(type(uint88).max));
There are many external risks so the suggestion was it should be consider making the contracts pausable, so if in the case of an unexpected event, the admin can pause transfers.
Manual Review
##POC https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/Pausable.sol
Consider making contracts Pausable
🌟 Selected for report: IllIllI
Also found by: 0v3rf10w, 0x1f8b, 0x29A, 0xKitsune, 0xNazgul, 0xSolus, 0xf15ers, 0xkatana, 0xmint, 8olidity, Chom, Cityscape, DavidGialdi, Deivitto, ElKu, Fitraldys, Funen, GreyArt, Lambda, Meera, Picodes, PierrickGT, Sm4rty, Tadashi, TerrierLover, TomJ, Tomio, UnusualTurtle, Waze, _Adam, antonttc, asutorufos, berndartmueller, c3phas, catchup, csanuragjain, delfin454000, djxploit, ellahi, fatherOfBlocks, hake, hansfriese, hyh, joestakey, kaden, minhquanym, oyc_109, rfa, sach1r0, saian, samruna, simon135, slywaters, ynnad
47.4309 USDC - $47.43
Every reason string takes at least 32 bytes. Use short reason strings that fits in 32 bytes or it will become more expensive.
Manual Review
contracts/protocol/modules/v1/NotionalTradeModule.sol#L169 "Send token must be an index component" contracts/protocol/modules/v1/NotionalTradeModule.sol#L199 "FCash to redeem must be an index component" contracts/protocol/modules/v1/NotionalTradeModule.sol#L378 "WrappedfCash not deployed for given parameters" contracts/protocol/modules/v1/NotionalTradeModule.sol#L485 "Not enough received amount" contracts/protocol/modules/v1/NotionalTradeModule.sol#L573 "Token is neither asset nor underlying token"
++i
than i++
for saving more gasUsing i++
instead ++i
for all the loops, the variable i is incremented using i++. It is known that implementation by using ++i
costs less gas per iteration than i++
.
Manual Review
contracts/protocol/modules/v1/NotionalTradeModule.sol#L238 for(uint256 i = 0; i < modules.length; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L254 for(uint256 i = 0; i < modules.length; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L393 for(uint256 i = 0; i < positionsLength; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L605 for(uint256 i = 0; i < positionsLength; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L618 for(uint256 i = 0; i < positionsLength; i++) {
and this can be used prefix instead of used postfix
contracts/protocol/modules/v1/NotionalTradeModule.sol#L610 numFCashPositions++; contracts/protocol/modules/v1/NotionalTradeModule.sol#L623 j++;
uint256 i = 0
into uint256 i
for saving more gasUsing this implementation can saving more gas for each loops.
Manual Review
Change it
contracts/protocol/modules/v1/NotionalTradeModule.sol#L238 for(uint256 i = 0; i < modules.length; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L254 for(uint256 i = 0; i < modules.length; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L393 for(uint256 i = 0; i < positionsLength; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L605 for(uint256 i = 0; i < positionsLength; i++) { contracts/protocol/modules/v1/NotionalTradeModule.sol#L618 for(uint256 i = 0; i < positionsLength; i++) {