The most common implementation is as follows:

function approveAndCall(address _spender, uint256 _value, bytes _extraData)  public returns (bool success) {
    tokenRecipient spender = tokenRecipient(_spender);
    if (approve(_spender, _value)) {
        _spender.receiveApproval(msg.sender, _value, this, _extraData);
        ApproveAndCall(_spender, _value, _extraData );
        return true;

From what I can see it's obligatory that the receiving contract has "Receiveapproval" function, meaning a hacker can't really call anything...on another thought:

If a receiving contract has receiveapproval function with delegatecall inside and the delegatecall calls back the sender, it will achieve a little but still something? Why? Because while delegatecall doesn't change storage of receiver it preserves the message sender, so:

  1. Contract A calls B via approveandcall
  2. B has a.delegatecall to any function of A
  3. A will receive the call from B looking as if it's from A but it will never change any storage on A.

Basically this can only be problem if A contains a very perverted function something like:

function allow_withdrawals_for_anyone() public 
require(msg.sender = address(this));
// you see the point

Or this will work too: function allowwithdrawals() internal {

// internal modifier should pass in this case }

This is just my understanding that while delegatecall doesn't change variables it at least registers a msg.sender which in this case is A, again I may be wrong but I see no other way of A knowing who the msg.sender is unless a function gets fully executed with a call.

If my reasoning is correct then I'd be happy to see cases of functions where this can be dangerous really.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.