Search code examples
ethereumsoliditysmartcontractsvyper

A security issue with require(send()) in Solidity


I'm working on a uni project based on blockchain, and I have to audit our system, check known attacks, ect. This the the document that I check, principaly, since i start to work on smart contracts issues first : Known-attack ethereum smart contract

I have trouble understanding the example used in the "Dos With (unexpected) revert attack" part. I share the code :

    // INSECURE
contract Auction {
    address currentLeader;
    uint highestBid;

    function bid() payable {
        require(msg.value > highestBid);

        require(currentLeader.send(highestBid)); // Refund the old leader, if it fails then revert

        currentLeader = msg.sender;
        highestBid = msg.value;
    }}

They say that an attacker could force the call of bid to revert everytime so no-one is able to bid, which would make the attacker win the auction by default. But.. How would he do that, that's the part I don't get. Do we agree that at least this piece of contract is the "valid one", and isn't a payload ? If the payload is a contract, can anyone provide an exemple/explanation ?

I'll add that, if here I quote a solidity contract, we work with Vyper, but from what I read before, this is still a kind of issue that i'll find there too.

Thanks in advance !


Solution

  • If send() target address is a smart contract it will execute the fallback function.

    If the currentLeader points to a smart contract that has a fallback function that has been intentionally made to revert on failed send, the bid() won't work for any participants until currentLeader has been changed.

    More information here.

    This is not a "DoS" attack but simply gotcha in Solidity programming.