Platform: Code4rena
Start Date: 18/10/2022
Pot Size: $75,000 USDC
Total HM: 27
Participants: 144
Period: 7 days
Judge: gzeon
Total Solo HM: 13
Id: 170
League: ETH
Rank: 106/144
Findings: 1
Award: $0.00
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: Rolezn
Also found by: 0x1f8b, 0x52, 0x5rings, 0xNazgul, 0xSmartContract, 0xZaharina, 0xhunter, 0xzh, 8olidity, Amithuddar, Aymen0909, B2, Bnke0x0, Chom, Deivitto, Diana, Diraco, Dravee, Franfran, JC, Jeiwan, Josiah, JrNet, Jujic, KingNFT, KoKo, Lambda, Margaret, Migue, Ocean_Sky, PaludoX0, Picodes, Rahoz, RaoulSchaffranek, RaymondFam, RedOneN, ReyAdmirado, Shinchan, Tagir2003, Trust, Waze, Yiko, __141345__, a12jmx, adriro, ajtra, arcoun, aysha, ballx, bin2chen, bobirichman, brgltd, bulej93, catchup, catwhiskeys, caventa, cccz, cdahlheimer, ch0bu, chaduke, chrisdior4, cloudjunky, cryptostellar5, cryptphi, csanuragjain, cylzxje, d3e4, delfin454000, djxploit, durianSausage, erictee, fatherOfBlocks, francoHacker, gianganhnguyen, gogo, hansfriese, i_got_hacked, ignacio, imare, karanctf, kv, leosathya, louhk, lukris02, lyncurion, m_Rassska, malinariy, martin, mcwildy, mics, minhtrng, nicobevi, oyc_109, pashov, peanuts, pedr02b2, peiw, rbserver, ret2basic, rotcivegaf, rvierdiiev, ryshaw, sakman, sakshamguruji, saneryee, securerodd, seyni, sikorico, svskaushik, teawaterwire, tnevler, w0Lfrum
0 USDC - $0.00
The version 0.8.13 has some issues like Vulnerability related to ABI-encoding and Vulnerability related to 'Optimizer Bug Regarding Memory Side Effects of Inline Assembly'.
Many contracts contain the encoding logics and there are many assemblies in the protocol also.
Recommend using the latest solidity version like 0.8.17.
// accommodating the 2300 gas stipend // adding 1x for each item in array to accomodate rounding errors uint256 gasCost = (23300 * length) + length;
Currently, it distrubute smaller eth than expected and we should change 23300
to 2300
like the comment.
bps[i] > 0
in configurePayouts()
function configurePayouts(address payable[] memory addresses, uint256[] memory bps) public onlyOwner { require(addresses.length == bps.length, "PA1D: missmatched array lenghts"); uint256 totalBp; for (uint256 i = 0; i < addresses.length; i++) { totalBp = totalBp + bps[i]; } require(totalBp == 10000, "PA1D: bps down't equal 10000"); //@audit-N5 _setPayoutAddresses(addresses); _setPayoutBps(bps); }
If bps[i] == 0
, it will just increase the length and produce unnecessary transfers in _payoutEth() and _payoutToken().
Also, with the revert-on-zero-value-tranfer tokens, _payoutToken()
will revert here.
function _payoutToken(address tokenAddress) private { address payable[] memory addresses = _getPayoutAddresses(); uint256[] memory bps = _getPayoutBps(); uint256 length = addresses.length; ERC20 erc20 = ERC20(tokenAddress); uint256 balance = erc20.balanceOf(address(this)); require(balance > 10000, "PA1D: Not enough tokens to transfer"); uint256 sending; //uint256 sent; for (uint256 i = 0; i < length; i++) { sending = ((bps[i] * balance) / 10000); require(erc20.transfer(addresses[i], sending), "PA1D: Couldn't transfer token"); // sent = sent + sending; } }
addresses.length
in configurePayouts()
function configurePayouts(address payable[] memory addresses, uint256[] memory bps) public onlyOwner { require(addresses.length == bps.length, "PA1D: missmatched array lenghts"); uint256 totalBp; for (uint256 i = 0; i < addresses.length; i++) { totalBp = totalBp + bps[i]; } require(totalBp == 10000, "PA1D: bps down't equal 10000"); //@audit-N5 _setPayoutAddresses(addresses); _setPayoutBps(bps); }
Currently, addresses.length
can be 10000 at most(when we check if bps > 0) and _payoutEth() and _payoutToken() will revert because of block gas limit.
We should check an upper limit like 50.
addresses
in _setPayoutAddresses()
function _setPayoutAddresses(address payable[] memory addresses) private { bytes32 slot = _payoutAddressesSlot; uint256 length = addresses.length; assembly { sstore(slot, length) } address payable value; for (uint256 i = 0; i < length; i++) { slot = keccak256(abi.encodePacked(i, slot)); value = addresses[i]; assembly { sstore(slot, value) } } }
Currently, there is no validation of address(0) and the tokens might be lost in _payoutEth() and _payoutToken().
require(totalBp == 10000, "PA1D: bps down't equal 10000");
Change down't
to doesn't
.