Say I have a contract called MyContract
, and I require to send 100000 DAI to it. Ideally, I'd firstly call approve(<address of A>, 100000e18)
in DAI's contract itself. Secondly, I'd execute, for instance, the function collectDAI(100000e18)
from MyContract
. This function will internally call transferFrom(msg.sender, address(this), 100000e18)
in DAI's contract and update MyContract
's state accordingly.
Well, in this scenario an attacker could detect my call to "approve" and immediately execute by himself the transferFrom
function (with very high fee if needed) and this transaction could potentially arrive before mine. Whenever I would try to call the collectDAI
function in MyContract
, I wouldn't be able, since the allowance has decreased to zero. Furthermore, MyContract
might not be prepared to handle undesired DAI, so those tokens might be lost forever.
So, is it just my imagination, or we are facing a HUGE vulnerability in ERC20 that could potentially disallow its usage in smart contracts?
Please note that I'm using DAI in this example for simplicity, but it's perfectly applicable to any ERC20.
approve
only when the current approved amount is zero. Another workaround is to implement a couple of additional functions -increaseApproval
anddecreaseApproval
.approve
twice, the attacker listening for the second one and triggeringtransferFrom
before the secondapprove
arrives. This attack vector is very limited to a sole attacker and a second call toapprove
, which makes it not so relevant. However the attack I'm describing can be executed by ANY attacker that pretends to destroy the business model of a DApp.