soliditynfterc721

Set approveForAll from a contract on another contract


I have two smart contracts (A, B), which are extended from ERC721. Is it possible to create a function in B to call setApprovalForAll on A from a user Z?

this is in contract B: testApprove(A) as user Z

    function testApprove(address _contract) public payable {
        bytes memory payload = abi.encodeWithSignature("setApprovalForAll(address,bool)", address(this), true);
        (bool success,) = address(_contract).delegatecall(payload);
        require(success);
        bool result = ERC721(_contract).isApprovedForAll(msg.sender, address(this));
        require(result, "Approve not set!");
    }

success is true, and there was no error because it ran OK. But when I check if contract B is approved, it's not!

Am I doing something wrong?

Thanks


Solution

  • bytes memory payload = abi.encodeWithSignature("setApprovalForAll(address,bool)", address(this), true);
    (bool success,) = address(_contract).delegatecall(payload);
    

    If this was invoked with regular .call, it would give approval from your contract (caller of the setApprovalForAll() function) to your contract (first param).

    Since it's invoked with .delegatecall, the storage change is not performed on the target contract - but on your contract (the delegate caller). So all this snippet does, it sets a storage value of your contract in the same storage slot that the target would set the approval.

    As per EIP-721, setApprovalForAll() sets the approval from msg.sender. So the only way to receive the approval from the user is to have them send the transaction directly to the token contract - not through any other contract in between.