Platform: Code4rena
Start Date: 05/10/2023
Pot Size: $33,050 USDC
Total HM: 1
Participants: 54
Period: 6 days
Judge: hansfriese
Id: 294
League: ETH
Rank: 47/54
Findings: 1
Award: $5.43
š Selected for report: 0
š Solo Findings: 0
š Selected for report: thekmj
Also found by: 0x3b, 33BYTEZZZ, Bauchibred, Chom, Dravee, J4X, Limbooo, Maroutis, MiloTruck, MrPotatoMagic, SBSecurity, Sathish9098, Tadev, ZanyBonzy, adam-idarrha, adriro, btk, hyh, lukejohn, nmirchev8, peakbolt, radev_sw, rvierdiiev
5.4311 USDC - $5.43
Issue | number of Instances | |
---|---|---|
Lā01 | No Need to call function retrieveProxyContractAddress because function deployProxyDelegatorIfNeeded already gives the proxy address | 1 |
Lā02 | the function delegateMulti does an unsafe external call back to the caller, so it should have reentrency guard | 1 |
Issue | number of Instances | |
---|---|---|
Nā01 | 1 |
retrieveProxyContractAddress
because function deployProxyDelegatorIfNeeded
already gives the proxy address.in the function _processDelegation
we call deployProxyDelegatorIfNeeded
but don't store the address where the proxy is deployed:
deployProxyDelegatorIfNeeded(target); transferBetweenDelegators(source, target, amount);
but instead we call retrieveProxyContractAddress
again to get the proxy address, which is a waste since we incur all the gas overhead from doing the calculations again, and also affects readability:
address proxyAddressTo = retrieveProxyContractAddress(token, to);
recommendation:
in the function transferBetweenDelegators
we should call deployProxyDelegatorIfNeeded
and store the address like so:
address proxyAddressTo = deployProxyDelegatorIfNeeded(target);
delegateMulti
does an unsafe external call back to the caller, so it should have reentrency guardthe function _mintBatch
does an unsafe external calls back to the address specified in the first parameter, which is msg.sender
in this case, if it's a contract:
function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response )
this function is called by _mintbatch
, and it calls back to the to
address, and in the contract we set it to msg.sender
.
_mintBatch(msg.sender, targets, amounts[:targetsLength], "");
recommendation:
because this function does an unsafe external call back to the caller, consider adding reentrency guard to this function.
_processDelegation
the function _processDelegation
checks for the balance of the user before transfering tokens between the two proxies, but the transaction will fail inevitably if the user had insufficient balance for the transfer because of the _burnbatch
call.
uint256 balance = getBalanceForDelegate(source); assert(amount <= balance);
#0 - c4-pre-sort
2023-10-13T12:34:11Z
141345 marked the issue as sufficient quality report
#1 - c4-judge
2023-10-24T15:56:45Z
hansfriese marked the issue as grade-b