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: 4/101
Findings: 1
Award: $197.19
🌟 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
197.1933 USDC - $197.19
For the SimpleFeiDaiPSM
contract, please keep in mind that DAI is considering to depeg from USD:
https://decrypt.co/107273/makerdao-founder-dai-drop-dollar-peg-tornado-cash-usdc
Consider making event parameters indexed
, e.g. address field here:
/// @notice event emitted upon a redemption event Redeem(address to, uint256 amountFeiIn, uint256 amountAssetOut); /// @notice event emitted when fei gets minted event Mint(address to, uint256 amountIn, uint256 amountFeiOut);
signAndClaim
in RariMerkleRedeemer
probably needs hasNotSigned
modifier, otherwise a malicious user can call the function multiple times with a signature and empty tokens array, thus spamming Signed
event:function signAndClaim( bytes calldata signature, address[] calldata cTokens, uint256[] calldata amounts, bytes32[][] calldata merkleProofs ) external override nonReentrant {
claimableAmount
(there are more places of occurrence):// check: verify that claimableAmount is zero, revert if not require(claims[msg.sender][_cToken] == 0, "User has already claimed for this cToken.");
// effect: update claimableAmount for the user claims[msg.sender][_cToken] = _amount;
_redeem
and _multiRedeem
: multi redeem for some reason checks that cToken address is not empty while single redeem doesn't:// check: cToken cannot be the zero address require(cTokens[i] != address(0), "Invalid cToken address");
This should not cause any issue but it would be nice to have these functions coherent.
TribeRedeemer
should have a reasonable upper limit for the number of tokensReceived
, otherwise calculations when iterating all the tokens might exceed the block gas limit.
Function previewRedeem
queries tokensReceivedOnRedeem
but later iterates over tokensReceived
directly:
function previewRedeem(uint256 amountIn) ... { tokens = tokensReceivedOnRedeem(); amountsOut = new uint256[](tokens.length); ... for (uint256 i = 0; i < tokensReceived.length; i++)
While in practice tokensReceived
and tokensReceivedOnRedeem
return the same array, it would be better not to make any assumptions and continue with a local instance of tokens.
tokensReceived
for TRIBE
redemption is sent initially, otherwise those who redeem later would get more:uint256 balance = IERC20(tokensReceived[i]).balanceOf(address(this)); ... uint256 redeemedAmount = (amountIn * balance) / base;
Also, consider adding an option for the user to opt out of specific tokens to basically skip them when iterating, e.g. if there is not enough balance of the certain token and the user does not care about it.
require(ECDSA.recover(MESSAGE_HASH, _signature) == msg.sender, "Signature not valid");
string public constant MESSAGE = "Sample message, please update.";