contract AffiliateFeeTransformer is
    Transformer
{
    // solhint-disable no-empty-blocks
    using LibRichErrorsV06 for bytes;
    using LibSafeMathV06 for uint256;
    using LibERC20Transformer for IERC20TokenV06;

    /// @dev Information for a single fee.
    struct TokenFee {
        // The token to transfer to `recipient`.
        IERC20TokenV06 token;
        // Amount of each `token` to transfer to `recipient`.
        // If `amount == uint256(-1)`, the entire balance of `token` will be
        // transferred.
        uint256 amount;
        // Recipient of `token`.
        address payable recipient;
    }

    uint256 private constant MAX_UINT256 = uint256(-1);

    /// @dev Create this contract.
    constructor()
        public
        Transformer()
    {}

    /// @dev Transfers tokens to recipients.
    /// @param data ABI-encoded `TokenFee[]`, indicating which tokens to transfer.
    /// @return success The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).
    function transform(
        bytes32, // callDataHash,
        address payable, // taker,
        bytes calldata data
    )
        external
        override
        returns (bytes4 success)
    {
        TokenFee[] memory fees = abi.decode(data, (TokenFee[]));

        // Transfer tokens to recipients.
        for (uint256 i = 0; i < fees.length; ++i) {
            uint256 amount = fees[i].amount;
            if (amount == MAX_UINT256) {
                amount = LibERC20Transformer.getTokenBalanceOf(fees[i].token, address(this));
            }
            if (amount != 0) {
                fees[i].token.transformerTransfer(fees[i].recipient, amount);
            }
        }

        return LibERC20Transformer.TRANSFORMER_SUCCESS;
    }
}
/// @dev A transformer that transfers tokens to arbitrary addresses.
function transform(
    bytes32, // callDataHash,
    address payable, // taker,
    bytes calldata data
)
    external
    override
    returns (bytes4 success)
{
    TokenFee[] memory fees = abi.decode(data, (TokenFee[]));

    // Transfer tokens to recipients.
    for (uint256 i = 0; i < fees.length; ++i) {
        uint256 amount = fees[i].amount;
        if (amount == MAX_UINT256) {
            amount = LibERC20Transformer.getTokenBalanceOf(fees[i].token, address(this));
        }
        if (amount != 0) {
            fees[i].token.transformerTransfer(fees[i].recipient, amount);
        }
    }

    return LibERC20Transformer.TRANSFORMER_SUCCESS;
}

/// @dev Transfers tokens to recipients.
/// @param data ABI-encoded `TokenFee[]`, indicating which tokens to transfer.
/// @return success The success bytes (`LibERC20Transformer.TRANSFORMER_SUCCESS`).