2

i have a contract who containt a function onTokenTransfer(address _sender, uint256 _fee, bytes memory _data), when i transfer some ERC-20 Token using ERC-677 function transferAndCall, the function onTokenTransfer in my contract trigger logic in it and call another function in my contract and for this i found two alternatives :

FIRST ONE :

i use low-level call :

function onTokenTransfer(
    address _sender,
    uint256 _fee,
    bytes memory _data
) public {
    require(_fee >= fee, "NOT ENOUGH FUNDS");
    (bool success, ) = address(this).call(_data);
    require(success, "NOT SUCCESS");
}

but I saw that I have to use it as little as possible for different reasons .

SECOND ONE :

decode data and then call my function :

function onTokenTransfer(
    address _sender,
    uint256 _fee,
    bytes memory _data
) public {
    require(_fee >= fee, "NOT ENOUGH FUNDS");

    myFunction(parameter); // for this i have to decode data to get the parameter value
    require(success, "NOT SUCCESS");
}

What is the best solution between those two, and if its the second one how to decode data to get the parameter value ? Thank you

1 Answer 1

2

Whenever possible, you should specify the function to call in your contract to reduce the attack surface. Otherwise, attackers might call your contract in unexpected ways.

If you always call the same contract function, you can simply pass only the encoded function arguments to transferAndCall and then decode them in the contract using the abi.decode method.

If you want to be able to call multiple functions, you must first remove the first 4 bytes of the calldata, since this represents the function selector. You can slice bytes in solitity as follows:

function slice(bytes calldata _data) external pure returns(bytes calldata){
    return _data[4:];
}

and then decode the remaining function arguments as above.

Alternatively, and if you know the input values, you can check that the input data is correct by comparing _data with the expected calldata constructed with the encodeWithSelector method, and then make a low-level call.

2
  • how do i remove the first 4 bytes inside solidity ?
    – noro meb
    Jan 31 at 13:35
  • 1
    have updated my answer Jan 31 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.