abstract contract ERC20BasicApproveExtension is ERC20Internal {
    /// @notice Approve `target` to spend `amount` and call it with data.
    /// @param target The address to be given rights to transfer and destination of the call.
    /// @param amount The number of tokens allowed.
    /// @param data The bytes for the call.
    /// @return The data of the call.
    function approveAndCall(
        address target,
        uint256 amount,
        bytes calldata data
    ) external payable returns (bytes memory) {
        require(BytesUtil.doFirstParamEqualsAddress(data, msg.sender), "FIRST_PARAM_NOT_SENDER");

        _approveFor(msg.sender, target, amount);

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returnData) = target.call{value: msg.value}(data);
        require(success, string(returnData));
        return returnData;
    }

    /// @notice Temporarily approve `target` to spend `amount` and call it with data.
    /// Previous approvals remains unchanged.
    /// @param target The destination of the call, allowed to spend the amount specified
    /// @param amount The number of tokens allowed to spend.
    /// @param data The bytes for the call.
    /// @return The data of the call.
    function paidCall(
        address target,
        uint256 amount,
        bytes calldata data
    ) external payable returns (bytes memory) {
        require(BytesUtil.doFirstParamEqualsAddress(data, msg.sender), "FIRST_PARAM_NOT_SENDER");

        if (amount > 0) {
            _addAllowanceIfNeeded(msg.sender, target, amount);
        }

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returnData) = target.call{value: msg.value}(data);
        require(success, string(returnData));

        return returnData;
    }
}
function approveAndCall(
    address target,
    uint256 amount,
    bytes calldata data
) external payable returns (bytes memory) {
    require(BytesUtil.doFirstParamEqualsAddress(data, msg.sender), "FIRST_PARAM_NOT_SENDER");

    _approveFor(msg.sender, target, amount);

    // solhint-disable-next-line avoid-low-level-calls
    (bool success, bytes memory returnData) = target.call{value: msg.value}(data);
    require(success, string(returnData));
    return returnData;
}

/// @notice Approve `target` to spend `amount` and call it with data.
/// @param target The address to be given rights to transfer and destination of the call.
/// @param amount The number of tokens allowed.
/// @param data The bytes for the call.
/// @return The data of the call.