for (uint256 i = 0; i < len; ) {
    uint256 assetIndex = i - (skipIndex ? 1 : 0);
    if (assets[i] == joinToken) {
        maxAmountsIn[i] = joinAmount;
        assetsIn[assetIndex] = joinAmount;
    } else if (assets[i] == upFrontToken && assets[i] != poolToken) {
        maxAmountsIn[i] = upfrontAmount;
        assetsIn[assetIndex] = upfrontAmount;
    } else {
        skipIndex = skipIndex || assets[i] == poolToken;
    }
    unchecked {
        i++;
    }
}
tokensIn = [49 ether, 0]
tokensIn = [49 ether, 49 ether]
function updateLeverJoin(
    PoolActionParams memory poolActionParams,
    address joinToken,
    address upFrontToken,
    uint256 flashLoanAmount,
    uint256 upfrontAmount
) external view returns (PoolActionParams memory outParams) {
    outParams = poolActionParams;

    if (poolActionParams.protocol == Protocol.BALANCER) {
        (bytes32 poolId, address[] memory assets, uint256[] memory assetsIn, uint256[] memory maxAmountsIn) = abi
            .decode(poolActionParams.args, (bytes32, address[], uint256[], uint256[]));

        address poolToken = balancerVault.getPool(poolId);

        uint256 len = assets.length;
        // the offset is needed because of the BPT token that needs to be skipped from the join
        bool skipIndex = false;
        uint256 joinAmount = flashLoanAmount;
        if (upFrontToken == joinToken) {
            joinAmount += upfrontAmount;
        }

        // update the join parameters with the new amounts
        for (uint256 i = 0; i < len; ) {
            uint256 assetIndex = i - (skipIndex ? 1 : 0);
            if (assets[i] == joinToken) {
                maxAmountsIn[i] = joinAmount;
                assetsIn[assetIndex] = joinAmount;
            } else if (assets[i] == upFrontToken && assets[i] != poolToken) {
                maxAmountsIn[i] = upfrontAmount;
                assetsIn[assetIndex] = upfrontAmount;
            } else {
                skipIndex = skipIndex || assets[i] == poolToken;
            }
            unchecked {
                i++;
            }
        }

        // update the join parameters
        outParams.args = abi.encode(poolId, assets, assetsIn, maxAmountsIn);
    }
}
