Platform: Code4rena
Start Date: 09/09/2022
Pot Size: $42,000 USDC
Total HM: 2
Participants: 101
Period: 3 days
Judge: hickuphh3
Total Solo HM: 2
Id: 161
League: ETH
Rank: 96/101
Findings: 1
Award: $33.58
đ Selected for report: 0
đ Solo Findings: 0
đ Selected for report: GalloDaSballo
Also found by: 0x040, 0x1f8b, 0x4non, 0x52, 0x85102, 0xNazgul, 0xSky, 0xSmartContract, Aymen0909, Bnke0x0, CertoraInc, Chandr, Chom, CodingNameKiki, Deivitto, Diana, Funen, JC, Jeiwan, Junnon, KIntern_NA, Lambda, Mohandes, Noah3o6, Ocean_Sky, Picodes, R2, Randyyy, RaymondFam, ReyAdmirado, Rohan16, Rolezn, Samatak, Sm4rty, SnowMan, SooYa, StevenL, Tagir2003, Tointer, TomJ, Tomo, V_B, Waze, _Adam, __141345__, a12jmx, ajtra, ak1, asutorufos, bharg4v, bobirichman, brgltd, c3phas, cccz, cryptonue, cryptostellar5, cryptphi, csanuragjain, d3e4, datapunk, delfin454000, dipp, djxploit, durianSausage, erictee, fatherOfBlocks, gogo, got_targ, hansfriese, horsefacts, hyh, ignacio, innertia, izhuer, karanctf, ladboy233, leosathya, lucacez, lukris02, mics, oyc_109, pashov, pauliax, prasantgupta52, rbserver, ret2basic, rfa, robee, rokinot, rotcivegaf, rvierdiiev, sach1r0, scaraven, sikorico, simon135, smiling_heretic, sorrynotsorry, unforgiven, wagmi, yixxas
33.5761 USDC - $33.58
In the contracts, floating pragmas should not be used. Contracts should be deployed with the same compiler version and flags that they have been tested with thoroughly. Locking the pragma helps to ensure that contracts do not accidentally get deployed using, for example, an outdated compiler version that might introduce bugs that affect the contract system negatively.
There were 2 instances of this issue.
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L2
File: contracts/peg/SimpleFeiDaiPSM.sol #1 pragma solidity ^0.8.4;
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/shutdown/redeem/TribeRedeemer.sol#L2
File: contracts/shutdown/redeem/TribeRedeemer.sol #2 pragma solidity ^0.8.4;
Lock the pragma version
The previewRedeem
function already defines a named return variable baseTokenAmount
.
The function should be altered as follows:
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol function previewRedeem(address cToken, uint256 amount) public view override returns (uint256 baseTokenAmount) { // Each ctoken exchange rate is stored as how much you should get for 1e18 of the particular cToken // Thus, we divide by 1e18 when returning the amount that a person should get when they provide // the amount of cTokens they're turning into the contract + baseTokenAmount = ((cTokenExchangeRates[cToken] * amount) / 1e18); - return (cTokenExchangeRates[cToken] * amount) / 1e18; }
return (cTokenExchangeRates[cToken] * amount) / 1e18;
should be removed as it is redundant and also does not use proper brackets which can result in confusion
When deploying contracts, you should use the latest released version of Solidity. Apart from exceptional cases, only the latest version receives security fixes. Furthermore, breaking changes as well as new features are introduced regularly.
There were 4 instances of this issue.
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L2
File: contracts/peg/SimpleFeiDaiPSM.sol #1 pragma solidity ^0.8.4;
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #2 pragma solidity =0.8.10;
File: contracts/shutdown/fuse/MerkleRedeemerDripper.sol #3 pragma solidity =0.8.10;
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/shutdown/redeem/TribeRedeemer.sol#L2
File: contracts/shutdown/redeem/TribeRedeemer.sol #4 pragma solidity ^0.8.4;
Update to the latest released version of Solidity
It is recommended that Solidity contracts are fully annotated using NatSpec
There were 16 instances of this issue.
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L26-L27
File: contracts/peg/SimpleFeiDaiPSM.sol #1 /// @notice event emitted upon a redemption event Redeem(address to, uint256 amountFeiIn, uint256 amountAssetOut);
Missing: @param to
, @param amountFeiIn
, @param amountAssetOut
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L28-L29
File: contracts/peg/SimpleFeiDaiPSM.sol #2 @notice event emitted when fei gets minted event Mint(address to, uint256 amountIn, uint256 amountFeiOut);
Missing: @param amountIn
, @param amountFeiOut
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L31-L37
File: contracts/peg/SimpleFeiDaiPSM.sol #3 /// @notice mint `amountFeiOut` FEI to address `to` for `amountIn` underlying tokens /// @dev see getMintAmountOut() to pre-calculate amount out function mint( address to, uint256 amountIn, uint256 minAmountOut ) external returns (uint256 amountFeiOut) {
Missing: @param minAmountOut
, @return amountFeiOut
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L48-L52
File: contracts/peg/SimpleFeiDaiPSM.sol #4 function redeem( address to, uint256 amountFeiIn, uint256 minAmountOut ) external returns (uint256 amountOut) {
Missing: @return amountOut
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #5 function claim( address _cToken, uint256 _amount, bytes32[] calldata _merkleProof ) external override hasSigned nonReentrant {
Missing: @param _cToken
, @param _amount
, @param _merkleProof
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #6 function multiClaim( address[] calldata _cTokens, uint256[] calldata _amounts, bytes32[][] calldata _merkleProofs ) external override hasSigned nonReentrant {
Missing: @param _cTokens
, @param _amounts
, @param _merkleProofs
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #7 function redeem(address cToken, uint256 cTokenAmount) external override hasSigned nonReentrant {
Missing: @param cTokenAmount
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #8 function multiRedeem(address[] calldata cTokens, uint256[] calldata cTokenAmounts)
Missing: `@param cTokenAmounts
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #9 function previewRedeem(address cToken, uint256 amount) public view override returns (uint256 baseTokenAmount) {
Missing: `@return baseTokenAmount
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #10 function signAndClaim( bytes calldata signature, address[] calldata cTokens, uint256[] calldata amounts, bytes32[][] calldata merkleProofs ) external override nonReentrant {
Missing: `@param signature
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #11 function signAndClaimAndRedeem( bytes calldata signature, address[] calldata cTokens, uint256[] calldata amountsToClaim, uint256[] calldata amountsToRedeem, bytes32[][] calldata merkleProofs ) external override hasNotSigned nonReentrant {
Missing: @param amountsToClaim
, @param amountsToRedeem
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #12 function _configureExchangeRates(address[] memory _cTokens, uint256[] memory _exchangeRates) internal {
Missing: @param _exchangeRates
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #13 function _configureMerkleRoots(address[] memory _cTokens, bytes32[] memory _roots) internal {
Missing: `@param _roots
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #14 function _configureBaseToken(address _baseToken) internal {
Missing: `@param _baseToken
File: contracts/shutdown/fuse/MerkleRedeemerDripper.sol #15 /// @notice Drips ERC20 tokens to the RariMerkleRedeemer contract /// @author kryptoklob contract MerkleRedeemerDripper is ERC20Dripper { constructor( address _core, address _target, uint256 _dripPeriod, uint256 _amountToDrip, address _token ) ERC20Dripper(_core, _target, _dripPeriod, _amountToDrip, _token) {}
Missing: @param _core
, @param _target
, @param _dripPeriod
, @param _amountToDrip
, `@param _token
File: contracts/shutdown/redeem/TribeRedeemer.sol #16 constructor( address _redeemedToken, address[] memory _tokensReceived, uint256 _redeemBase )
Missing: @param _redeemedToken
, @param _tokensReceived
, @param _redeemBase
Constants and immutable variables should be named in all capital letters
There were 2 instances of this issue.
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L75
File: contracts/peg/SimpleFeiDaiPSM.sol #1 address public constant balanceReportedIn = address(DAI);
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L92-L98
File: contracts/peg/SimpleFeiDaiPSM.sol #2 uint256 public constant mintFeeBasisPoints = 0; uint256 public constant redeemFeeBasisPoints = 0; address public constant underlyingToken = address(DAI); uint256 public constant getMaxMintAmountOut = type(uint256).max; bool public constant paused = false; bool public constant redeemPaused = false; bool public constant mintPaused = false;
Use all capital letters when naming constants/immutable variables
uint256 is assigned to zero by default, additional reassignment to zero is unnecessary
There were 8 instances of this issue.
https://github.com/code-423n4/2022-09-tribe/blob/main/contracts/peg/SimpleFeiDaiPSM.sol#L92-L93
File: contracts/peg/SimpleFeiDaiPSM.sol #1 - uint256 public constant mintFeeBasisPoints = 0; + uint256 public constant mintFeeBasisPoints; - uint256 public constant redeemFeeBasisPoints = 0; + uint256 public constant redeemFeeBasisPoints;
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #2 - for (uint256 i = 0; i < _cTokens.length; i++) { + for (uint256 i; i < _cTokens.length; i++) {
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #3 - for (uint256 i = 0; i < _cTokens.length; i++) { + for (uint256 i; i < _cTokens.length; i++) {
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #4 - for (uint256 i = 0; i < _cTokens.length; i++) { + for (uint256 i; i < _cTokens.length; i++) {
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #5 - for (uint256 i = 0; i < cTokens.length; i++) { + for (uint256 i; i < cTokens.length; i++) {
File: contracts/shutdown/fuse/RariMerkleRedeemer.sol #6 - for (uint256 i = 0; i < cTokens.length; i++) { + for (uint256 i; i < cTokens.length; i++) {
File: contracts/shutdown/redeem/TribeRedeemer.sol #7 - for (uint256 i = 0; i < tokensReceived.length; i++) { + for (uint256 i; i < tokensReceived.length; i++) {
File: contracts/shutdown/redeem/TribeRedeemer.sol #8 - for (uint256 i = 0; i < tokens.length; i++) { + for (uint256 i; i < tokens.length; i++) {