abstract contract AssetHelpers {
    using SafeERC20 for ERC20;
    using SafeMath for uint256;

    /// @dev Helper to approve a target account with the max amount of an asset.
    /// This is helpful for fully trusted contracts, such as adapters that
    /// interact with external protocol like Uniswap, Compound, etc.
    function __approveAssetMaxAsNeeded(
        address _asset,
        address _target,
        uint256 _neededAmount
    ) internal {
        uint256 allowance = ERC20(_asset).allowance(address(this), _target);
        if (allowance < _neededAmount) {
            if (allowance > 0) {
                ERC20(_asset).safeApprove(_target, 0);
            }
            ERC20(_asset).safeApprove(_target, type(uint256).max);
        }
    }

    /// @dev Helper to transfer full asset balances from the current contract to a target
    function __pushFullAssetBalances(address _target, address[] memory _assets)
        internal
        returns (uint256[] memory amountsTransferred_)
    {
        amountsTransferred_ = new uint256[](_assets.length);
        for (uint256 i; i < _assets.length; i++) {
            ERC20 assetContract = ERC20(_assets[i]);
            amountsTransferred_[i] = assetContract.balanceOf(address(this));
            if (amountsTransferred_[i] > 0) {
                assetContract.safeTransfer(_target, amountsTransferred_[i]);
            }
        }

        return amountsTransferred_;
    }
}
/// @title AssetHelpers Contract
/// @author Enzyme Council <security@enzyme.finance>
/// @notice A util contract for common token actions
function __pushFullAssetBalances(address _target, address[] memory _assets)
    internal
    returns (uint256[] memory amountsTransferred_)
{
    amountsTransferred_ = new uint256[](_assets.length);
    for (uint256 i; i < _assets.length; i++) {
        ERC20 assetContract = ERC20(_assets[i]);
        amountsTransferred_[i] = assetContract.balanceOf(address(this));
        if (amountsTransferred_[i] > 0) {
            assetContract.safeTransfer(_target, amountsTransferred_[i]);
        }
    }

    return amountsTransferred_;
}

/// @dev Helper to transfer full asset balances from the current contract to a target