If the user is a smart contract? - enderphan94/solidity-pentest GitHub Wiki

Sending ether to the users is an unsteady way. For example:

function sendETH() external payable{
        for(uint256 i=0; i< users.length; i++){
            address user = users[i];
            payable(user).transfer(msg.value);
        }
    }

So the users here can be wallet addresses or contract addresses. the wallet address users are fine but the contract address users. The contract can be modified by the users, so they can control the way to receive the ether from others. what if the user A have a contract like this:

contract A{
        receive() external payable {
             revert();
    }

}

HIGHLY recommended that you require users to pull their funds instead of push them to the users with a for-loop.

A lot harder to implement with a large amount of users, need to run though the loop until getting low on gas, hold position in the loop, and then wait until the next execution. If you don’t implement this then one one will get paid (ever!) when your number of users is too large to loop through without breaking the gas limit.

An even bigger problem is that it is a huge security issue. What if one of the users makes his fallback function revert(); then after him, no one would be able to receive their ether because the loop will always fail (revert the entire execution) when paying out this mischevious user.

There are lots more issues with the push method of sending payments, but these should be enough.