UNPKG

@yfi/sdk

Version:

Interaction framework for the yearn protocol

11,888 lines 398 kB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }

require('cross-fetch/polyfill');
var providers = require('@ethersproject/providers');
var EventEmitter = _interopDefault(require('events'));
var BigNumber = require('bignumber.js');
var BigNumber__default = _interopDefault(BigNumber);
var address = require('@ethersproject/address');
var contracts = require('@ethersproject/contracts');
var Emittery = _interopDefault(require('emittery'));
var bignumber = require('@ethersproject/bignumber');
var fetch$1 = _interopDefault(require('cross-fetch'));
var constants = require('@ethersproject/constants');
var bignumber$1 = require('@ethersproject/bignumber/lib/bignumber');

function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  try {
    var info = gen[key](arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }

  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then(_next, _throw);
  }
}

function _asyncToGenerator(fn) {
  return function () {
    var self = this,
        args = arguments;
    return new Promise(function (resolve, reject) {
      var gen = fn.apply(self, args);

      function _next(value) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
      }

      function _throw(err) {
        asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
      }

      _next(undefined);
    });
  };
}

function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, descriptor.key, descriptor);
  }
}

function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}

function _extends() {
  _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  return _extends.apply(this, arguments);
}

function _inheritsLoose(subClass, superClass) {
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype.constructor = subClass;

  _setPrototypeOf(subClass, superClass);
}

function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
    return o.__proto__ || Object.getPrototypeOf(o);
  };
  return _getPrototypeOf(o);
}

function _setPrototypeOf(o, p) {
  _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
    o.__proto__ = p;
    return o;
  };

  return _setPrototypeOf(o, p);
}

function _isNativeReflectConstruct() {
  if (typeof Reflect === "undefined" || !Reflect.construct) return false;
  if (Reflect.construct.sham) return false;
  if (typeof Proxy === "function") return true;

  try {
    Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
    return true;
  } catch (e) {
    return false;
  }
}

function _construct(Parent, args, Class) {
  if (_isNativeReflectConstruct()) {
    _construct = Reflect.construct;
  } else {
    _construct = function _construct(Parent, args, Class) {
      var a = [null];
      a.push.apply(a, args);
      var Constructor = Function.bind.apply(Parent, a);
      var instance = new Constructor();
      if (Class) _setPrototypeOf(instance, Class.prototype);
      return instance;
    };
  }

  return _construct.apply(null, arguments);
}

function _isNativeFunction(fn) {
  return Function.toString.call(fn).indexOf("[native code]") !== -1;
}

function _wrapNativeSuper(Class) {
  var _cache = typeof Map === "function" ? new Map() : undefined;

  _wrapNativeSuper = function _wrapNativeSuper(Class) {
    if (Class === null || !_isNativeFunction(Class)) return Class;

    if (typeof Class !== "function") {
      throw new TypeError("Super expression must either be null or a function");
    }

    if (typeof _cache !== "undefined") {
      if (_cache.has(Class)) return _cache.get(Class);

      _cache.set(Class, Wrapper);
    }

    function Wrapper() {
      return _construct(Class, arguments, _getPrototypeOf(this).constructor);
    }

    Wrapper.prototype = Object.create(Class.prototype, {
      constructor: {
        value: Wrapper,
        enumerable: false,
        writable: true,
        configurable: true
      }
    });
    return _setPrototypeOf(Wrapper, Class);
  };

  return _wrapNativeSuper(Class);
}

function _unsupportedIterableToArray(o, minLen) {
  if (!o) return;
  if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  var n = Object.prototype.toString.call(o).slice(8, -1);
  if (n === "Object" && o.constructor) n = o.constructor.name;
  if (n === "Map" || n === "Set") return Array.from(o);
  if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
}

function _arrayLikeToArray(arr, len) {
  if (len == null || len > arr.length) len = arr.length;

  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

  return arr2;
}

function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  if (it) return (it = it.call(o)).next.bind(it);

  if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
    if (it) o = it;
    var i = 0;
    return function () {
      if (i >= o.length) return {
        done: true
      };
      return {
        done: false,
        value: o[i++]
      };
    };
  }

  throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var CustomError = /*#__PURE__*/function (_Error) {
  _inheritsLoose(CustomError, _Error);

  function CustomError(message, error_type) {
    var _this;

    _this = _Error.call(this, message) || this;
    _this.error_type = error_type;
    return _this;
  }

  return CustomError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
/**
 * Generic SDK error. Wrapped errors are:
 *
 * - ethers.js errors
 * - http request errors
 */

var SdkError = /*#__PURE__*/function (_CustomError) {
  _inheritsLoose(SdkError, _CustomError);

  function SdkError(message, error_code) {
    var _this2;

    _this2 = _CustomError.call(this, message, "sdk") || this;
    _this2.error_code = error_code;
    return _this2;
  }

  return SdkError;
}(CustomError);
SdkError.NO_SLIPPAGE = "no_slippage";

var SimulationError = /*#__PURE__*/function (_CustomError) {
  _inheritsLoose(SimulationError, _CustomError);

  function SimulationError(message, error_code) {
    var _this;

    _this = _CustomError.call(this, message, "simulation") || this;
    _this.error_code = error_code;
    return _this;
  }

  return SimulationError;
}(CustomError);
SimulationError.NO_LOG = "no_log";
SimulationError.TENDERLY_RESPONSE_ERROR = "tenderly_response_error";
SimulationError.PARTIAL_REVERT = "partial_revert";
var ZapperError = /*#__PURE__*/function (_CustomError2) {
  _inheritsLoose(ZapperError, _CustomError2);

  function ZapperError(message, error_code) {
    var _this2;

    _this2 = _CustomError2.call(this, message, "zapper") || this;
    _this2.error_code = error_code;
    return _this2;
  }

  return ZapperError;
}(CustomError);
ZapperError.ZAP_IN_APPROVAL_STATE = "zap_in_approval_state";
ZapperError.ZAP_IN_APPROVAL = "zap_in_approval";
ZapperError.ZAP_OUT_APPROVAL_STATE = "zap_out_approval_state";
ZapperError.ZAP_OUT_APPROVAL = "zap_out_approval";
ZapperError.ZAP_IN = "zap_in";
ZapperError.ZAP_OUT = "zap_out";
var EthersError = /*#__PURE__*/function (_CustomError3) {
  _inheritsLoose(EthersError, _CustomError3);

  function EthersError(message, error_code) {
    var _this3;

    _this3 = _CustomError3.call(this, message, "ethers") || this;
    _this3.error_code = error_code;
    return _this3;
  }

  return EthersError;
}(CustomError);
EthersError.FAIL_TOKEN_FETCH = "fail_token_fetch";
EthersError.NO_DECIMALS = "no_decimals";
EthersError.NO_PRICE_PER_SHARE = "no_price_per_share";
EthersError.POPULATING_TRANSACTION = "populating_transaction";
var TenderlyError = /*#__PURE__*/function (_CustomError4) {
  _inheritsLoose(TenderlyError, _CustomError4);

  function TenderlyError(message, error_code) {
    var _this4;

    _this4 = _CustomError4.call(this, message, "tenderly") || this;
    _this4.error_code = error_code;
    return _this4;
  }

  return TenderlyError;
}(CustomError);
TenderlyError.SIMULATION_CALL = "simulation_call";
TenderlyError.CREATE_FORK = "create_fork";
var PriceFetchingError = /*#__PURE__*/function (_CustomError5) {
  _inheritsLoose(PriceFetchingError, _CustomError5);

  function PriceFetchingError(message, error_code) {
    var _this5;

    _this5 = _CustomError5.call(this, message, "price_fetching") || this;
    _this5.error_code = error_code;
    return _this5;
  }

  return PriceFetchingError;
}(CustomError);
PriceFetchingError.FETCHING_PRICE_ORACLE = "fetching_price_oracle";
PriceFetchingError.FETCHING_PRICE_PICKLE = "fetching_price_pickle";

(function (ZapProtocol) {
  ZapProtocol["PICKLE"] = "pickle";
  ZapProtocol["YEARN"] = "yearn";
})(exports.ZapProtocol || (exports.ZapProtocol = {}));

function encode(_ref) {
  var str = _ref.str,
      encoding = _ref.encoding;
  return Buffer.from(str, "binary").toString(encoding);
}

var toBN = function toBN(amount) {
  return new BigNumber__default(amount || "0");
};

var DefaultContext = {
  // Public API key provided by zapper.
  // see https://docs.zapper.fi/zapper-api/endpoints
  zapper: "96e0cc51-a62e-42ca-acee-910ea7d2a241",
  // The default tenderly dashboard for Yearn
  simulation: {
    dashboardUrl: "https://dashboard.tenderly.co/yearn/yearn-web"
  },
  cache: {
    useCache: true,
    url: "https://cache.yearn.finance"
  }
};
/**
 * [[Context]] is the configuration object passed around every function in
 * the SDK. It contains basic information on how to access the various services
 * that the SDK aggregates.
 *
 * [[Context]] **should not** be instantiated by users, as it's managed by
 * {@link Yearn.context}.
 */

var Context = /*#__PURE__*/function () {
  function Context(ctx) {
    this.ctx = Object.assign({}, DefaultContext, ctx);
    this.events = new EventEmitter().setMaxListeners(100);
    this.setProvider(ctx.provider);
  }
  /**
   * Change providers during executions for all services that require on-chain
   * interaction.
   * @param provider new provider(s)
   */


  var _proto = Context.prototype;

  _proto.setProvider = function setProvider(provider) {
    if (provider instanceof providers.JsonRpcProvider) {
      this.ctx.provider = {
        read: provider,
        write: provider
      };
    } else if (provider) {
      this.ctx.provider = provider;
    }

    this.events.emit(Context.PROVIDER, this.ctx.provider);
  };

  _createClass(Context, [{
    key: "provider",
    get: function get() {
      if (this.ctx.provider) return this.ctx.provider;
      throw new SdkError("provider must be undefined in Context for this feature to work.");
    }
  }, {
    key: "zapper",
    get: function get() {
      if (this.ctx.zapper) return encode({
        str: this.ctx.zapper + ":",
        encoding: "base64"
      });
      throw new SdkError("zapper must be undefined in Context for this feature to work.");
    }
  }, {
    key: "etherscan",
    get: function get() {
      if (this.ctx.etherscan) return this.ctx.etherscan;
      throw new SdkError("etherscan must be undefined in Context for this feature to work.");
    }
  }, {
    key: "addresses",
    get: function get() {
      return Object.assign({
        adapters: {}
      }, this.ctx.addresses);
    },
    set: function set(addresses) {
      this.ctx.addresses = addresses;
    }
  }, {
    key: "simulation",
    get: function get() {
      if (this.ctx.simulation) return this.ctx.simulation;
      throw new SdkError("simulation configuration must be defined in Context for this feature to work.");
    }
  }, {
    key: "cache",
    get: function get() {
      if (this.ctx.cache) return this.ctx.cache;
      throw new SdkError("cache must be defined in Context for this feature to work.");
    }
  }, {
    key: "subgraph",
    get: function get() {
      return this.ctx.subgraph;
    }
  }, {
    key: "partnerId",
    get: function get() {
      return this.ctx.partnerId;
    }
  }, {
    key: "locale",
    get: function get() {
      return this.ctx.locale || "en";
    }
  }]);

  return Context;
}();
Context.PROVIDER = "refresh:provider";

function createCommonjsModule(fn, module) {
	return module = { exports: {} }, fn(module, module.exports), module.exports;
}

var runtime_1 = createCommonjsModule(function (module) {
/**
 * Copyright (c) 2014-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

var runtime = (function (exports) {

  var Op = Object.prototype;
  var hasOwn = Op.hasOwnProperty;
  var undefined$1; // More compressible than void 0.
  var $Symbol = typeof Symbol === "function" ? Symbol : {};
  var iteratorSymbol = $Symbol.iterator || "@@iterator";
  var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
  var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

  function define(obj, key, value) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
    return obj[key];
  }
  try {
    // IE 8 has a broken Object.defineProperty that only works on DOM objects.
    define({}, "");
  } catch (err) {
    define = function(obj, key, value) {
      return obj[key] = value;
    };
  }

  function wrap(innerFn, outerFn, self, tryLocsList) {
    // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
    var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
    var generator = Object.create(protoGenerator.prototype);
    var context = new Context(tryLocsList || []);

    // The ._invoke method unifies the implementations of the .next,
    // .throw, and .return methods.
    generator._invoke = makeInvokeMethod(innerFn, self, context);

    return generator;
  }
  exports.wrap = wrap;

  // Try/catch helper to minimize deoptimizations. Returns a completion
  // record like context.tryEntries[i].completion. This interface could
  // have been (and was previously) designed to take a closure to be
  // invoked without arguments, but in all the cases we care about we
  // already have an existing method we want to call, so there's no need
  // to create a new function object. We can even get away with assuming
  // the method takes exactly one argument, since that happens to be true
  // in every case, so we don't have to touch the arguments object. The
  // only additional allocation required is the completion record, which
  // has a stable shape and so hopefully should be cheap to allocate.
  function tryCatch(fn, obj, arg) {
    try {
      return { type: "normal", arg: fn.call(obj, arg) };
    } catch (err) {
      return { type: "throw", arg: err };
    }
  }

  var GenStateSuspendedStart = "suspendedStart";
  var GenStateSuspendedYield = "suspendedYield";
  var GenStateExecuting = "executing";
  var GenStateCompleted = "completed";

  // Returning this object from the innerFn has the same effect as
  // breaking out of the dispatch switch statement.
  var ContinueSentinel = {};

  // Dummy constructor functions that we use as the .constructor and
  // .constructor.prototype properties for functions that return Generator
  // objects. For full spec compliance, you may wish to configure your
  // minifier not to mangle the names of these two functions.
  function Generator() {}
  function GeneratorFunction() {}
  function GeneratorFunctionPrototype() {}

  // This is a polyfill for %IteratorPrototype% for environments that
  // don't natively support it.
  var IteratorPrototype = {};
  define(IteratorPrototype, iteratorSymbol, function () {
    return this;
  });

  var getProto = Object.getPrototypeOf;
  var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  if (NativeIteratorPrototype &&
      NativeIteratorPrototype !== Op &&
      hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
    // This environment has a native %IteratorPrototype%; use it instead
    // of the polyfill.
    IteratorPrototype = NativeIteratorPrototype;
  }

  var Gp = GeneratorFunctionPrototype.prototype =
    Generator.prototype = Object.create(IteratorPrototype);
  GeneratorFunction.prototype = GeneratorFunctionPrototype;
  define(Gp, "constructor", GeneratorFunctionPrototype);
  define(GeneratorFunctionPrototype, "constructor", GeneratorFunction);
  GeneratorFunction.displayName = define(
    GeneratorFunctionPrototype,
    toStringTagSymbol,
    "GeneratorFunction"
  );

  // Helper for defining the .next, .throw, and .return methods of the
  // Iterator interface in terms of a single ._invoke method.
  function defineIteratorMethods(prototype) {
    ["next", "throw", "return"].forEach(function(method) {
      define(prototype, method, function(arg) {
        return this._invoke(method, arg);
      });
    });
  }

  exports.isGeneratorFunction = function(genFun) {
    var ctor = typeof genFun === "function" && genFun.constructor;
    return ctor
      ? ctor === GeneratorFunction ||
        // For the native GeneratorFunction constructor, the best we can
        // do is to check its .name property.
        (ctor.displayName || ctor.name) === "GeneratorFunction"
      : false;
  };

  exports.mark = function(genFun) {
    if (Object.setPrototypeOf) {
      Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
    } else {
      genFun.__proto__ = GeneratorFunctionPrototype;
      define(genFun, toStringTagSymbol, "GeneratorFunction");
    }
    genFun.prototype = Object.create(Gp);
    return genFun;
  };

  // Within the body of any async function, `await x` is transformed to
  // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
  // `hasOwn.call(value, "__await")` to determine if the yielded value is
  // meant to be awaited.
  exports.awrap = function(arg) {
    return { __await: arg };
  };

  function AsyncIterator(generator, PromiseImpl) {
    function invoke(method, arg, resolve, reject) {
      var record = tryCatch(generator[method], generator, arg);
      if (record.type === "throw") {
        reject(record.arg);
      } else {
        var result = record.arg;
        var value = result.value;
        if (value &&
            typeof value === "object" &&
            hasOwn.call(value, "__await")) {
          return PromiseImpl.resolve(value.__await).then(function(value) {
            invoke("next", value, resolve, reject);
          }, function(err) {
            invoke("throw", err, resolve, reject);
          });
        }

        return PromiseImpl.resolve(value).then(function(unwrapped) {
          // When a yielded Promise is resolved, its final value becomes
          // the .value of the Promise<{value,done}> result for the
          // current iteration.
          result.value = unwrapped;
          resolve(result);
        }, function(error) {
          // If a rejected Promise was yielded, throw the rejection back
          // into the async generator function so it can be handled there.
          return invoke("throw", error, resolve, reject);
        });
      }
    }

    var previousPromise;

    function enqueue(method, arg) {
      function callInvokeWithMethodAndArg() {
        return new PromiseImpl(function(resolve, reject) {
          invoke(method, arg, resolve, reject);
        });
      }

      return previousPromise =
        // If enqueue has been called before, then we want to wait until
        // all previous Promises have been resolved before calling invoke,
        // so that results are always delivered in the correct order. If
        // enqueue has not been called before, then it is important to
        // call invoke immediately, without waiting on a callback to fire,
        // so that the async generator function has the opportunity to do
        // any necessary setup in a predictable way. This predictability
        // is why the Promise constructor synchronously invokes its
        // executor callback, and why async functions synchronously
        // execute code before the first await. Since we implement simple
        // async functions in terms of async generators, it is especially
        // important to get this right, even though it requires care.
        previousPromise ? previousPromise.then(
          callInvokeWithMethodAndArg,
          // Avoid propagating failures to Promises returned by later
          // invocations of the iterator.
          callInvokeWithMethodAndArg
        ) : callInvokeWithMethodAndArg();
    }

    // Define the unified helper method that is used to implement .next,
    // .throw, and .return (see defineIteratorMethods).
    this._invoke = enqueue;
  }

  defineIteratorMethods(AsyncIterator.prototype);
  define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
    return this;
  });
  exports.AsyncIterator = AsyncIterator;

  // Note that simple async functions are implemented on top of
  // AsyncIterator objects; they just return a Promise for the value of
  // the final result produced by the iterator.
  exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
    if (PromiseImpl === void 0) PromiseImpl = Promise;

    var iter = new AsyncIterator(
      wrap(innerFn, outerFn, self, tryLocsList),
      PromiseImpl
    );

    return exports.isGeneratorFunction(outerFn)
      ? iter // If outerFn is a generator, return the full iterator.
      : iter.next().then(function(result) {
          return result.done ? result.value : iter.next();
        });
  };

  function makeInvokeMethod(innerFn, self, context) {
    var state = GenStateSuspendedStart;

    return function invoke(method, arg) {
      if (state === GenStateExecuting) {
        throw new Error("Generator is already running");
      }

      if (state === GenStateCompleted) {
        if (method === "throw") {
          throw arg;
        }

        // Be forgiving, per 25.3.3.3.3 of the spec:
        // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
        return doneResult();
      }

      context.method = method;
      context.arg = arg;

      while (true) {
        var delegate = context.delegate;
        if (delegate) {
          var delegateResult = maybeInvokeDelegate(delegate, context);
          if (delegateResult) {
            if (delegateResult === ContinueSentinel) continue;
            return delegateResult;
          }
        }

        if (context.method === "next") {
          // Setting context._sent for legacy support of Babel's
          // function.sent implementation.
          context.sent = context._sent = context.arg;

        } else if (context.method === "throw") {
          if (state === GenStateSuspendedStart) {
            state = GenStateCompleted;
            throw context.arg;
          }

          context.dispatchException(context.arg);

        } else if (context.method === "return") {
          context.abrupt("return", context.arg);
        }

        state = GenStateExecuting;

        var record = tryCatch(innerFn, self, context);
        if (record.type === "normal") {
          // If an exception is thrown from innerFn, we leave state ===
          // GenStateExecuting and loop back for another invocation.
          state = context.done
            ? GenStateCompleted
            : GenStateSuspendedYield;

          if (record.arg === ContinueSentinel) {
            continue;
          }

          return {
            value: record.arg,
            done: context.done
          };

        } else if (record.type === "throw") {
          state = GenStateCompleted;
          // Dispatch the exception by looping back around to the
          // context.dispatchException(context.arg) call above.
          context.method = "throw";
          context.arg = record.arg;
        }
      }
    };
  }

  // Call delegate.iterator[context.method](context.arg) and handle the
  // result, either by returning a { value, done } result from the
  // delegate iterator, or by modifying context.method and context.arg,
  // setting context.delegate to null, and returning the ContinueSentinel.
  function maybeInvokeDelegate(delegate, context) {
    var method = delegate.iterator[context.method];
    if (method === undefined$1) {
      // A .throw or .return when the delegate iterator has no .throw
      // method always terminates the yield* loop.
      context.delegate = null;

      if (context.method === "throw") {
        // Note: ["return"] must be used for ES3 parsing compatibility.
        if (delegate.iterator["return"]) {
          // If the delegate iterator has a return method, give it a
          // chance to clean up.
          context.method = "return";
          context.arg = undefined$1;
          maybeInvokeDelegate(delegate, context);

          if (context.method === "throw") {
            // If maybeInvokeDelegate(context) changed context.method from
            // "return" to "throw", let that override the TypeError below.
            return ContinueSentinel;
          }
        }

        context.method = "throw";
        context.arg = new TypeError(
          "The iterator does not provide a 'throw' method");
      }

      return ContinueSentinel;
    }

    var record = tryCatch(method, delegate.iterator, context.arg);

    if (record.type === "throw") {
      context.method = "throw";
      context.arg = record.arg;
      context.delegate = null;
      return ContinueSentinel;
    }

    var info = record.arg;

    if (! info) {
      context.method = "throw";
      context.arg = new TypeError("iterator result is not an object");
      context.delegate = null;
      return ContinueSentinel;
    }

    if (info.done) {
      // Assign the result of the finished delegate to the temporary
      // variable specified by delegate.resultName (see delegateYield).
      context[delegate.resultName] = info.value;

      // Resume execution at the desired location (see delegateYield).
      context.next = delegate.nextLoc;

      // If context.method was "throw" but the delegate handled the
      // exception, let the outer generator proceed normally. If
      // context.method was "next", forget context.arg since it has been
      // "consumed" by the delegate iterator. If context.method was
      // "return", allow the original .return call to continue in the
      // outer generator.
      if (context.method !== "return") {
        context.method = "next";
        context.arg = undefined$1;
      }

    } else {
      // Re-yield the result returned by the delegate method.
      return info;
    }

    // The delegate iterator is finished, so forget it and continue with
    // the outer generator.
    context.delegate = null;
    return ContinueSentinel;
  }

  // Define Generator.prototype.{next,throw,return} in terms of the
  // unified ._invoke helper method.
  defineIteratorMethods(Gp);

  define(Gp, toStringTagSymbol, "Generator");

  // A Generator should always return itself as the iterator object when the
  // @@iterator function is called on it. Some browsers' implementations of the
  // iterator prototype chain incorrectly implement this, causing the Generator
  // object to not be returned from this call. This ensures that doesn't happen.
  // See https://github.com/facebook/regenerator/issues/274 for more details.
  define(Gp, iteratorSymbol, function() {
    return this;
  });

  define(Gp, "toString", function() {
    return "[object Generator]";
  });

  function pushTryEntry(locs) {
    var entry = { tryLoc: locs[0] };

    if (1 in locs) {
      entry.catchLoc = locs[1];
    }

    if (2 in locs) {
      entry.finallyLoc = locs[2];
      entry.afterLoc = locs[3];
    }

    this.tryEntries.push(entry);
  }

  function resetTryEntry(entry) {
    var record = entry.completion || {};
    record.type = "normal";
    delete record.arg;
    entry.completion = record;
  }

  function Context(tryLocsList) {
    // The root entry object (effectively a try statement without a catch
    // or a finally block) gives us a place to store values thrown from
    // locations where there is no enclosing try statement.
    this.tryEntries = [{ tryLoc: "root" }];
    tryLocsList.forEach(pushTryEntry, this);
    this.reset(true);
  }

  exports.keys = function(object) {
    var keys = [];
    for (var key in object) {
      keys.push(key);
    }
    keys.reverse();

    // Rather than returning an object with a next method, we keep
    // things simple and return the next function itself.
    return function next() {
      while (keys.length) {
        var key = keys.pop();
        if (key in object) {
          next.value = key;
          next.done = false;
          return next;
        }
      }

      // To avoid creating an additional object, we just hang the .value
      // and .done properties off the next function object itself. This
      // also ensures that the minifier will not anonymize the function.
      next.done = true;
      return next;
    };
  };

  function values(iterable) {
    if (iterable) {
      var iteratorMethod = iterable[iteratorSymbol];
      if (iteratorMethod) {
        return iteratorMethod.call(iterable);
      }

      if (typeof iterable.next === "function") {
        return iterable;
      }

      if (!isNaN(iterable.length)) {
        var i = -1, next = function next() {
          while (++i < iterable.length) {
            if (hasOwn.call(iterable, i)) {
              next.value = iterable[i];
              next.done = false;
              return next;
            }
          }

          next.value = undefined$1;
          next.done = true;

          return next;
        };

        return next.next = next;
      }
    }

    // Return an iterator with no values.
    return { next: doneResult };
  }
  exports.values = values;

  function doneResult() {
    return { value: undefined$1, done: true };
  }

  Context.prototype = {
    constructor: Context,

    reset: function(skipTempReset) {
      this.prev = 0;
      this.next = 0;
      // Resetting context._sent for legacy support of Babel's
      // function.sent implementation.
      this.sent = this._sent = undefined$1;
      this.done = false;
      this.delegate = null;

      this.method = "next";
      this.arg = undefined$1;

      this.tryEntries.forEach(resetTryEntry);

      if (!skipTempReset) {
        for (var name in this) {
          // Not sure about the optimal order of these conditions:
          if (name.charAt(0) === "t" &&
              hasOwn.call(this, name) &&
              !isNaN(+name.slice(1))) {
            this[name] = undefined$1;
          }
        }
      }
    },

    stop: function() {
      this.done = true;

      var rootEntry = this.tryEntries[0];
      var rootRecord = rootEntry.completion;
      if (rootRecord.type === "throw") {
        throw rootRecord.arg;
      }

      return this.rval;
    },

    dispatchException: function(exception) {
      if (this.done) {
        throw exception;
      }

      var context = this;
      function handle(loc, caught) {
        record.type = "throw";
        record.arg = exception;
        context.next = loc;

        if (caught) {
          // If the dispatched exception was caught by a catch block,
          // then let that catch block handle the exception normally.
          context.method = "next";
          context.arg = undefined$1;
        }

        return !! caught;
      }

      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        var record = entry.completion;

        if (entry.tryLoc === "root") {
          // Exception thrown outside of any try block that could handle
          // it, so set the completion value of the entire function to
          // throw the exception.
          return handle("end");
        }

        if (entry.tryLoc <= this.prev) {
          var hasCatch = hasOwn.call(entry, "catchLoc");
          var hasFinally = hasOwn.call(entry, "finallyLoc");

          if (hasCatch && hasFinally) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            } else if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else if (hasCatch) {
            if (this.prev < entry.catchLoc) {
              return handle(entry.catchLoc, true);
            }

          } else if (hasFinally) {
            if (this.prev < entry.finallyLoc) {
              return handle(entry.finallyLoc);
            }

          } else {
            throw new Error("try statement without catch or finally");
          }
        }
      }
    },

    abrupt: function(type, arg) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc <= this.prev &&
            hasOwn.call(entry, "finallyLoc") &&
            this.prev < entry.finallyLoc) {
          var finallyEntry = entry;
          break;
        }
      }

      if (finallyEntry &&
          (type === "break" ||
           type === "continue") &&
          finallyEntry.tryLoc <= arg &&
          arg <= finallyEntry.finallyLoc) {
        // Ignore the finally entry if control is not jumping to a
        // location outside the try/catch block.
        finallyEntry = null;
      }

      var record = finallyEntry ? finallyEntry.completion : {};
      record.type = type;
      record.arg = arg;

      if (finallyEntry) {
        this.method = "next";
        this.next = finallyEntry.finallyLoc;
        return ContinueSentinel;
      }

      return this.complete(record);
    },

    complete: function(record, afterLoc) {
      if (record.type === "throw") {
        throw record.arg;
      }

      if (record.type === "break" ||
          record.type === "continue") {
        this.next = record.arg;
      } else if (record.type === "return") {
        this.rval = this.arg = record.arg;
        this.method = "return";
        this.next = "end";
      } else if (record.type === "normal" && afterLoc) {
        this.next = afterLoc;
      }

      return ContinueSentinel;
    },

    finish: function(finallyLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.finallyLoc === finallyLoc) {
          this.complete(entry.completion, entry.afterLoc);
          resetTryEntry(entry);
          return ContinueSentinel;
        }
      }
    },

    "catch": function(tryLoc) {
      for (var i = this.tryEntries.length - 1; i >= 0; --i) {
        var entry = this.tryEntries[i];
        if (entry.tryLoc === tryLoc) {
          var record = entry.completion;
          if (record.type === "throw") {
            var thrown = record.arg;
            resetTryEntry(entry);
          }
          return thrown;
        }
      }

      // The context.catch method must only be called with a location
      // argument that corresponds to a known catch block.
      throw new Error("illegal catch attempt");
    },

    delegateYield: function(iterable, resultName, nextLoc) {
      this.delegate = {
        iterator: values(iterable),
        resultName: resultName,
        nextLoc: nextLoc
      };

      if (this.method === "next") {
        // Deliberately forget the last sent value so that we don't
        // accidentally pass it on to the delegate.
        this.arg = undefined$1;
      }

      return ContinueSentinel;
    }
  };

  // Regardless of whether this script is executing as a CommonJS module
  // or not, return the runtime object so that we can declare the variable
  // regeneratorRuntime in the outer scope, which allows this module to be
  // injected easily by `bin/regenerator --include-runtime script.js`.
  return exports;

}(
  // If this script is executing as a CommonJS module, use module.exports
  // as the regeneratorRuntime namespace. Otherwise create a new empty
  // object. Either way, the resulting object will be used to initialize
  // the regeneratorRuntime variable at the top of this file.
   module.exports 
));

try {
  regeneratorRuntime = runtime;
} catch (accidentalStrictMode) {
  // This module should not be running in strict mode, so the above
  // assignment should always work unless something is misconfigured. Just
  // in case runtime.js accidentally runs in strict mode, in modern engines
  // we can explicitly access globalThis. In older engines we can escape
  // strict mode using a global Function call. This could conceivably fail
  // if a Content Security Policy forbids using Function, but in that case
  // the proper solution is to fix the accidental strict mode problem. If
  // you've misconfigured your bundler to force strict mode and applied a
  // CSP to forbid Function, and you're not willing to fix either of those
  // problems, please detail your unique predicament in a GitHub issue.
  if (typeof globalThis === "object") {
    globalThis.regeneratorRuntime = runtime;
  } else {
    Function("r", "regeneratorRuntime = r")(runtime);
  }
}
});

var CachedFetcher = /*#__PURE__*/function () {
  function CachedFetcher(path, ctx, chainId) {
    this.path = path;
    this.ctx = ctx;
    this.chainId = chainId;
  }

  var _proto = CachedFetcher.prototype;

  _proto.fetch = /*#__PURE__*/function () {
    var _fetch = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(queryParameters) {
      var _call$headers$get;

      var cached, path, call, timeout, _call, url, status, statusText, json, maxAgeMatches, maxAge, now;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!(!this.ctx.cache.useCache || !this.ctx.cache.url)) {
                _context.next = 2;
                break;
              }

              return _context.abrupt("return", undefined);

            case 2:
              cached = this.currentValue;

              if (!cached) {
                _context.next = 5;
                break;
              }

              return _context.abrupt("return", cached);

            case 5:
              path = this.ctx.cache.url + "/v1/chains/" + this.chainId + "/" + this.path;

              if (queryParameters) {
                path += "?" + queryParameters;
              }

              _context.prev = 7;
              timeout = 5000;
              _context.next = 11;
              return this.fetchWithTimeout(path, timeout);

            case 11:
              call = _context.sent;
              _context.next = 18;
              break;

            case 14:
              _context.prev = 14;
              _context.t0 = _context["catch"](7);
              console.warn("Call to cache at " + path + " timed out");
              return _context.abrupt("return", undefined);

            case 18:
              if (!(call.status !== 200)) {
                _context.next = 22;
                break;
              }

              _call = call, url = _call.url, status = _call.status, statusText = _call.statusText;
              console.warn("Call to cache failed at " + url + " (status " + status + " " + statusText + ")");
              return _context.abrupt("return", undefined);

            case 22:
              _context.next = 24;
              return call.json();

            case 24:
              json = _context.sent;

              if (json) {
                _context.next = 27;
                break;
              }

              return _context.abrupt("return", undefined);

            case 27:
              maxAgeMatches = (_call$headers$get = call.headers.get("cache-control")) == null ? void 0 : _call$headers$get.match(/max-age=(\d+)/);
              maxAge = maxAgeMatches ? parseInt(maxAgeMatches[1], 10) : 30;
              now = new Date().getTime();
              this.expiryDate = new Date(now + maxAge * 1000);
              this.cachedValue = json;
              return _context.abrupt("return", json);

            case 33:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this, [[7, 14]]);
    }));

    function fetch(_x) {
      return _fetch.apply(this, arguments);
    }

    return fetch;
  }();

  _proto.fetchWithTimeout = /*#__PURE__*/function () {
    var _fetchWithTimeout = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(url, timeout) {
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              return _context2.abrupt("return", Promise.race([fetch(url), new Promise(function (_, reject) {
                return setTimeout(function () {
                  return reject("timeout");
                }, timeout);
              })]));

            case 1:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2);
    }));

    function fetchWithTimeout(_x2, _x3) {
      return _fetchWithTimeout.apply(this, arguments);
    }

    return fetchWithTimeout;
  }();

  _createClass(CachedFetcher, [{
    key: "currentValue",
    get: function get() {
      if (!this.expiryDate) {
        return undefined;
      }

      var now = new Date();

      if (now < this.expiryDate && this.cachedValue) {
        return this.cachedValue;
      }

      return undefined;
    }
  }]);

  return CachedFetcher;
}();

var Service = function Service(chainId, ctx) {
  this.chainId = chainId;
  this.ctx = ctx;
  this.events = new Emittery();
};
var ServiceInterface = /*#__PURE__*/function (_Service) {
  _inheritsLoose(ServiceInterface, _Service);

  function ServiceInterface(yearn, chainId, ctx) {
    var _this;

    _this = _Service.call(this, chainId, ctx) || this;
    _this.yearn = yearn;
    return _this;
  }

  return ServiceInterface;
}(Service);
/**
 * Contract that supports two different providers to differentiate read and
 * write operations.
 */

var WrappedContract = function WrappedContract(address, abi, ctx) {
  var _this2 = this;

  this.address = address;
  this.abi = abi;
  this.read = new contracts.Contract(address, abi, ctx.provider.read);
  this.write = new contracts.Contract(address, abi, ctx.provider.write);
  ctx.events.on(Context.PROVIDER, function (provider) {
    _this2.read = new contracts.Contract(_this2.address, _this2.abi, provider.read);
    _this2.write = new contracts.Contract(_this2.address, _this2.abi, provider.write);
  });
};
var ContractAddressId;

(function (ContractAddressId) {
  ContractAddressId["oracle"] = "ORACLE";
  ContractAddressId["adapter_ironbank"] = "REGISTRY_ADAPTER_IRON_BANK";
  ContractAddressId["adapter_registry_v2"] = "REGISTRY_ADAPTER_V2_VAULTS";
  ContractAddressId["helper"] = "HELPER";
  ContractAddressId["allowlist"] = "ALLOW_LIST_REGISTRY";
  ContractAddressId["partner"] = "PARTNER_TRACKER";
  ContractAddressId["zapperZapIn"] = "ZAPPER_ZAP_IN";
  ContractAddressId["zapperZapOut"] = "ZAPPER_ZAP_OUT";
  ContractAddressId["pickleZapIn"] = "PICKLE_ZAP_IN";
  ContractAddressId["unused"] = "UNUSED";
})(ContractAddressId || (ContractAddressId = {}));
/**
 * A service that has a contract representation on chain.
 */


var ContractService = /*#__PURE__*/function (_Service2) {
  _inheritsLoose(ContractService, _Service2);

  function ContractService(chainId, ctx, addressProvider) {
    var _this3;

    _this3 = _Service2.call(this, chainId, ctx) || this;
    _this3.addressProvider = addressProvider;
    return _this3;
  }

  var _proto = ContractService.prototype;

  _proto._getContract = /*#__PURE__*/function () {
    var _getContract2 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(abi, contractId, ctx) {
      var address;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (!(contractId === ContractAddressId.unused)) {
                _context.next = 2;
                break;
              }

              throw new Error("Trying to get the contract instance on the generic class.");

            case 2:
              _context.prev = 2;
              _context.next = 5;
              return this.addressProvider.addressById(contractId);

            case 5:
              address = _context.sent;
              return _context.abrupt("return", new WrappedContract(address, abi, ctx));

            case 9:
              _context.prev = 9;
              _context.t0 = _context["catch"](2);
              console.error("Contract address for " + contractId + " is missing from the Address Provider");
              throw _context.t0;

            case 13:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this, [[2, 9]]);
    }));

    function _getContract(_x, _x2, _x3) {
      return _getContract2.apply(this, arguments);
    }

    return _getContract;
  }();

  return ContractService;
}(Service);
ContractService.abi = [];
ContractService.contractId = ContractAddressId.unused;

var ZeroAddress = "0x0000000000000000000000000000000000000000";
var EthAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
var WethAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2";
var WrappedFantomAddress = "0x21be370D5312f44cB42ce377BC9b8a0cEF1A4C83";
var SUPPORTED_ZAP_OUT_ADDRESSES_MAINNET = {
  ETH: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
  DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
  USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
  WBTC: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
};
var FANTOM_TOKEN = {
  address: ZeroAddress,
  name: "Fantom",
  dataSource: "sdk",
  decimals: "18",
  priceUsdc: "0",
  supported: {
    ftmApeZap: true
  },
  symbol: "FTM"
};
var ETH_TOKEN = {
  address: EthAddress,
  name: "ETH",
  dataSource: "sdk",
  decimals: "18",
  priceUsdc: "0",
  supported: {
    zapper: true
  },
  symbol: "ETH"
};

function isNativeToken(address) {
  return [EthAddress, ZeroAddress].includes(address);
} // handle a non-200 `fetch` response.

function handleHttpError(_x) {
  return _handleHttpError.apply(this, arguments);
} // formally convert USD values to USDC values (* 1e6), using Usdc type alias.

function _handleHttpError() {
  _handleHttpError = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(response) {
    var url, status, statusText;
    return runtime_1.wrap(function _callee$(_context) {
      while (1) {
        switch (_context.prev = _context.next) {
          case 0:
            if (!(response.status !== 200)) {
              _context.next = 3;
              break;
            }

            url = response.url, status = response.status, statusText = response.statusText;
            throw new SdkError("HTTP to " + url + " request failed (status " + status + " " + statusText + ")");

          case 3:
            return _context.abrupt("return", response);

          case 4:
          case "end":
            return _context.stop();
        }
      }
    }, _callee);
  }));
  return _handleHttpError.apply(this, arguments);
}

function usdc(usd) {
  return bignumber.BigNumber.from(Math.floor(Number(usd) * 1e6)).toString();
} // formally convert BigNumber to Integer type alias.

function _int(value) {
  return value.toString();
}
function chunkArray(array, size) {
  if (size < 1) {
    throw new Error("Size needs to be positive: " + size);
  }

  var result = [];

  for (var i = 0; i < array.length; i += size) {
    var chunk = array.slice(i, i + size);
    result.push(chunk);
  }

  return result;
} // converts timestamps from second and microsecond format to milliseconds

function convertSecondsMillisOrMicrosToMillis(timestamp) {
  var testSeconds = /^\d{10}$/;
  var testMillis = /^\d{13}$/;
  var testMicros = /^\d{16}$/;
  var input = typeof timestamp === "string" ? timestamp : timestamp.toString();
  input = input.padStart(10, "0"); // optional padding in case of a number input

  if (testMillis.test(input)) {
    return +timestamp;
  } else if (testMicros.test(input)) {
    return +timestamp / 1000;
  } else if (testSeconds.test(input)) {
    return +timestamp * 1000;
  } else {
    throw new Error("Timestamp in invalid format");
  }
}
/**
 * Merges array b into a by address removing a duplicates from b
 *
 * @param a higher priority array
 * @param b lower priority array
 *
 * @returns combined arrays by address without duplicates
 */

function mergeByAddress(a, b) {
  var filter = new Set(a.map(function (_ref) {
    var address = _ref.address;
    return address;
  }));
  return [].concat(a, b.filter(function (_ref2) {
    var address = _ref2.address;
    return !filter.has(address);
  }));
}

var YVBOOST = "0x9d409a0a012cfba9b15f6d4b36ac57a46966ab9a";
var YVECRV = "0xc5bddf9843308380375a611c18b50fb9341f502a";
var PSLPYVBOOSTETH = "0xced67a187b923f0e5ebcc77c7f2f7da20099e378";
var LAB_ADDRESSESS = [YVBOOST, YVECRV, PSLPYVBOOSTETH];
var VAULT_EARNINGS = "query VaultEarnings($vault: ID!) {\n    vault(id: $vault) {\n      token {\n        id\n        decimals\n      }\n      latestUpdate {\n        returnsGenerated\n      }\n    }\n  }\n";
var PROTOCOL_EARNINGS = "query ProtocolEarnings {\n    vaults {\n      token {\n        id\n        decimals\n      }\n      latestUpdate {\n        returnsGenerated\n      }\n    }\n  }\n";
var buildAccountEarningsVariables = function buildAccountEarningsVariables(id) {
  return {
    id: id,
    ignoredVaults: LAB_ADDRESSESS
  };
};
var ACCOUNT_EARNINGS = "\n  query AccountEarnings($id: ID!, $ignoredVaults: [String!]) {\n    account(id: $id) {\n      vaultPositions(where: { vault_not_in: $ignoredVaults } ) {\n        balanceShares\n        token {\n          id\n          decimals\n        }\n        shareToken {\n          symbol\n        }\n        updates {\n          deposits\n          withdrawals\n          tokensReceived\n          tokensSent\n        }\n        vault {\n          id\n          latestUpdate {\n            pricePerShare\n          }\n        }\n      }\n    }\n  }\n";
var ASSET_HISTORIC_EARNINGS = function ASSET_HISTORIC_EARNINGS(blocks) {
  var makeBlockQuery = function makeBlockQuery(block) {
    return "\n    block_" + block + ": vault(id: $id, block: { number: " + block + " } ) {\n      vaultDayData(orderBy: timestamp, orderDirection: desc, first: 1) {\n        timestamp\n      }\n      strategies {\n        latestReport {\n          totalGain\n          totalLoss\n        }\n      }\n    }\n    ";
  };

  var historicQueries = blocks.map(function (block) {
    return makeBlockQuery(block);
  });
  var result = "query AssetHistoricEarnings($id: ID!) {\n    vault(id: $id) {\n      token {\n        id\n        decimals\n      }\n    }\n    " + historicQueries.join("") + "\n  }\n  ";
  return result;
};
var ACCOUNT_HISTORIC_EARNINGS = "query AccountHistoricEarnings($id: ID!, $shareToken: String!, $fromDate: String!, $toDate: BigInt!) {\n  account(id: $id) {\n      vaultPositions(where: { shareToken: $shareToken }) {\n        balanceShares\n        token {\n          id\n          decimals\n        }\n        vault {\n          vaultDayData(where: { timestamp_gte: $fromDate, timestamp_lte: $toDate }, orderBy: timestamp, orderDirection: asc, first: 1000) {\n            pricePerShare\n            timestamp\n          }\n        }\n        updates(orderBy: timestamp, orderDirection: asc, first: 1000) {\n          balanceShares\n          timestamp\n          deposits\n          withdrawals\n          tokensReceived\n          tokensSent\n        }\n      }\n    }\n  }\n";
var PROTOCOL_FEES = "query ProtocolFees($sinceDate: BigInt!) {\n    transfers(where: { timestamp_gt: $sinceDate }, first: 1000) {\n      tokenAmountUsdc\n    }\n  }\n";

var BigZero = /*#__PURE__*/new BigNumber.BigNumber(0);
var EarningsInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(EarningsInterface, _ServiceInterface);

  function EarningsInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.assetHistoricEarningsCache = new CachedFetcher("vaults/earnings/get", _this.ctx, _this.chainId);
    return _this;
  }
  /**
   * @deprecated
   * Not able to be accurately calculated by the subgraph, this functionality will be removed in a future version
   */


  var _proto = EarningsInterface.prototype;

  _proto.protocolEarnings =
  /*#__PURE__*/
  function () {
    var _protocolEarnings = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
      var _response$data;

      var response, result, _iterator, _step, vault, returnsGenerated, earningsUsdc;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.yearn.services.subgraph.fetchQuery(PROTOCOL_EARNINGS);

            case 2:
              response = _context.sent;
              result = BigZero;

              if (!(!(response != null && response.data) || !((_response$data = response.data) != null && _response$data.vaults))) {
                _context.next = 6;
                break;
              }

              return _context.abrupt("return", result.toFixed(0));

            case 6:
              _iterator = _createForOfIteratorHelperLoose(response.data.vaults);

            case 7:
              if ((_step = _iterator()).done) {
                _context.next = 18;
                break;
              }

              vault = _step.value;

              if (vault.latestUpdate) {
                _context.next = 11;
                break;
              }

              return _context.abrupt("continue", 16);

            case 11:
              returnsGenerated = new BigNumber.BigNumber(vault.latestUpdate.returnsGenerated);
              _context.next = 14;
              return this.tokensValueInUsdc(returnsGenerated, vault.token.id, vault.token.decimals);

            case 14:
              earningsUsdc = _context.sent;
              result = result.plus(earningsUsdc);

            case 16:
              _context.next = 7;
              break;

            case 18:
              return _context.abrupt("return", result.toFixed(0));

            case 19:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function protocolEarnings() {
      return _protocolEarnings.apply(this, arguments);
    }

    return protocolEarnings;
  }();

  _proto.assetEarnings = /*#__PURE__*/function () {
    var _assetEarnings = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(assetAddress) {
      var _response$data2, _vault$latestUpdate;

      var response, vault, returnsGenerated, earningsUsdc;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.yearn.services.subgraph.fetchQuery(VAULT_EARNINGS, {
                vault: assetAddress
              });

            case 2:
              response = _context2.sent;

              if (!(!(response != null && response.data) || !((_response$data2 = response.data) != null && _response$data2.vault))) {
                _context2.next = 5;
                break;
              }

              throw new SdkError("No asset with address " + assetAddress);

            case 5:
              vault = response.data.vault;
              returnsGenerated = new BigNumber.BigNumber(((_vault$latestUpdate = vault.latestUpdate) == null ? void 0 : _vault$latestUpdate.returnsGenerated) || 0);
              _context2.next = 9;
              return this.tokensValueInUsdc(returnsGenerated, vault.token.id, vault.token.decimals);

            case 9:
              earningsUsdc = _context2.sent;
              return _context2.abrupt("return", {
                assetAddress: address.getAddress(assetAddress),
                amount: returnsGenerated.toFixed(0),
                amountUsdc: earningsUsdc.toFixed(0),
                tokenAddress: address.getAddress(vault.token.id)
              });

            case 11:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function assetEarnings(_x) {
      return _assetEarnings.apply(this, arguments);
    }

    return assetEarnings;
  }();

  _proto.accountAssetsData = /*#__PURE__*/function () {
    var _accountAssetsData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(accountAddress) {
      var _response$data3,
          _this2 = this;

      var response, account, assetsData, assetAddresses, apys, totalEarnings, holdings, grossApy, estimatedYearlyYield, earningsAssetData;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return this.yearn.services.subgraph.fetchQuery(ACCOUNT_EARNINGS, buildAccountEarningsVariables(accountAddress));

            case 2:
              response = _context4.sent;
              account = response == null ? void 0 : (_response$data3 = response.data) == null ? void 0 : _response$data3.account;

              if (account) {
                _context4.next = 6;
                break;
              }

              return _context4.abrupt("return", {
                earnings: "0",
                holdings: "0",
                earningsAssetData: [],
                grossApy: 0,
                estimatedYearlyYield: "0"
              });

            case 6:
              _context4.next = 8;
              return Promise.all(account.vaultPositions.map( /*#__PURE__*/function () {
                var _ref = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(assetPosition) {
                  var _assetPosition$vault$;

                  var balanceTokens, _assetPosition$update, deposits, withdrawals, tokensReceived, tokensSent, positiveTokens, negativeTokens, earningsTokens, earningsUsdc, balanceUsdc;

                  return runtime_1.wrap(function _callee3$(_context3) {
                    while (1) {
                      switch (_context3.prev = _context3.next) {
                        case 0:
                          balanceTokens = new BigNumber.BigNumber(assetPosition.balanceShares).multipliedBy(new BigNumber.BigNumber(((_assetPosition$vault$ = assetPosition.vault.latestUpdate) == null ? void 0 : _assetPosition$vault$.pricePerShare) || 0)).div(Math.pow(10, assetPosition.token.decimals));
                          _assetPosition$update = assetPosition.updates.reduce(function (_ref2, current) {
                            var deposits = _ref2.deposits,
                                withdrawals = _ref2.withdrawals,
                                tokensReceived = _ref2.tokensReceived,
                                tokensSent = _ref2.tokensSent;
                            return {
                              deposits: deposits.plus(new BigNumber.BigNumber(current.deposits)),
                              withdrawals: withdrawals.plus(new BigNumber.BigNumber(current.withdrawals)),
                              tokensReceived: tokensReceived.plus(new BigNumber.BigNumber(current.tokensReceived)),
                              tokensSent: tokensSent.plus(new BigNumber.BigNumber(current.tokensSent))
                            };
                          }, {
                            deposits: BigZero,
                            withdrawals: BigZero,
                            tokensReceived: BigZero,
                            tokensSent: BigZero
                          }), deposits = _assetPosition$update.deposits, withdrawals = _assetPosition$update.withdrawals, tokensReceived = _assetPosition$update.tokensReceived, tokensSent = _assetPosition$update.tokensSent;
                          positiveTokens = balanceTokens.plus(withdrawals).plus(tokensSent);
                          negativeTokens = deposits.plus(tokensReceived);
                          earningsTokens = positiveTokens.minus(negativeTokens);
                          _context3.next = 7;
                          return _this2.tokensValueInUsdc(earningsTokens, assetPosition.token.id, assetPosition.token.decimals);

                        case 7:
                          earningsUsdc = _context3.sent;
                          _context3.next = 10;
                          return _this2.tokensValueInUsdc(balanceTokens, assetPosition.token.id, assetPosition.token.decimals);

                        case 10:
                          balanceUsdc = _context3.sent;
                          return _context3.abrupt("return", {
                            assetAddress: address.getAddress(assetPosition.vault.id),
                            balanceUsdc: balanceUsdc,
                            earned: earningsUsdc.toFixed(0)
                          });

                        case 12:
                        case "end":
                          return _context3.stop();
                      }
                    }
                  }, _callee3);
                }));

                return function (_x3) {
                  return _ref.apply(this, arguments);
                };
              }()));

            case 8:
              assetsData = _context4.sent;
              assetAddresses = assetsData.map(function (assetData) {
                return assetData.assetAddress;
              });
              _context4.next = 12;
              return this.yearn.services.vision.apy(assetAddresses);

            case 12:
              apys = _context4.sent;
              totalEarnings = assetsData.map(function (datum) {
                return new BigNumber.BigNumber(datum.earned);
              }).reduce(function (sum, value) {
                return sum.plus(value);
              });
              holdings = assetsData.map(function (datum) {
                return new BigNumber.BigNumber(datum.balanceUsdc);
              }).reduce(function (sum, value) {
                return sum.plus(value);
              });
              grossApy = holdings.isEqualTo(BigZero) ? BigZero : assetsData.map(function (datum) {
                var _apys$datum$assetAddr, _apys$datum$assetAddr2;

                if (((_apys$datum$assetAddr = apys[datum.assetAddress]) == null ? void 0 : _apys$datum$assetAddr.type) === "new") {
                  return BigZero;
                }

                var apy = ((_apys$datum$assetAddr2 = apys[datum.assetAddress]) == null ? void 0 : _apys$datum$assetAddr2.net_apy) || 0;
                return new BigNumber.BigNumber(apy).times(datum.balanceUsdc).div(holdings);
              }).reduce(function (sum, value) {
                return sum.plus(value);
              });
              estimatedYearlyYield = grossApy.multipliedBy(holdings);
              earningsAssetData = assetsData.map(function (datum) {
                return {
                  assetAddress: datum.assetAddress,
                  earned: datum.earned
                };
              });
              return _context4.abrupt("return", {
                earnings: BigNumber.BigNumber.max(totalEarnings, 0).toFixed(0),
                holdings: BigNumber.BigNumber.max(holdings, 0).toFixed(0),
                grossApy: grossApy.toNumber(),
                estimatedYearlyYield: BigNumber.BigNumber.max(estimatedYearlyYield, 0).toFixed(0),
                earningsAssetData: earningsAssetData
              });

            case 19:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function accountAssetsData(_x2) {
      return _accountAssetsData.apply(this, arguments);
    }

    return accountAssetsData;
  }();

  _proto.assetsHistoricEarnings = /*#__PURE__*/function () {
    var _assetsHistoricEarnings = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(fromDaysAgo) {
      var _this3 = this;

      var cached, assetsStatic, assetAddresses, latestBlockNumber, resolvedPromises, result, _iterator2, _step2, resolvedPromise;

      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (fromDaysAgo === void 0) {
                fromDaysAgo = 30;
              }

              if (!(fromDaysAgo === 30)) {
                _context6.next = 7;
                break;
              }

              _context6.next = 4;
              return this.assetHistoricEarningsCache.fetch();

            case 4:
              cached = _context6.sent;

              if (!cached) {
                _context6.next = 7;
                break;
              }

              return _context6.abrupt("return", cached);

            case 7:
              _context6.next = 9;
              return this.yearn.services.lens.adapters.vaults.v2.assetsStatic();

            case 9:
              assetsStatic = _context6.sent;
              assetAddresses = assetsStatic.map(function (asset) {
                return asset.address;
              });
              _context6.next = 13;
              return this.ctx.provider.read.getBlockNumber();

            case 13:
              latestBlockNumber = _context6.sent;
              _context6.next = 16;
              return Promise.allSettled(assetAddresses.map( /*#__PURE__*/function () {
                var _ref3 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(address) {
                  return runtime_1.wrap(function _callee5$(_context5) {
                    while (1) {
                      switch (_context5.prev = _context5.next) {
                        case 0:
                          return _context5.abrupt("return", _this3.assetHistoricEarnings(address, fromDaysAgo, latestBlockNumber));

                        case 1:
                        case "end":
                          return _context5.stop();
                      }
                    }
                  }, _callee5);
                }));

                return function (_x5) {
                  return _ref3.apply(this, arguments);
                };
              }()));

            case 16:
              resolvedPromises = _context6.sent;
              result = [];

              for (_iterator2 = _createForOfIteratorHelperLoose(resolvedPromises); !(_step2 = _iterator2()).done;) {
                resolvedPromise = _step2.value;

                if (resolvedPromise.status === "fulfilled") {
                  result.push(resolvedPromise.value);
                }
              }

              return _context6.abrupt("return", result);

            case 20:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function assetsHistoricEarnings(_x4) {
      return _assetsHistoricEarnings.apply(this, arguments);
    }

    return assetsHistoricEarnings;
  }();

  _proto.assetHistoricEarnings = /*#__PURE__*/function () {
    var _assetHistoricEarnings = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(vault, fromDaysAgo, latestBlockNumber) {
      var _this4 = this;

      var blockNumber, blocks, _yield$this$yearn$ser, data, labels, token, priceUsdc, earningsDayData;

      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              if (!(latestBlockNumber != null)) {
                _context7.next = 4;
                break;
              }

              _context7.t0 = latestBlockNumber;
              _context7.next = 7;
              break;

            case 4:
              _context7.next = 6;
              return this.ctx.provider.read.getBlockNumber();

            case 6:
              _context7.t0 = _context7.sent;

            case 7:
              blockNumber = _context7.t0;
              blockNumber -= this.blockOffset(); // subgraph might be slightly behind latest block

              blocks = Array.from(Array(fromDaysAgo).keys()).reverse().map(function (day) {
                return blockNumber - day * _this4.blocksPerDay();
              }); // eslint-disable-next-line @typescript-eslint/no-explicit-any

              _context7.next = 12;
              return this.yearn.services.subgraph.fetchQuery(ASSET_HISTORIC_EARNINGS(blocks), {
                id: vault
              });

            case 12:
              _yield$this$yearn$ser = _context7.sent;
              data = _yield$this$yearn$ser.data;
              labels = blocks.map(function (block) {
                return "block_" + block;
              });
              token = data.vault.token.id;
              _context7.next = 18;
              return this.yearn.services.oracle.getPriceUsdc(token).then(function (price) {
                return new BigNumber.BigNumber(price);
              });

            case 18:
              priceUsdc = _context7.sent;
              earningsDayData = labels.map(function (label) {
                var strategies = data[label].strategies;

                var _strategies$reduce = strategies.reduce(function (_ref4, _ref5) {
                  var totalGain = _ref4.totalGain,
                      totalLoss = _ref4.totalLoss;
                  var latestReport = _ref5.latestReport;

                  if (latestReport) {
                    totalGain = totalGain.plus(toBN(latestReport.totalGain));
                    totalLoss = totalLoss.plus(toBN(latestReport.totalLoss));
                  }

                  return {
                    totalGain: totalGain,
                    totalLoss: totalLoss
                  };
                }, {
                  totalGain: toBN(0),
                  totalLoss: toBN(0)
                }),
                    totalGain = _strategies$reduce.totalGain,
                    totalLoss = _strategies$reduce.totalLoss;

                var amountEarnt = totalGain.minus(totalLoss);
                var amountUsdc = priceUsdc.multipliedBy(amountEarnt).dividedBy(toBN(10).pow(toBN(data.vault.token.decimals)));
                var dayData = {
                  earnings: {
                    amountUsdc: amountUsdc.toFixed(0),
                    amount: amountEarnt.toFixed(0)
                  },
                  date: new Date(convertSecondsMillisOrMicrosToMillis(data[label].vaultDayData[0].timestamp)).toJSON()
                };
                return dayData;
              });
              return _context7.abrupt("return", {
                assetAddress: vault,
                dayData: earningsDayData,
                decimals: data.vault.token.decimals
              });

            case 21:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function assetHistoricEarnings(_x6, _x7, _x8) {
      return _assetHistoricEarnings.apply(this, arguments);
    }

    return assetHistoricEarnings;
  }();

  _proto.accountHistoricEarnings = /*#__PURE__*/function () {
    var _accountHistoricEarnings = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(accountAddress, shareTokenAddress, fromDaysAgo, toDaysAgo) {
      var _response$data$accoun;

      var response, vaultPositions, snapshotTimeline, updates, _iterator3, _step3, _step3$value, index, vaultPositionUpdate, _snapshot, previousSnapshot, _snapshot2, lastSnapshot, distantFuture, snapshot, vaultDayData, token, usdcPrice, earningsDayData;

      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              if (!(toDaysAgo && toDaysAgo > fromDaysAgo)) {
                _context9.next = 2;
                break;
              }

              throw new SdkError("fromDaysAgo must be greater than toDaysAgo");

            case 2:
              _context9.next = 4;
              return this.yearn.services.subgraph.fetchQuery(ACCOUNT_HISTORIC_EARNINGS, {
                id: accountAddress,
                shareToken: shareTokenAddress,
                fromDate: this.getDate(fromDaysAgo).getTime().toString(),
                toDate: this.getDate(toDaysAgo || 0).getTime().toString()
              });

            case 4:
              response = _context9.sent;
              vaultPositions = (_response$data$accoun = response.data.account) == null ? void 0 : _response$data$accoun.vaultPositions;

              if (vaultPositions) {
                _context9.next = 8;
                break;
              }

              throw new SdkError("No account with address " + accountAddress);

            case 8:
              snapshotTimeline = [];
              updates = vaultPositions.flatMap(function (vaultPosition) {
                return vaultPosition.updates;
              }).sort(function (lhs, rhs) {
                return convertSecondsMillisOrMicrosToMillis(+lhs.timestamp - +rhs.timestamp);
              });

              for (_iterator3 = _createForOfIteratorHelperLoose(updates.entries()); !(_step3 = _iterator3()).done;) {
                _step3$value = _step3.value, index = _step3$value[0], vaultPositionUpdate = _step3$value[1];

                if (index === 0) {
                  _snapshot = {
                    startDate: new Date(0),
                    endDate: new Date(convertSecondsMillisOrMicrosToMillis(vaultPositionUpdate.timestamp)),
                    deposits: new BigNumber.BigNumber(vaultPositionUpdate.deposits),
                    withdrawals: new BigNumber.BigNumber(vaultPositionUpdate.withdrawals),
                    tokensReceived: new BigNumber.BigNumber(vaultPositionUpdate.tokensReceived),
                    tokensSent: new BigNumber.BigNumber(vaultPositionUpdate.tokensSent),
                    balanceShares: new BigNumber.BigNumber(vaultPositionUpdate.balanceShares)
                  };
                  snapshotTimeline.push(_snapshot);
                } else {
                  previousSnapshot = snapshotTimeline[index - 1];
                  _snapshot2 = {
                    startDate: previousSnapshot.endDate,
                    endDate: new Date(convertSecondsMillisOrMicrosToMillis(vaultPositionUpdate.timestamp)),
                    deposits: previousSnapshot.deposits.plus(new BigNumber.BigNumber(vaultPositionUpdate.deposits)),
                    withdrawals: previousSnapshot.withdrawals.plus(new BigNumber.BigNumber(vaultPositionUpdate.withdrawals)),
                    tokensReceived: previousSnapshot.tokensReceived.plus(new BigNumber.BigNumber(vaultPositionUpdate.tokensReceived)),
                    tokensSent: previousSnapshot.tokensSent.plus(new BigNumber.BigNumber(vaultPositionUpdate.tokensSent)),
                    balanceShares: previousSnapshot.balanceShares.plus(new BigNumber.BigNumber(vaultPositionUpdate.balanceShares))
                  };
                  snapshotTimeline.push(_snapshot2);
                }
              }

              if (snapshotTimeline.length > 0) {
                lastSnapshot = snapshotTimeline[snapshotTimeline.length - 1];
                distantFuture = new Date().setFullYear(3000);
                snapshot = {
                  startDate: lastSnapshot.endDate,
                  endDate: new Date(distantFuture),
                  deposits: lastSnapshot.deposits,
                  withdrawals: lastSnapshot.withdrawals,
                  tokensReceived: lastSnapshot.tokensReceived,
                  tokensSent: lastSnapshot.tokensSent,
                  balanceShares: lastSnapshot.balanceShares
                };
                snapshotTimeline.push(snapshot);
              }

              vaultDayData = vaultPositions[0].vault.vaultDayData;
              token = vaultPositions[0].token;
              _context9.next = 16;
              return this.yearn.services.oracle.getPriceUsdc(token.id).then(function (id) {
                return new BigNumber.BigNumber(id);
              });

            case 16:
              usdcPrice = _context9.sent;
              _context9.next = 19;
              return Promise.all(vaultDayData.map( /*#__PURE__*/function () {
                var _ref6 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(vaultDayDatum) {
                  var date, snapshot, balanceTokens, positives, negatives, earnings, amountUsdc;
                  return runtime_1.wrap(function _callee8$(_context8) {
                    while (1) {
                      switch (_context8.prev = _context8.next) {
                        case 0:
                          date = new Date(convertSecondsMillisOrMicrosToMillis(vaultDayDatum.timestamp));
                          snapshot = snapshotTimeline.find(function (snapshot) {
                            return date >= snapshot.startDate && date < snapshot.endDate;
                          });

                          if (!snapshot) {
                            _context8.next = 11;
                            break;
                          }

                          balanceTokens = snapshot.balanceShares.multipliedBy(new BigNumber.BigNumber(vaultDayDatum.pricePerShare)).dividedBy(new BigNumber.BigNumber(Math.pow(10, token.decimals)));
                          positives = balanceTokens.plus(snapshot.withdrawals).plus(snapshot.tokensSent);
                          negatives = snapshot.deposits.plus(snapshot.tokensReceived);
                          earnings = positives.minus(negatives);
                          amountUsdc = usdcPrice.multipliedBy(earnings).dividedBy(new BigNumber.BigNumber(10).pow(token.decimals));
                          return _context8.abrupt("return", {
                            earnings: {
                              amount: earnings.toFixed(0),
                              amountUsdc: amountUsdc.toFixed(0)
                            },
                            date: date.toJSON()
                          });

                        case 11:
                          return _context8.abrupt("return", {
                            earnings: {
                              amount: "0",
                              amountUsdc: "0"
                            },
                            date: date.toJSON()
                          });

                        case 12:
                        case "end":
                          return _context8.stop();
                      }
                    }
                  }, _callee8);
                }));

                return function (_x13) {
                  return _ref6.apply(this, arguments);
                };
              }()));

            case 19:
              earningsDayData = _context9.sent;
              return _context9.abrupt("return", {
                accountAddress: accountAddress,
                shareTokenAddress: shareTokenAddress,
                decimals: token.decimals,
                dayData: earningsDayData
              });

            case 21:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function accountHistoricEarnings(_x9, _x10, _x11, _x12) {
      return _accountHistoricEarnings.apply(this, arguments);
    }

    return accountHistoricEarnings;
  }();

  _proto.tokensValueInUsdc = /*#__PURE__*/function () {
    var _tokensValueInUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(tokenAmount, tokenAddress, decimals) {
      var tokenUsdcPrice;
      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              _context10.next = 2;
              return this.yearn.services.oracle.getPriceUsdc(tokenAddress);

            case 2:
              tokenUsdcPrice = _context10.sent;
              return _context10.abrupt("return", new BigNumber.BigNumber(tokenUsdcPrice).multipliedBy(tokenAmount).div(Math.pow(10, decimals)));

            case 4:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function tokensValueInUsdc(_x14, _x15, _x16) {
      return _tokensValueInUsdc.apply(this, arguments);
    }

    return tokensValueInUsdc;
  }();

  _proto.getDate = function getDate(daysAgo) {
    var date = new Date();
    date.setDate(date.getDate() - daysAgo);
    return date;
  };

  _proto.blocksPerDay = function blocksPerDay() {
    switch (this.chainId) {
      case 1:
      case 1337:
      case 42161:
        return 5760;

      case 250:
        return 86400;
    }
  };

  _proto.blockOffset = function blockOffset() {
    switch (this.chainId) {
      case 1:
      case 1337:
      case 42161:
        return 100;

      case 250:
        return 1000;
    }
  };

  return EarningsInterface;
}(ServiceInterface);

var FeesInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(FeesInterface, _ServiceInterface);

  function FeesInterface() {
    return _ServiceInterface.apply(this, arguments) || this;
  }

  var _proto = FeesInterface.prototype;

  _proto.protocolFees = /*#__PURE__*/function () {
    var _protocolFees = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(since) {
      var _response$data;

      var response, transfers;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.yearn.services.subgraph.fetchQuery(PROTOCOL_FEES, {
                sinceDate: since.getTime().toString()
              });

            case 2:
              response = _context.sent;

              if (!(!(response != null && response.data) || !((_response$data = response.data) != null && _response$data.transfers))) {
                _context.next = 5;
                break;
              }

              return _context.abrupt("return", toBN(0).toFixed(0));

            case 5:
              transfers = response.data.transfers;
              return _context.abrupt("return", transfers.reduce(function (prev, _ref) {
                var tokenAmountUsdc = _ref.tokenAmountUsdc;
                return prev.plus(toBN(tokenAmountUsdc || 0));
              }, toBN(0)).toFixed(0));

            case 7:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function protocolFees(_x) {
      return _protocolFees.apply(this, arguments);
    }

    return protocolFees;
  }();

  return FeesInterface;
}(ServiceInterface);

var IronBankInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(IronBankInterface, _ServiceInterface);

  function IronBankInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.cachedFetcherGet = new CachedFetcher("ironbank/get", _this.ctx, _this.chainId);
    _this.cachedFetcherGetDynamic = new CachedFetcher("ironbank/getDynamic", _this.ctx, _this.chainId);
    _this.cachedFetcherTokens = new CachedFetcher("ironbank/tokens", _this.ctx, _this.chainId);
    return _this;
  }
  /**
   * Get all IronBank markets.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */


  var _proto = IronBankInterface.prototype;

  _proto.get =
  /*#__PURE__*/
  function () {
    var _get = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses, overrides) {
      var cached, assetsStatic, assetsDynamic, assets, _loop, _iterator, _step;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.cachedFetcherGet.fetch();

            case 2:
              cached = _context.sent;

              if (!cached) {
                _context.next = 9;
                break;
              }

              if (!addresses) {
                _context.next = 8;
                break;
              }

              return _context.abrupt("return", cached.filter(function (market) {
                return addresses.includes(market.address);
              }));

            case 8:
              return _context.abrupt("return", cached);

            case 9:
              _context.next = 11;
              return this.yearn.services.lens.adapters.ironBank.assetsStatic(addresses, overrides);

            case 11:
              assetsStatic = _context.sent;
              _context.next = 14;
              return this.yearn.services.lens.adapters.ironBank.assetsDynamic(addresses, overrides);

            case 14:
              assetsDynamic = _context.sent;
              assets = new Array();

              _loop = function _loop() {
                var asset = _step.value;
                var dynamic = assetsDynamic.find(function (_ref) {
                  var address = _ref.address;
                  return asset.address === address;
                });

                if (!dynamic) {
                  throw new SdkError("Dynamic asset does not exist for " + asset.address);
                }

                assets.push(_extends({}, asset, dynamic));
              };

              for (_iterator = _createForOfIteratorHelperLoose(assetsStatic); !(_step = _iterator()).done;) {
                _loop();
              }

              return _context.abrupt("return", assets);

            case 19:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function get(_x, _x2) {
      return _get.apply(this, arguments);
    }

    return get;
  }()
  /**
   * Get static part of IronBank markets.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.getStatic =
  /*#__PURE__*/
  function () {
    var _getStatic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses, overrides) {
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.yearn.services.lens.adapters.ironBank.assetsStatic(addresses, overrides);

            case 2:
              return _context2.abrupt("return", _context2.sent);

            case 3:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function getStatic(_x3, _x4) {
      return _getStatic.apply(this, arguments);
    }

    return getStatic;
  }()
  /**
   * Get dynamic part of IronBank markets.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.getDynamic =
  /*#__PURE__*/
  function () {
    var _getDynamic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(addresses, overrides) {
      var cached;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return this.cachedFetcherGetDynamic.fetch();

            case 2:
              cached = _context3.sent;

              if (!cached) {
                _context3.next = 9;
                break;
              }

              if (!addresses) {
                _context3.next = 8;
                break;
              }

              return _context3.abrupt("return", cached.filter(function (market) {
                return addresses.includes(market.address);
              }));

            case 8:
              return _context3.abrupt("return", cached);

            case 9:
              _context3.next = 11;
              return this.yearn.services.lens.adapters.ironBank.assetsDynamic(addresses, overrides);

            case 11:
              return _context3.abrupt("return", _context3.sent);

            case 12:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function getDynamic(_x5, _x6) {
      return _getDynamic.apply(this, arguments);
    }

    return getDynamic;
  }()
  /**
   * Get IronBank market positions for a particular address.
   * @param address
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.positionsOf =
  /*#__PURE__*/
  function () {
    var _positionsOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(address, addresses, overrides) {
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              return _context4.abrupt("return", this.yearn.services.lens.adapters.ironBank.positionsOf(address, addresses, overrides));

            case 1:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function positionsOf(_x7, _x8, _x9) {
      return _positionsOf.apply(this, arguments);
    }

    return positionsOf;
  }()
  /**
   * Get the IronBank User Summary for a particular address.
   * @param address
   * @param overrides
   * @returns
   */
  ;

  _proto.summaryOf =
  /*#__PURE__*/
  function () {
    var _summaryOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(address, overrides) {
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              return _context5.abrupt("return", this.yearn.services.lens.adapters.ironBank.generalPositionOf(address, overrides));

            case 1:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function summaryOf(_x10, _x11) {
      return _summaryOf.apply(this, arguments);
    }

    return summaryOf;
  }()
  /**
   * Get the IronBank User Metadata for a particular address.
   * @param address
   * @param addresses
   * @param overrides
   * @returns
   */
  ;

  _proto.metadataOf =
  /*#__PURE__*/
  function () {
    var _metadataOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(address, addresses, overrides) {
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              return _context6.abrupt("return", this.yearn.services.lens.adapters.ironBank.assetsUserMetadata(address, addresses, overrides));

            case 1:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function metadataOf(_x12, _x13, _x14) {
      return _metadataOf.apply(this, arguments);
    }

    return metadataOf;
  }()
  /**
   * Get all IronBank market's underlying token balances for a particular
   * address.
   * @param address
   * @param overrides
   * @returns
   */
  ;

  _proto.balances =
  /*#__PURE__*/
  function () {
    var _balances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(address, overrides) {
      var tokens, balances;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              _context7.next = 2;
              return this.tokens();

            case 2:
              tokens = _context7.sent;
              _context7.next = 5;
              return this.yearn.services.helper.tokenBalances(address, tokens.map(function (token) {
                return token.address;
              }), overrides);

            case 5:
              balances = _context7.sent;
              return _context7.abrupt("return", balances.map(function (balance) {
                var token = tokens.find(function (token) {
                  return token.address === balance.address;
                });

                if (!token) {
                  throw new SdkError("Token does not exist for Balance(" + balance.address + ")");
                }

                return _extends({}, balance, {
                  token: token
                });
              }));

            case 7:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function balances(_x15, _x16) {
      return _balances.apply(this, arguments);
    }

    return balances;
  }()
  /**
   * Get all IronBank market's underlying tokens.
   * @param overrides
   * @returns
   */
  ;

  _proto.tokens =
  /*#__PURE__*/
  function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(overrides) {
      var _this2 = this;

      var cached, tokenAddresses, icons, erc20Tokens, erc20ToToken;
      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              _context9.next = 2;
              return this.cachedFetcherTokens.fetch();

            case 2:
              cached = _context9.sent;

              if (!cached) {
                _context9.next = 5;
                break;
              }

              return _context9.abrupt("return", cached);

            case 5:
              _context9.next = 7;
              return this.yearn.services.lens.adapters.ironBank.tokens(overrides);

            case 7:
              tokenAddresses = _context9.sent;
              icons = this.yearn.services.asset.icon(tokenAddresses);
              _context9.next = 11;
              return this.yearn.services.helper.tokens(tokenAddresses, overrides);

            case 11:
              erc20Tokens = _context9.sent;

              erc20ToToken = /*#__PURE__*/function () {
                var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(erc20Token) {
                  return runtime_1.wrap(function _callee8$(_context8) {
                    while (1) {
                      switch (_context8.prev = _context8.next) {
                        case 0:
                          _context8.t0 = _extends;
                          _context8.t1 = {};
                          _context8.t2 = erc20Token;
                          _context8.t3 = icons[erc20Token.address];
                          _context8.t4 = {
                            ironBank: true
                          };
                          _context8.next = 7;
                          return _this2.yearn.services.oracle.getPriceUsdc(erc20Token.address, overrides);

                        case 7:
                          _context8.t5 = _context8.sent;
                          _context8.t6 = {
                            icon: _context8.t3,
                            dataSource: "ironBank",
                            supported: _context8.t4,
                            priceUsdc: _context8.t5
                          };
                          return _context8.abrupt("return", (0, _context8.t0)(_context8.t1, _context8.t2, _context8.t6));

                        case 10:
                        case "end":
                          return _context8.stop();
                      }
                    }
                  }, _callee8);
                }));

                return function erc20ToToken(_x18) {
                  return _ref2.apply(this, arguments);
                };
              }();

              return _context9.abrupt("return", Promise.all(erc20Tokens.map(erc20ToToken)));

            case 14:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function tokens(_x17) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }();

  return IronBankInterface;
}(ServiceInterface);

var HourInMilliseconds = 1000 * 60 * 60;
var PickleApiUrl = "https://api.pickle.finance/prod/protocol/pools";
var PickleApiBackupUrl = "https://f8wgg18t1h.execute-api.us-west-1.amazonaws.com/prod/protocol/pools";
var PickleJars = ["0xCeD67a187b923F0E5ebcc77C7f2F7da20099e378"];
var PickleService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(PickleService, _Service);

  function PickleService() {
    var _this;

    _this = _Service.apply(this, arguments) || this;
    _this.pickleJarUSDPrices = new Map();
    _this.lastFetchedDate = new Date(0);
    return _this;
  }
  /**
   * Fetches the USD price of a pickle jar token
   * @param jar the address of the jar to fetch
   * @returns the price of the jar token in USD
   */


  var _proto = PickleService.prototype;

  _proto.getPriceUsdc =
  /*#__PURE__*/
  function () {
    var _getPriceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(jar) {
      var _this$pickleJarUSDPri;

      var oneHourAgo;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              oneHourAgo = new Date(Date.now() - HourInMilliseconds);

              if (!(this.lastFetchedDate < oneHourAgo)) {
                _context.next = 4;
                break;
              }

              _context.next = 4;
              return this.fetchPickleJarPrices();

            case 4:
              return _context.abrupt("return", usdc((_this$pickleJarUSDPri = this.pickleJarUSDPrices.get(jar)) == null ? void 0 : _this$pickleJarUSDPri.toFixed(0)) || "0");

            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function getPriceUsdc(_x) {
      return _getPriceUsdc.apply(this, arguments);
    }

    return getPriceUsdc;
  }();

  _proto.fetchPickleJarPrices = /*#__PURE__*/function () {
    var _fetchPickleJarPrices = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2() {
      var jarData, relevantJars, _iterator, _step, jarDatum, usdPrice;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return fetch(PickleApiUrl)["catch"](function () {
                return fetch(PickleApiBackupUrl);
              }).then(function (res) {
                return res.json();
              });

            case 2:
              jarData = _context2.sent;
              this.pickleJarUSDPrices.clear();
              this.lastFetchedDate = new Date();
              relevantJars = jarData.filter(function (jar) {
                return PickleJars.includes(address.getAddress(jar.jarAddress));
              });

              for (_iterator = _createForOfIteratorHelperLoose(relevantJars); !(_step = _iterator()).done;) {
                jarDatum = _step.value;
                usdPrice = new BigNumber.BigNumber(jarDatum.liquidity_locked / jarDatum.tokens);
                this.pickleJarUSDPrices.set(address.getAddress(jarDatum.jarAddress), usdPrice);
              }

            case 7:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function fetchPickleJarPrices() {
      return _fetchPickleJarPrices.apply(this, arguments);
    }

    return fetchPickleJarPrices;
  }();

  return PickleService;
}(Service);

var baseUrl = "https://simulate.yearn.network";
var latestBlockKey = -1;
/**
 * [[SimulationExecutor]] performs simulation requests and returns the response
 * with no data manipulation. If the simulation results in an error then an alert is sent
 * via telegram if the appropriate environment variables are set. Forks are necessary to be
 * created if two subsequent simulations are needed e.g. if a zap in is wished to be simulated
 * but the user has not approved the zap contract then the steps to simulate it are:
 * 1. Create a fork
 * 2. Simulate the approval transaction using this fork
 * 3. Simulate the zap in using the approval transaction as the root
 */

var SimulationExecutor = /*#__PURE__*/function () {
  function SimulationExecutor(telegram, ctx) {
    this.telegram = telegram;
    this.ctx = ctx;
  }
  /**
   * Simulate a transaction
   * @param from
   * @param to
   * @param input the encoded input data as per the ethereum abi specification
   * @param value the ether value of the transaction
   * @param options simulation options
   * @returns data about the simulated transaction
   */


  var _proto = SimulationExecutor.prototype;

  _proto.simulateRaw =
  /*#__PURE__*/
  function () {
    var _simulateRaw = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(from, to, input, options, value) {
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              if (value === void 0) {
                value = "0";
              }

              _context.next = 4;
              return this.makeSimulationRequest(from, to, input, options, value);

            case 4:
              return _context.abrupt("return", _context.sent);

            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function simulateRaw(_x, _x2, _x3, _x4, _x5) {
      return _simulateRaw.apply(this, arguments);
    }

    return simulateRaw;
  }()
  /**
   * Simulates an interaction with a vault to see how much of the desired token
   * will be received. This happens by inspecting the logs of the transaction and
   * finding the Transfer event where the desired token is transferred to the user.
   * @param from
   * @param to
   * @param data
   * @param targetToken the token being bought by this transaction
   * @param from the address initiating this transaction
   * @param options
   * @param value
   * @returns the amount of tokens simulated to be bought
   */
  ;

  _proto.simulateVaultInteraction =
  /*#__PURE__*/
  function () {
    var _simulateVaultInteraction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(from, to, data, targetToken, options, value) {
      var response, getAddressFromTopic, encodedTransferFunction, log, tokensReceived;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (value === void 0) {
                value = "0";
              }

              _context2.next = 3;
              return this.makeSimulationRequest(from, to, data, options, value);

            case 3:
              response = _context2.sent;

              getAddressFromTopic = function getAddressFromTopic(topic) {
                return address.getAddress(topic.slice(-40)); // the last 20 bytes of the topic is the address
              };

              encodedTransferFunction = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"; // keccak256("Transfer(address,address,uint256)")

              log = response.transaction.transaction_info.logs.reverse().find(function (log) {
                return log.raw.topics[0] === encodedTransferFunction && getAddressFromTopic(log.raw.topics[2]) === address.getAddress(from);
              });

              if (log) {
                _context2.next = 9;
                break;
              }

              throw new SimulationError("No log of transferring token " + targetToken + " to " + from, SimulationError.NO_LOG);

            case 9:
              tokensReceived = new BigNumber__default(log.raw.data).toFixed(0);
              return _context2.abrupt("return", tokensReceived);

            case 11:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function simulateVaultInteraction(_x6, _x7, _x8, _x9, _x10, _x11) {
      return _simulateVaultInteraction.apply(this, arguments);
    }

    return simulateVaultInteraction;
  }()
  /**
   * Performs a simulation with preset parameters
   * @param from
   * @param to
   * @param data
   * @param options
   * @param value
   * @returns the resulting data from the transaction
   */
  ;

  _proto.makeSimulationRequest =
  /*#__PURE__*/
  function () {
    var _makeSimulationRequest = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(from, to, data, options, value) {
      var _transactionRequest$c, _transactionRequest$v, _transactionRequest$g, _transactionRequest$g2;

      var constructedPath, transactionRequest, body, simulationResponse, errorMessage, _allCalls$find, allCalls, partialRevertError, _errorMessage;

      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (value === void 0) {
                value = "0";
              }

              constructedPath = options != null && options.forkId ? baseUrl + "/fork/" + options.forkId + "/simulate" : baseUrl + "/simulate";
              _context3.next = 4;
              return this.getPopulatedTransactionRequest(from, to, data, options, value);

            case 4:
              transactionRequest = _context3.sent;
              body = {
                from: from,
                to: to,
                input: data,
                network_id: ((_transactionRequest$c = transactionRequest.chainId) == null ? void 0 : _transactionRequest$c.toString()) || "1",
                block_number: latestBlockKey,
                simulation_type: "quick",
                root: options == null ? void 0 : options.root,
                value: ((_transactionRequest$v = transactionRequest.value) == null ? void 0 : _transactionRequest$v.toString()) || "0",
                gas: parseInt(((_transactionRequest$g = transactionRequest.gasLimit) == null ? void 0 : _transactionRequest$g.toString()) || "0"),
                gas_price: ((_transactionRequest$g2 = transactionRequest.gasPrice) == null ? void 0 : _transactionRequest$g2.toString()) || 0,
                save: options.save || true,
                nonce: transactionRequest.nonce
              };
              _context3.next = 8;
              return fetch(constructedPath, {
                method: "POST",
                headers: {
                  "Content-Type": "application/json"
                },
                body: JSON.stringify(body)
              }).then(function (res) {
                return res.json();
              })["catch"](function () {
                throw new TenderlyError("simulation call to Tenderly failed", TenderlyError.SIMULATION_CALL);
              });

            case 8:
              simulationResponse = _context3.sent;
              errorMessage = simulationResponse.transaction.error_message;

              if (!errorMessage) {
                _context3.next = 15;
                break;
              }

              if (options.save) {
                this.sendErrorMessage(errorMessage, simulationResponse.simulation.id, options.forkId);
              }

              throw new SimulationError(errorMessage, SimulationError.TENDERLY_RESPONSE_ERROR);

            case 15:
              // even though the transaction has been successful one of it's calls could have failed i.e. a partial revert might have happened
              allCalls = this.getAllSimulationCalls(simulationResponse.transaction.transaction_info.call_trace);
              partialRevertError = (_allCalls$find = allCalls.find(function (call) {
                return call.error;
              })) == null ? void 0 : _allCalls$find.error;

              if (!partialRevertError) {
                _context3.next = 21;
                break;
              }

              _errorMessage = "Partial Revert - " + partialRevertError;
              this.sendErrorMessage(_errorMessage, simulationResponse.simulation.id, options == null ? void 0 : options.forkId);
              throw new SimulationError(_errorMessage, SimulationError.PARTIAL_REVERT);

            case 21:
              return _context3.abrupt("return", simulationResponse);

            case 22:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function makeSimulationRequest(_x12, _x13, _x14, _x15, _x16) {
      return _makeSimulationRequest.apply(this, arguments);
    }

    return makeSimulationRequest;
  }()
  /**
   * Simulates a transaction, with the `save` parameter initially set to `false`. If this simulation fails then
   * the simulation is re-executed but with `save` set to `true` so the failure can be stored and later analyzed.
   * @param simulate the function which executes the simulation, passing in `save` as an argument.
   * @param forkIdToDeleteOnSuccess if the simulation is successful there is no reason to save it. Delete the fork to avoid clutter
   * @returns the result of the simulate parameter
   */
  ;

  _proto.executeSimulationWithReSimulationOnFailure =
  /*#__PURE__*/
  function () {
    var _executeSimulationWithReSimulationOnFailure = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(simulate, forkIdToDeleteOnSuccess) {
      var _this = this;

      var result;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              if (forkIdToDeleteOnSuccess === void 0) {
                forkIdToDeleteOnSuccess = null;
              }

              _context4.prev = 1;
              _context4.next = 4;
              return simulate(false).then(function (res) {
                // if the transaction used a fork and was successful then delete it
                if (forkIdToDeleteOnSuccess) {
                  _this.deleteFork(forkIdToDeleteOnSuccess);
                }

                return res;
              });

            case 4:
              result = _context4.sent;
              return _context4.abrupt("return", result);

            case 8:
              _context4.prev = 8;
              _context4.t0 = _context4["catch"](1);
              _context4.prev = 10;
              _context4.next = 13;
              return simulate(true);

            case 13:
              _context4.next = 18;
              break;

            case 15:
              _context4.prev = 15;
              _context4.t1 = _context4["catch"](10);
              console.error(_context4.t1);

            case 18:
              throw _context4.t0;

            case 19:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, null, [[1, 8], [10, 15]]);
    }));

    function executeSimulationWithReSimulationOnFailure(_x17, _x18) {
      return _executeSimulationWithReSimulationOnFailure.apply(this, arguments);
    }

    return executeSimulationWithReSimulationOnFailure;
  }()
  /**
   * Create a new fork that can be used to simulate multiple sequential transactions on
   * e.g. approval followed by a deposit.
   * @returns the uuid of a new fork that has been created
   */
  ;

  _proto.createFork =
  /*#__PURE__*/
  function () {
    var _createFork = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5() {
      var body, response;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              body = {
                alias: "",
                description: "",
                network_id: "1"
              };
              _context5.next = 3;
              return fetch(baseUrl + "/fork", {
                method: "POST",
                headers: {
                  "Content-Type": "application/json"
                },
                body: JSON.stringify(body)
              }).then(function (res) {
                return res.json();
              })["catch"](function () {
                throw new TenderlyError("failed to create fork", TenderlyError.CREATE_FORK);
              });

            case 3:
              _context5.next = 5;
              return _context5.sent;

            case 5:
              response = _context5.sent;
              return _context5.abrupt("return", response.simulation_fork.id);

            case 7:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5);
    }));

    function createFork() {
      return _createFork.apply(this, arguments);
    }

    return createFork;
  }()
  /**
   * Recursively loops through the simulation call trace, aggregating all calls into a flattened array.
   * @param callTrace the starting call trace to inspect
   * @returns a flattened array of call data
   */
  ;

  _proto.getAllSimulationCalls = function getAllSimulationCalls(callTrace) {
    var result = [];
    result = result.concat(callTrace.calls || []);

    for (var _iterator = _createForOfIteratorHelperLoose(callTrace.calls || []), _step; !(_step = _iterator()).done;) {
      var calls = _step.value;
      var res = this.getAllSimulationCalls(calls);
      result = result.concat(res);
    }

    return result;
  }
  /**
   * Creates a transaction object and populates it to fill in parameters such as gas price,
   * gas limit and nonce for a more accurate simulations
   * @param from
   * @param to
   * @param data
   * @param value
   * @param options
   * @returns A populated TransactionRequest object
   */
  ;

  _proto.getPopulatedTransactionRequest =
  /*#__PURE__*/
  function () {
    var _getPopulatedTransactionRequest = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(from, to, data, options, value) {
      var signer, provider, transactionRequest, result;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (value === void 0) {
                value = "0";
              }

              if (options != null && options.forkId) {
                provider = new providers.JsonRpcProvider("https://rpc.tenderly.co/fork/" + options.forkId);
                signer = provider.getSigner(from);
              } else {
                signer = this.ctx.provider.write.getSigner(from);
              }

              if (options.maxFeePerGas && options.maxPriorityFeePerGas) {
                delete options.gasPrice;
              }

              transactionRequest = {
                from: from,
                to: to,
                data: data,
                value: value,
                gasLimit: options.gasLimit,
                gasPrice: options.gasPrice,
                maxFeePerGas: options.maxFeePerGas,
                maxPriorityFeePerGas: options.maxPriorityFeePerGas,
                type: options.gasPrice ? 0 : undefined
              };
              _context6.next = 6;
              return signer.populateTransaction(transactionRequest)["catch"](function () {
                throw new EthersError("error populating transaction", EthersError.POPULATING_TRANSACTION);
              });

            case 6:
              result = _context6.sent;
              return _context6.abrupt("return", result);

            case 8:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function getPopulatedTransactionRequest(_x19, _x20, _x21, _x22, _x23) {
      return _getPopulatedTransactionRequest.apply(this, arguments);
    }

    return getPopulatedTransactionRequest;
  }()
  /**
   * Deletes a fork. This should be done after its successful use in order to avoid clutter.
   * @param forkId the fork to be deleted
   * @returns the deletion response
   */
  ;

  _proto.deleteFork =
  /*#__PURE__*/
  function () {
    var _deleteFork = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(forkId) {
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              _context7.next = 2;
              return fetch(baseUrl + "/fork/" + forkId, {
                method: "DELETE"
              });

            case 2:
              return _context7.abrupt("return", _context7.sent);

            case 3:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7);
    }));

    function deleteFork(_x24) {
      return _deleteFork.apply(this, arguments);
    }

    return deleteFork;
  }()
  /**
   * Sends a message to a telegram channel reporting a simulation error
   * @param errorMessage the error to be reported
   * @param simulationId the id of the simulation so the simulation failure can be inspected in the dashboard
   * @param forkId the optional id of the fork so the simulation failure can be inspected in the dashboard
   */
  ;

  _proto.sendErrorMessage = function sendErrorMessage(errorMessage, simulationId, forkId) {
    var transactionUrl;

    if (this.ctx.simulation.dashboardUrl) {
      transactionUrl = this.ctx.simulation.dashboardUrl + "/" + (forkId ? "fork/" + forkId + "/simulation" : "simulator") + "/" + simulationId;
    }

    var message = ["Simulation error", errorMessage, transactionUrl].map(function (item) {
      return item;
    }).join("\n\n");
    this.telegram.sendMessage(message);
  };

  return SimulationExecutor;
}();

var VaultContract = /*#__PURE__*/function () {
  function VaultContract(contract) {
    var _this = this;

    this.contract = contract;

    this.encodeDeposit = function (amount) {
      return _this.contract["interface"].encodeFunctionData("deposit", [amount]);
    };

    this.encodeWithdraw = function (amount) {
      return _this.contract["interface"].encodeFunctionData("withdraw", [amount]);
    };
  }

  var _proto = VaultContract.prototype;

  _proto.decimals = /*#__PURE__*/function () {
    var _decimals = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
      var decimals;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.contract.decimals();

            case 2:
              decimals = _context.sent;
              return _context.abrupt("return", new BigNumber.BigNumber(decimals.toString()));

            case 4:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function decimals() {
      return _decimals.apply(this, arguments);
    }

    return decimals;
  }();

  _proto.token = /*#__PURE__*/function () {
    var _token = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2() {
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.contract.token();

            case 2:
              return _context2.abrupt("return", _context2.sent);

            case 3:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function token() {
      return _token.apply(this, arguments);
    }

    return token;
  }();

  _createClass(VaultContract, null, [{
    key: "abi",
    get: function get() {
      return ["function token() view returns (address)", "function decimals() view returns (uint256)", "function deposit(uint256 amount) public", "function withdraw(uint256 amount) public"];
    }
  }]);

  return VaultContract;
}();
var PickleJarContract = /*#__PURE__*/function (_VaultContract) {
  _inheritsLoose(PickleJarContract, _VaultContract);

  function PickleJarContract(jarAddress, signer) {
    return _VaultContract.call(this, new contracts.Contract(jarAddress, [].concat(VaultContract.abi, PickleJarContract.pickleJarAbi), signer)) || this;
  }

  var _proto2 = PickleJarContract.prototype;

  _proto2.pricePerShare = /*#__PURE__*/function () {
    var _pricePerShare = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3() {
      var ratio;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return this.contract.getRatio();

            case 2:
              ratio = _context3.sent;
              return _context3.abrupt("return", new BigNumber.BigNumber(ratio.toString()));

            case 4:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function pricePerShare() {
      return _pricePerShare.apply(this, arguments);
    }

    return pricePerShare;
  }();

  _createClass(PickleJarContract, null, [{
    key: "pickleJarAbi",
    get: function get() {
      return ["function getRatio() public view returns (uint256)"];
    }
  }]);

  return PickleJarContract;
}(VaultContract);
var YearnVaultContract = /*#__PURE__*/function (_VaultContract2) {
  _inheritsLoose(YearnVaultContract, _VaultContract2);

  function YearnVaultContract(jarAddress, signer) {
    return _VaultContract2.call(this, new contracts.Contract(jarAddress, [].concat(VaultContract.abi, YearnVaultContract.yearnVaultAbi), signer)) || this;
  }

  var _proto3 = YearnVaultContract.prototype;

  _proto3.pricePerShare = /*#__PURE__*/function () {
    var _pricePerShare2 = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4() {
      var pricePerShare;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return this.contract.pricePerShare();

            case 2:
              pricePerShare = _context4.sent;
              return _context4.abrupt("return", new BigNumber.BigNumber(pricePerShare.toString()));

            case 4:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function pricePerShare() {
      return _pricePerShare2.apply(this, arguments);
    }

    return pricePerShare;
  }();

  _createClass(YearnVaultContract, null, [{
    key: "yearnVaultAbi",
    get: function get() {
      return ["function pricePerShare() view returns (uint256)"];
    }
  }]);

  return YearnVaultContract;
}(VaultContract);

/**
 * Supported chains in the yearn ecosystem.
 */
var Chains = {
  1: "ethereum",
  250: "fantom",
  1337: "ethereum",
  42161: "arbitrum"
};
var isEthereum = function isEthereum(chainId) {
  return chainId === 1 || chainId === 1337;
};
var isFantom = function isFantom(chainId) {
  return chainId === 250;
};
var allSupportedChains = /*#__PURE__*/Object.keys(Chains).map(function (key) {
  return Number(key);
});

function getZapInDetails(_ref) {
  var _vault$metadata;

  var chainId = _ref.chainId,
      token = _ref.token,
      vault = _ref.vault;

  if (!token.supported || !((_vault$metadata = vault.metadata) != null && _vault$metadata.zapInWith)) {
    return {
      isZapInSupported: false,
      zapInWith: null
    };
  }

  if (isEthereum(chainId)) {
    var zapInWith = vault.metadata.zapInWith;

    if (zapInWith && isValidZap(zapInWith, token.supported)) {
      var isZapInSupported = Boolean(token.supported.zapper) && Boolean(token.supported[zapInWith]);
      return {
        isZapInSupported: isZapInSupported,
        zapInWith: isZapInSupported ? zapInWith : null
      };
    }
  }

  if (isFantom(chainId)) {
    var _zapInWith = "ftmApeZap"; // Hardcoded for now

    var _isZapInSupported = Boolean(token.supported[_zapInWith]);

    return {
      isZapInSupported: _isZapInSupported,
      zapInWith: _isZapInSupported ? _zapInWith : null
    };
  }

  return {
    isZapInSupported: false,
    zapInWith: null
  };
}
function getZapOutDetails(_ref2) {
  var _vault$metadata2;

  var chainId = _ref2.chainId,
      token = _ref2.token,
      vault = _ref2.vault;

  if (!token.supported || !((_vault$metadata2 = vault.metadata) != null && _vault$metadata2.zapOutWith)) {
    return {
      isZapOutSupported: false,
      zapOutWith: null
    };
  }

  if (isEthereum(chainId)) {
    var zapOutWith = vault.metadata.zapOutWith;

    if (zapOutWith && isValidZap(zapOutWith, token.supported)) {
      var isZapOutSupported = Boolean(token.supported.zapper) && Boolean(token.supported[zapOutWith]);
      return {
        isZapOutSupported: isZapOutSupported,
        zapOutWith: isZapOutSupported ? zapOutWith : null
      };
    }
  }

  if (isFantom(chainId)) {
    var _zapOutWith = "ftmApeZap"; // Hardcoded for now

    var _isZapOutSupported = Boolean(token.supported[_zapOutWith]);

    return {
      isZapOutSupported: _isZapOutSupported,
      zapOutWith: _isZapOutSupported ? _zapOutWith : null
    };
  }

  return {
    isZapOutSupported: false,
    zapOutWith: null
  };
}
/**
 * Returns true if the given zap is valid for the given token.
 * @param zap the zap type to check
 * @param zaps the zap types supported by the token
 * @returns true if the zap type is supported by the token
 */

function isValidZap(zap, zaps) {
  return zap in zaps;
}

/**
 * [[SimulationInterface]] allows the simulation of ethereum transactions using Tenderly's api.
 * This allows us to know information before executing a transaction on mainnet.
 * For example it can simulate how much slippage is likely to be experienced when withdrawing from a vault,
 * or how many underlying tokens the user will receive upon withdrawing share tokens.
 */

var SimulationInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(SimulationInterface, _ServiceInterface);

  function SimulationInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.simulationExecutor = new SimulationExecutor(_this.yearn.services.telegram, _this.ctx);
    return _this;
  }

  var _proto = SimulationInterface.prototype;

  _proto.deposit = /*#__PURE__*/function () {
    var _deposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(from, sellToken, amount, toVault, options) {
      var depositArgs, signer, vaultContract, vault, token, isUnderlyingToken, _getZapInDetails, isZapInSupported, zapInWith;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              depositArgs = {
                from: from,
                sellToken: sellToken,
                amount: amount,
                toVault: toVault,
                options: options
              };
              signer = this.ctx.provider.write.getSigner(from);
              vaultContract = this.getVaultContract({
                toVault: toVault,
                signer: signer
              });
              _context.next = 6;
              return this.getZappableVault({
                vaultAddress: toVault,
                vaultContract: vaultContract
              });

            case 6:
              vault = _context.sent;

              if (vault) {
                _context.next = 9;
                break;
              }

              throw new SdkError("Could not get vault: " + toVault);

            case 9:
              _context.next = 11;
              return this.yearn.tokens.findByAddress(sellToken);

            case 11:
              token = _context.sent;

              if (token) {
                _context.next = 14;
                break;
              }

              throw new SdkError("Could not find the token by address: " + sellToken);

            case 14:
              _context.next = 16;
              return this.isUnderlyingToken({
                vault: toVault,
                address: token.address
              });

            case 16:
              isUnderlyingToken = _context.sent;

              if (!isUnderlyingToken) {
                _context.next = 19;
                break;
              }

              return _context.abrupt("return", this.handleDirectSimulationDeposit({
                depositArgs: depositArgs,
                vaultContract: vaultContract,
                vault: vault,
                signer: signer
              }));

            case 19:
              _getZapInDetails = getZapInDetails({
                chainId: this.chainId,
                token: token,
                vault: vault
              }), isZapInSupported = _getZapInDetails.isZapInSupported, zapInWith = _getZapInDetails.zapInWith;

              if (!(isZapInSupported && zapInWith)) {
                _context.next = 22;
                break;
              }

              return _context.abrupt("return", this.handleZapInSimulationDeposit({
                depositArgs: depositArgs,
                zapInWith: zapInWith,
                vault: vault
              }));

            case 22:
              throw new SdkError("Deposit of " + token.address + " to " + toVault + " is not supported");

            case 23:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function deposit(_x, _x2, _x3, _x4, _x5) {
      return _deposit.apply(this, arguments);
    }

    return deposit;
  }();

  _proto.handleDirectSimulationDeposit = /*#__PURE__*/function () {
    var _handleDirectSimulationDeposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(_ref) {
      var _this2 = this;

      var depositArgs, vaultContract, vault, signer, _yield$this$getApprov, root, forkId, simulateFn;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              depositArgs = _ref.depositArgs, vaultContract = _ref.vaultContract, vault = _ref.vault, signer = _ref.signer;
              _context2.next = 3;
              return this.getApprovalData({
                depositArgs: depositArgs,
                signer: signer
              });

            case 3:
              _yield$this$getApprov = _context2.sent;
              root = _yield$this$getApprov.approvalTransactionId;
              forkId = _yield$this$getApprov.forkId;

              simulateFn = function simulateFn(save) {
                return _this2.directDeposit({
                  depositArgs: _extends({}, depositArgs, {
                    options: _extends({}, depositArgs.options, {
                      forkId: forkId,
                      save: save,
                      root: root
                    })
                  }),
                  vaultContract: vaultContract,
                  vault: vault
                });
              };

              return _context2.abrupt("return", this.simulationExecutor.executeSimulationWithReSimulationOnFailure(simulateFn, forkId));

            case 8:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function handleDirectSimulationDeposit(_x6) {
      return _handleDirectSimulationDeposit.apply(this, arguments);
    }

    return handleDirectSimulationDeposit;
  }();

  _proto.withdraw = /*#__PURE__*/function () {
    var _withdraw = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(from, fromVault, amount, toToken, options) {
      var _this3 = this;

      var withdrawArgs, signer, vaultContract, _yield$this$yearn$vau, vault, token, isUnderlyingToken, simulateFn, _getZapOutDetails, isZapOutSupported, zapOutWith;

      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              withdrawArgs = {
                from: from,
                fromVault: fromVault,
                amount: amount,
                toToken: toToken,
                options: options
              };
              signer = this.ctx.provider.write.getSigner(from);
              vaultContract = new YearnVaultContract(fromVault, signer);
              _context3.next = 6;
              return this.yearn.vaults.get([fromVault]);

            case 6:
              _yield$this$yearn$vau = _context3.sent;
              vault = _yield$this$yearn$vau[0];

              if (vault) {
                _context3.next = 10;
                break;
              }

              throw new SdkError("Could not get vault: " + fromVault);

            case 10:
              _context3.next = 12;
              return this.yearn.tokens.findByAddress(toToken);

            case 12:
              token = _context3.sent;

              if (token) {
                _context3.next = 15;
                break;
              }

              throw new SdkError("Could not find the token by address: " + toToken);

            case 15:
              _context3.next = 17;
              return this.isUnderlyingToken({
                vault: fromVault,
                address: token.address
              });

            case 17:
              isUnderlyingToken = _context3.sent;

              if (!isUnderlyingToken) {
                _context3.next = 21;
                break;
              }

              simulateFn = function simulateFn(save) {
                return _this3.directWithdraw(_extends({}, withdrawArgs, {
                  vaultContract: vaultContract,
                  options: _extends({}, options, {
                    save: save
                  })
                }));
              };

              return _context3.abrupt("return", this.simulationExecutor.executeSimulationWithReSimulationOnFailure(simulateFn));

            case 21:
              _getZapOutDetails = getZapOutDetails({
                chainId: this.chainId,
                token: token,
                vault: vault
              }), isZapOutSupported = _getZapOutDetails.isZapOutSupported, zapOutWith = _getZapOutDetails.zapOutWith;

              if (!(isZapOutSupported && zapOutWith)) {
                _context3.next = 24;
                break;
              }

              return _context3.abrupt("return", this.handleZapOutSimulation({
                withdrawArgs: withdrawArgs,
                zapOutWith: zapOutWith,
                token: token
              }));

            case 24:
              throw new SdkError("Withdraw from " + fromVault + " to " + toToken + " is not supported");

            case 25:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function withdraw(_x7, _x8, _x9, _x10, _x11) {
      return _withdraw.apply(this, arguments);
    }

    return withdraw;
  }();

  _proto.getWithdrawApprovalData = /*#__PURE__*/function () {
    var _getWithdrawApprovalData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(_ref2) {
      var from, fromVault, options, _yield$this$yearn$ser, isApproved, forkId, zapApprovalTransaction, _yield$this$simulatio, simulation;

      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              from = _ref2.from, fromVault = _ref2.fromVault, options = _ref2.options;
              _context4.prev = 1;
              _context4.next = 4;
              return this.yearn.services.zapper.zapOutApprovalState(from, fromVault);

            case 4:
              _yield$this$yearn$ser = _context4.sent;
              isApproved = _yield$this$yearn$ser.isApproved;

              if (!isApproved) {
                _context4.next = 8;
                break;
              }

              return _context4.abrupt("return", {
                needsApproving: false
              });

            case 8:
              _context4.next = 13;
              break;

            case 10:
              _context4.prev = 10;
              _context4.t0 = _context4["catch"](1);
              throw new ZapperError("zap out approval state", ZapperError.ZAP_OUT_APPROVAL_STATE);

            case 13:
              _context4.next = 15;
              return this.simulationExecutor.createFork();

            case 15:
              forkId = _context4.sent;
              _context4.prev = 16;
              _context4.next = 19;
              return this.yearn.services.zapper.zapOutApprovalTransaction(from, fromVault, "0");

            case 19:
              zapApprovalTransaction = _context4.sent;
              _context4.next = 22;
              return this.simulationExecutor.makeSimulationRequest(zapApprovalTransaction.from, zapApprovalTransaction.to, zapApprovalTransaction.data, _extends({}, options, {
                forkId: forkId,
                save: true
              }));

            case 22:
              _yield$this$simulatio = _context4.sent;
              simulation = _yield$this$simulatio.simulation;
              return _context4.abrupt("return", {
                needsApproving: true,
                root: simulation.id,
                forkId: forkId
              });

            case 27:
              _context4.prev = 27;
              _context4.t1 = _context4["catch"](16);
              throw new ZapperError("zap out approval transaction", ZapperError.ZAP_OUT_APPROVAL);

            case 30:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this, [[1, 10], [16, 27]]);
    }));

    function getWithdrawApprovalData(_x12) {
      return _getWithdrawApprovalData.apply(this, arguments);
    }

    return getWithdrawApprovalData;
  }();

  _proto.directDeposit = /*#__PURE__*/function () {
    var _directDeposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(_ref3) {
      var _ref3$depositArgs, toVault, amount, from, sellToken, options, vaultContract, vault, encodedInputData, addressToDeposit, tokensReceived, targetTokenAmountUsdc, decimals, pricePerShare, targetUnderlyingTokensReceived;

      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              _ref3$depositArgs = _ref3.depositArgs, toVault = _ref3$depositArgs.toVault, amount = _ref3$depositArgs.amount, from = _ref3$depositArgs.from, sellToken = _ref3$depositArgs.sellToken, options = _ref3$depositArgs.options, vaultContract = _ref3.vaultContract, vault = _ref3.vault;
              _context5.next = 3;
              return this.getEncodedInputData({
                vaultContract: vaultContract,
                amount: amount,
                toVault: toVault
              });

            case 3:
              encodedInputData = _context5.sent;

              if (encodedInputData) {
                _context5.next = 6;
                break;
              }

              throw new SdkError("directDeposit#encodeDeposit failed");

            case 6:
              _context5.next = 8;
              return this.getActionableAddress({
                toVault: toVault
              });

            case 8:
              addressToDeposit = _context5.sent;
              _context5.next = 11;
              return this.simulationExecutor.simulateVaultInteraction(from, addressToDeposit, encodedInputData, toVault, options);

            case 11:
              tokensReceived = _context5.sent;
              _context5.next = 14;
              return this.yearn.services.oracle.getNormalizedValueUsdc(toVault, tokensReceived)["catch"](function () {
                throw new PriceFetchingError("Error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 14:
              targetTokenAmountUsdc = _context5.sent;
              decimals = vault.decimals, pricePerShare = vault.metadata.pricePerShare;

              if (decimals) {
                _context5.next = 18;
                break;
              }

              throw new SdkError("Decimals missing for vault " + vault.address);

            case 18:
              if (pricePerShare) {
                _context5.next = 20;
                break;
              }

              throw new SdkError("Price per share missing in vault " + vault.address + " metadata");

            case 20:
              targetUnderlyingTokensReceived = toBN(tokensReceived).div(toBN(10).pow(decimals)).multipliedBy(pricePerShare).toFixed(0);
              return _context5.abrupt("return", {
                sourceTokenAddress: sellToken,
                sourceTokenAmount: amount,
                targetTokenAddress: toVault,
                targetTokenAmount: tokensReceived,
                targetTokenAmountUsdc: targetTokenAmountUsdc,
                targetUnderlyingTokenAddress: toVault,
                targetUnderlyingTokenAmount: targetUnderlyingTokensReceived,
                conversionRate: 1,
                slippage: 0
              });

            case 22:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function directDeposit(_x13) {
      return _directDeposit.apply(this, arguments);
    }

    return directDeposit;
  }();

  _proto.getEncodedInputData = /*#__PURE__*/function () {
    var _getEncodedInputData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(_ref4) {
      var _this$yearn$services$;

      var vaultContract, amount, toVault;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              vaultContract = _ref4.vaultContract, amount = _ref4.amount, toVault = _ref4.toVault;

              if (this.shouldUsePartnerService(toVault)) {
                _context6.next = 3;
                break;
              }

              return _context6.abrupt("return", vaultContract.encodeDeposit(amount));

            case 3:
              return _context6.abrupt("return", (_this$yearn$services$ = this.yearn.services.partner) == null ? void 0 : _this$yearn$services$.encodeDeposit(toVault, amount));

            case 4:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function getEncodedInputData(_x14) {
      return _getEncodedInputData.apply(this, arguments);
    }

    return getEncodedInputData;
  }();

  _proto.getActionableAddress = /*#__PURE__*/function () {
    var _getActionableAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(_ref5) {
      var _this$yearn$services$2;

      var toVault, partnerAddress;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              toVault = _ref5.toVault;

              if (this.shouldUsePartnerService(toVault)) {
                _context7.next = 3;
                break;
              }

              return _context7.abrupt("return", toVault);

            case 3:
              _context7.next = 5;
              return (_this$yearn$services$2 = this.yearn.services.partner) == null ? void 0 : _this$yearn$services$2.address;

            case 5:
              partnerAddress = _context7.sent;
              return _context7.abrupt("return", partnerAddress || toVault);

            case 7:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function getActionableAddress(_x15) {
      return _getActionableAddress.apply(this, arguments);
    }

    return getActionableAddress;
  }();

  _proto.depositNeedsApproving = /*#__PURE__*/function () {
    var _depositNeedsApproving = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(_ref6) {
      var _ref6$depositArgs, from, sellToken, amount, toVault, signer, TokenAbi, contract, addressToCheck, allowance;

      return runtime_1.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              _ref6$depositArgs = _ref6.depositArgs, from = _ref6$depositArgs.from, sellToken = _ref6$depositArgs.sellToken, amount = _ref6$depositArgs.amount, toVault = _ref6$depositArgs.toVault, signer = _ref6.signer;
              TokenAbi = ["function allowance(address owner, address spender) view returns (uint256)"];
              contract = new contracts.Contract(sellToken, TokenAbi, signer);
              _context8.next = 5;
              return this.getActionableAddress({
                toVault: toVault
              });

            case 5:
              addressToCheck = _context8.sent;
              _context8.prev = 6;
              _context8.next = 9;
              return contract.allowance(from, addressToCheck);

            case 9:
              allowance = _context8.sent;
              return _context8.abrupt("return", toBN(allowance.toString()).lt(toBN(amount)));

            case 13:
              _context8.prev = 13;
              _context8.t0 = _context8["catch"](6);
              throw new SdkError("Failed to get allowance from the contract: " + _context8.t0);

            case 16:
            case "end":
              return _context8.stop();
          }
        }
      }, _callee8, this, [[6, 13]]);
    }));

    function depositNeedsApproving(_x16) {
      return _depositNeedsApproving.apply(this, arguments);
    }

    return depositNeedsApproving;
  }();

  _proto.zapIn = /*#__PURE__*/function () {
    var _zapIn = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(_ref7) {
      var _ref7$depositArgs, sellToken, from, amount, toVault, options, vault, skipGasEstimate, zapToken, zapProtocol, zapInParams, value, tokensReceived, decimals, pricePerShare, underlyingTokenAddress, targetUnderlyingTokensReceived, amountReceivedUsdc, oracleToken, zapInAmountUsdc, conversionRate;

      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              _ref7$depositArgs = _ref7.depositArgs, sellToken = _ref7$depositArgs.sellToken, from = _ref7$depositArgs.from, amount = _ref7$depositArgs.amount, toVault = _ref7$depositArgs.toVault, options = _ref7$depositArgs.options, vault = _ref7.vault, skipGasEstimate = _ref7.skipGasEstimate;
              zapToken = sellToken === EthAddress ? ZeroAddress : sellToken;

              if (options.slippage) {
                _context9.next = 4;
                break;
              }

              throw new SdkError("slippage needs to be set", SdkError.NO_SLIPPAGE);

            case 4:
              zapProtocol = this.getZapProtocol({
                vaultAddress: toVault
              });
              _context9.next = 7;
              return this.yearn.services.zapper.zapIn(from, zapToken, amount, toVault, options.gasPrice || "0", options.slippage, skipGasEstimate, zapProtocol)["catch"](function () {
                throw new ZapperError("zap in", ZapperError.ZAP_IN);
              });

            case 7:
              zapInParams = _context9.sent;
              value = toBN(zapInParams.value).toFixed(0);
              options.gasPrice = options.gasPrice || zapInParams.gasPrice;

              if (!skipGasEstimate) {
                options.gasLimit = zapInParams.gas;
              }

              _context9.next = 13;
              return this.simulationExecutor.simulateVaultInteraction(from, zapInParams.to, zapInParams.data, toVault, options, value);

            case 13:
              tokensReceived = _context9.sent;
              decimals = vault.decimals, pricePerShare = vault.metadata.pricePerShare, underlyingTokenAddress = vault.token;

              if (decimals) {
                _context9.next = 17;
                break;
              }

              throw new SdkError("Decimals missing for vault " + vault.address);

            case 17:
              if (pricePerShare) {
                _context9.next = 19;
                break;
              }

              throw new SdkError("Price per share missing in vault " + vault.address + " metadata");

            case 19:
              targetUnderlyingTokensReceived = toBN(tokensReceived).div(toBN(10).pow(decimals)).multipliedBy(pricePerShare).toFixed(0);
              _context9.t0 = zapProtocol;
              _context9.next = _context9.t0 === exports.ZapProtocol.YEARN ? 23 : _context9.t0 === exports.ZapProtocol.PICKLE ? 27 : 31;
              break;

            case 23:
              _context9.next = 25;
              return this.yearn.services.oracle.getNormalizedValueUsdc(toVault, tokensReceived).then(function (price) {
                return toBN(price);
              })["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 25:
              amountReceivedUsdc = _context9.sent;
              return _context9.abrupt("break", 31);

            case 27:
              _context9.next = 29;
              return this.yearn.services.pickle.getPriceUsdc(toVault)["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_PICKLE);
              }).then(function (usdc) {
                return toBN(usdc);
              });

            case 29:
              amountReceivedUsdc = _context9.sent.dividedBy(toBN(10).pow(decimals)).multipliedBy(toBN(tokensReceived));
              return _context9.abrupt("break", 31);

            case 31:
              oracleToken = sellToken === EthAddress ? WethAddress : sellToken;
              _context9.t1 = toBN;
              _context9.next = 35;
              return this.yearn.services.oracle.getNormalizedValueUsdc(oracleToken, amount)["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 35:
              _context9.t2 = _context9.sent;
              zapInAmountUsdc = (0, _context9.t1)(_context9.t2);
              conversionRate = amountReceivedUsdc.div(zapInAmountUsdc).toNumber();
              return _context9.abrupt("return", {
                sourceTokenAddress: sellToken,
                sourceTokenAmount: amount,
                targetTokenAddress: zapInParams.buyTokenAddress,
                targetTokenAmount: tokensReceived,
                targetTokenAmountUsdc: amountReceivedUsdc.toFixed(0),
                targetUnderlyingTokenAddress: underlyingTokenAddress,
                targetUnderlyingTokenAmount: targetUnderlyingTokensReceived,
                conversionRate: conversionRate,
                slippage: 1 - conversionRate
              });

            case 39:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function zapIn(_x17) {
      return _zapIn.apply(this, arguments);
    }

    return zapIn;
  }();

  _proto.directWithdraw = /*#__PURE__*/function () {
    var _directWithdraw = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(_ref8) {
      var from, toToken, amount, fromVault, vaultContract, options, encodedInputData, tokensReceived, targetTokenAmountUsdc;
      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              from = _ref8.from, toToken = _ref8.toToken, amount = _ref8.amount, fromVault = _ref8.fromVault, vaultContract = _ref8.vaultContract, options = _ref8.options;
              encodedInputData = vaultContract.encodeWithdraw(amount);
              _context10.next = 4;
              return this.simulationExecutor.simulateVaultInteraction(from, fromVault, encodedInputData, toToken, options);

            case 4:
              tokensReceived = _context10.sent;
              _context10.next = 7;
              return this.yearn.services.oracle.getNormalizedValueUsdc(toToken, tokensReceived)["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 7:
              targetTokenAmountUsdc = _context10.sent;
              return _context10.abrupt("return", {
                sourceTokenAddress: fromVault,
                sourceTokenAmount: amount,
                targetTokenAddress: toToken,
                targetTokenAmount: tokensReceived,
                targetTokenAmountUsdc: targetTokenAmountUsdc,
                targetUnderlyingTokenAddress: toToken,
                targetUnderlyingTokenAmount: tokensReceived,
                conversionRate: 1,
                slippage: 0
              });

            case 9:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function directWithdraw(_x18) {
      return _directWithdraw.apply(this, arguments);
    }

    return directWithdraw;
  }();

  _proto.zapOut = /*#__PURE__*/function () {
    var _zapOut = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee12(_ref9) {
      var _this4 = this;

      var from, toToken, underlyingTokenAddress, amount, fromVault, skipGasEstimate, options, zapToken, zapOutParams, tokensReceived, oracleToken, zapOutAmountUsdc, soldAssetAmountUsdc, conversionRate;
      return runtime_1.wrap(function _callee12$(_context12) {
        while (1) {
          switch (_context12.prev = _context12.next) {
            case 0:
              from = _ref9.from, toToken = _ref9.toToken, underlyingTokenAddress = _ref9.underlyingTokenAddress, amount = _ref9.amount, fromVault = _ref9.fromVault, skipGasEstimate = _ref9.skipGasEstimate, options = _ref9.options;

              if (options.slippage) {
                _context12.next = 3;
                break;
              }

              throw new SdkError("slippage needs to be set", SdkError.NO_SLIPPAGE);

            case 3:
              zapToken = toToken === EthAddress ? ZeroAddress : toToken;
              _context12.next = 6;
              return this.yearn.services.zapper.zapOut(from, zapToken, amount, fromVault, "0", options.slippage, skipGasEstimate)["catch"](function () {
                throw new ZapperError("error zapping out", ZapperError.ZAP_OUT);
              });

            case 6:
              zapOutParams = _context12.sent;

              if (!skipGasEstimate) {
                options.gasLimit = zapOutParams.gas;
              }

              _context12.next = 10;
              return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11() {
                var response;
                return runtime_1.wrap(function _callee11$(_context11) {
                  while (1) {
                    switch (_context11.prev = _context11.next) {
                      case 0:
                        if (!(zapToken === ZeroAddress)) {
                          _context11.next = 7;
                          break;
                        }

                        _context11.next = 3;
                        return _this4.simulationExecutor.makeSimulationRequest(from, zapOutParams.to, zapOutParams.data, options, zapOutParams.value);

                      case 3:
                        response = _context11.sent;
                        return _context11.abrupt("return", toBN(response.transaction.transaction_info.call_trace.output).toFixed(0));

                      case 7:
                        _context11.next = 9;
                        return _this4.simulationExecutor.simulateVaultInteraction(from, zapOutParams.to, zapOutParams.data, toToken, options, zapOutParams.value);

                      case 9:
                        return _context11.abrupt("return", _context11.sent);

                      case 10:
                      case "end":
                        return _context11.stop();
                    }
                  }
                }, _callee11);
              }))();

            case 10:
              tokensReceived = _context12.sent;
              oracleToken = toToken === EthAddress ? WethAddress : toToken;
              _context12.next = 14;
              return this.yearn.services.oracle.getNormalizedValueUsdc(oracleToken, tokensReceived)["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 14:
              zapOutAmountUsdc = _context12.sent;
              _context12.next = 17;
              return this.yearn.services.oracle.getNormalizedValueUsdc(fromVault, amount)["catch"](function () {
                throw new PriceFetchingError("error fetching price", PriceFetchingError.FETCHING_PRICE_ORACLE);
              });

            case 17:
              soldAssetAmountUsdc = _context12.sent;
              conversionRate = toBN(zapOutAmountUsdc).div(toBN(soldAssetAmountUsdc)).toNumber();
              return _context12.abrupt("return", {
                sourceTokenAddress: fromVault,
                sourceTokenAmount: amount,
                targetTokenAddress: toToken,
                targetTokenAmount: tokensReceived,
                targetTokenAmountUsdc: zapOutAmountUsdc,
                targetUnderlyingTokenAddress: underlyingTokenAddress,
                targetUnderlyingTokenAmount: tokensReceived,
                conversionRate: conversionRate,
                slippage: 1 - conversionRate
              });

            case 20:
            case "end":
              return _context12.stop();
          }
        }
      }, _callee12, this);
    }));

    function zapOut(_x19) {
      return _zapOut.apply(this, arguments);
    }

    return zapOut;
  }();

  _proto.shouldUsePartnerService = function shouldUsePartnerService(vault) {
    var _this$yearn$services$3;

    return !!((_this$yearn$services$3 = this.yearn.services.partner) != null && _this$yearn$services$3.isAllowed(vault));
  };

  _proto.getZapperZapInApprovalData = /*#__PURE__*/function () {
    var _getZapperZapInApprovalData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee14(_ref11) {
      var _this5 = this;

      var sellToken, from, toVault, options, zapProtocol, isApprovalNeeded, forkId, approvalTransactionId;
      return runtime_1.wrap(function _callee14$(_context14) {
        while (1) {
          switch (_context14.prev = _context14.next) {
            case 0:
              sellToken = _ref11.sellToken, from = _ref11.from, toVault = _ref11.toVault, options = _ref11.options;

              if (!(sellToken === EthAddress)) {
                _context14.next = 3;
                break;
              }

              return _context14.abrupt("return", {
                needsApproving: false
              });

            case 3:
              zapProtocol = this.getZapProtocol({
                vaultAddress: toVault
              });
              _context14.next = 6;
              return this.yearn.services.zapper.zapInApprovalState(from, sellToken, zapProtocol).then(function (state) {
                return !state.isApproved;
              })["catch"](function () {
                throw new ZapperError("approval state", ZapperError.ZAP_IN_APPROVAL_STATE);
              });

            case 6:
              isApprovalNeeded = _context14.sent;

              if (isApprovalNeeded) {
                _context14.next = 9;
                break;
              }

              return _context14.abrupt("return", {
                needsApproving: false
              });

            case 9:
              _context14.next = 11;
              return this.simulationExecutor.createFork();

            case 11:
              forkId = _context14.sent;
              _context14.next = 14;
              return this.yearn.services.zapper.zapInApprovalTransaction(from, sellToken, "0", zapProtocol)["catch"](function () {
                throw new ZapperError("approval", ZapperError.ZAP_IN_APPROVAL);
              }).then( /*#__PURE__*/function () {
                var _ref13 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee13(_ref12) {
                  var from, to, data;
                  return runtime_1.wrap(function _callee13$(_context13) {
                    while (1) {
                      switch (_context13.prev = _context13.next) {
                        case 0:
                          from = _ref12.from, to = _ref12.to, data = _ref12.data;
                          return _context13.abrupt("return", _this5.simulationExecutor.makeSimulationRequest(from, to, data, _extends({}, options, {
                            forkId: forkId,
                            save: true
                          })));

                        case 2:
                        case "end":
                          return _context13.stop();
                      }
                    }
                  }, _callee13);
                }));

                return function (_x21) {
                  return _ref13.apply(this, arguments);
                };
              }()).then(function (res) {
                return res.simulation.id;
              });

            case 14:
              approvalTransactionId = _context14.sent;
              return _context14.abrupt("return", {
                needsApproving: true,
                approvalTransactionId: approvalTransactionId,
                forkId: forkId
              });

            case 16:
            case "end":
              return _context14.stop();
          }
        }
      }, _callee14, this);
    }));

    function getZapperZapInApprovalData(_x20) {
      return _getZapperZapInApprovalData.apply(this, arguments);
    }

    return getZapperZapInApprovalData;
  }();

  _proto.getZapperZapInSimulationArgs = /*#__PURE__*/function () {
    var _getZapperZapInSimulationArgs = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee15(_ref14) {
      var _this6 = this;

      var depositArgs, vault, _yield$this$getZapper, needsApproving, approvalTransactionId, forkId, simulateFn;

      return runtime_1.wrap(function _callee15$(_context15) {
        while (1) {
          switch (_context15.prev = _context15.next) {
            case 0:
              depositArgs = _ref14.depositArgs, vault = _ref14.vault;

              if (depositArgs.options.slippage) {
                _context15.next = 3;
                break;
              }

              throw new SdkError("slippage needs to be specified for a zap", SdkError.NO_SLIPPAGE);

            case 3:
              _context15.next = 5;
              return this.getZapperZapInApprovalData(depositArgs);

            case 5:
              _yield$this$getZapper = _context15.sent;
              needsApproving = _yield$this$getZapper.needsApproving;
              approvalTransactionId = _yield$this$getZapper.approvalTransactionId;
              forkId = _yield$this$getZapper.forkId;

              simulateFn = function simulateFn(save) {
                return _this6.zapIn({
                  depositArgs: _extends({}, depositArgs, {
                    options: _extends({}, depositArgs.options, {
                      forkId: forkId,
                      save: save,
                      root: approvalTransactionId
                    })
                  }),
                  vault: vault,
                  skipGasEstimate: needsApproving
                });
              };

              return _context15.abrupt("return", {
                simulateFn: simulateFn,
                forkId: forkId
              });

            case 11:
            case "end":
              return _context15.stop();
          }
        }
      }, _callee15, this);
    }));

    function getZapperZapInSimulationArgs(_x22) {
      return _getZapperZapInSimulationArgs.apply(this, arguments);
    }

    return getZapperZapInSimulationArgs;
  }();

  _proto.approve = /*#__PURE__*/function () {
    var _approve = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee16(_ref15) {
      var from, sellToken, amount, toVault, options, tokenAbi, signer, tokenContract, addressToApprove, encodedInputData, simulationResponse;
      return runtime_1.wrap(function _callee16$(_context16) {
        while (1) {
          switch (_context16.prev = _context16.next) {
            case 0:
              from = _ref15.from, sellToken = _ref15.sellToken, amount = _ref15.amount, toVault = _ref15.toVault, options = _ref15.options;
              tokenAbi = ["function approve(address spender, uint256 amount) returns (bool)"];
              signer = this.ctx.provider.write.getSigner(from);
              tokenContract = new contracts.Contract(sellToken, tokenAbi, signer);
              _context16.next = 6;
              return this.getActionableAddress({
                toVault: toVault
              });

            case 6:
              addressToApprove = _context16.sent;
              encodedInputData = tokenContract["interface"].encodeFunctionData("approve", [addressToApprove, amount]);
              _context16.next = 10;
              return this.simulationExecutor.makeSimulationRequest(from, sellToken, encodedInputData, _extends({}, options, {
                save: true
              }));

            case 10:
              simulationResponse = _context16.sent;
              return _context16.abrupt("return", simulationResponse.simulation.id);

            case 12:
            case "end":
              return _context16.stop();
          }
        }
      }, _callee16, this);
    }));

    function approve(_x23) {
      return _approve.apply(this, arguments);
    }

    return approve;
  }();

  _proto.getApprovalData = /*#__PURE__*/function () {
    var _getApprovalData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee17(_ref16) {
      var depositArgs, signer, depositNeedsApproving, forkId, approvalTransactionId;
      return runtime_1.wrap(function _callee17$(_context17) {
        while (1) {
          switch (_context17.prev = _context17.next) {
            case 0:
              depositArgs = _ref16.depositArgs, signer = _ref16.signer;
              _context17.next = 3;
              return this.depositNeedsApproving({
                depositArgs: depositArgs,
                signer: signer
              });

            case 3:
              depositNeedsApproving = _context17.sent;

              if (depositNeedsApproving) {
                _context17.next = 6;
                break;
              }

              return _context17.abrupt("return", {});

            case 6:
              _context17.next = 8;
              return this.simulationExecutor.createFork();

            case 8:
              forkId = _context17.sent;
              _context17.next = 11;
              return this.approve(_extends({}, depositArgs, {
                options: _extends({}, depositArgs.options, {
                  forkId: forkId
                })
              }));

            case 11:
              approvalTransactionId = _context17.sent;
              return _context17.abrupt("return", {
                approvalTransactionId: approvalTransactionId,
                forkId: forkId
              });

            case 13:
            case "end":
              return _context17.stop();
          }
        }
      }, _callee17, this);
    }));

    function getApprovalData(_x24) {
      return _getApprovalData.apply(this, arguments);
    }

    return getApprovalData;
  }();

  _proto.getVaultContract = function getVaultContract(_ref17) {
    var toVault = _ref17.toVault,
        signer = _ref17.signer;
    var zapProtocol = this.getZapProtocol({
      vaultAddress: toVault
    });
    return zapProtocol === exports.ZapProtocol.PICKLE ? new PickleJarContract(toVault, signer) : new YearnVaultContract(toVault, signer);
  };

  _proto.handleZapInSimulationDeposit = /*#__PURE__*/function () {
    var _handleZapInSimulationDeposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee18(_ref18) {
      var zapInWith, vault, depositArgs, _yield$this$getZapper2, simulateFn, _forkId;

      return runtime_1.wrap(function _callee18$(_context18) {
        while (1) {
          switch (_context18.prev = _context18.next) {
            case 0:
              zapInWith = _ref18.zapInWith, vault = _ref18.vault, depositArgs = _ref18.depositArgs;

              if (!(zapInWith === "zapperZapIn")) {
                _context18.next = 8;
                break;
              }

              _context18.next = 4;
              return this.getZapperZapInSimulationArgs({
                depositArgs: depositArgs,
                vault: vault
              });

            case 4:
              _yield$this$getZapper2 = _context18.sent;
              simulateFn = _yield$this$getZapper2.simulateFn;
              _forkId = _yield$this$getZapper2.forkId;
              return _context18.abrupt("return", this.simulationExecutor.executeSimulationWithReSimulationOnFailure(simulateFn, _forkId));

            case 8:
              if (!(zapInWith === "ftmApeZap")) {
                _context18.next = 10;
                break;
              }

              throw new SdkError("ftmApeZap not implemented yet!");

            case 10:
              throw new SdkError("zapInWith \"" + zapInWith + "\" not supported yet!");

            case 11:
            case "end":
              return _context18.stop();
          }
        }
      }, _callee18, this);
    }));

    function handleZapInSimulationDeposit(_x25) {
      return _handleZapInSimulationDeposit.apply(this, arguments);
    }

    return handleZapInSimulationDeposit;
  }();

  _proto.isUnderlyingToken = /*#__PURE__*/function () {
    var _isUnderlyingToken = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee19(_ref19) {
      var vault, address;
      return runtime_1.wrap(function _callee19$(_context19) {
        while (1) {
          switch (_context19.prev = _context19.next) {
            case 0:
              vault = _ref19.vault, address = _ref19.address;

              if (!PickleJars.includes(vault)) {
                _context19.next = 3;
                break;
              }

              return _context19.abrupt("return", false);

            case 3:
              return _context19.abrupt("return", this.yearn.vaults.isUnderlyingToken(vault, address));

            case 4:
            case "end":
              return _context19.stop();
          }
        }
      }, _callee19, this);
    }));

    function isUnderlyingToken(_x26) {
      return _isUnderlyingToken.apply(this, arguments);
    }

    return isUnderlyingToken;
  }();

  _proto.getZappableVault = /*#__PURE__*/function () {
    var _getZappableVault = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee20(_ref20) {
      var vaultAddress, vaultContract, zapProtocol, _yield$Promise$all, decimals, pricePerShare, _yield$this$yearn$vau2, vault;

      return runtime_1.wrap(function _callee20$(_context20) {
        while (1) {
          switch (_context20.prev = _context20.next) {
            case 0:
              vaultAddress = _ref20.vaultAddress, vaultContract = _ref20.vaultContract;
              zapProtocol = this.getZapProtocol({
                vaultAddress: vaultAddress
              });

              if (!(zapProtocol === exports.ZapProtocol.PICKLE)) {
                _context20.next = 9;
                break;
              }

              _context20.next = 5;
              return Promise.all([vaultContract.decimals()["catch"](function () {
                throw new EthersError("no decimals", EthersError.NO_DECIMALS);
              }), vaultContract.pricePerShare()["catch"](function () {
                throw new EthersError("no price per share", EthersError.NO_PRICE_PER_SHARE);
              })]);

            case 5:
              _yield$Promise$all = _context20.sent;
              decimals = _yield$Promise$all[0];
              pricePerShare = _yield$Promise$all[1];
              return _context20.abrupt("return", {
                address: vaultAddress,
                token: "0x9461173740d27311b176476fa27e94c681b1ea6b",
                decimals: decimals.toString(),
                metadata: {
                  zapInWith: "zapperZapIn",
                  zapOutWith: "zapperZapOut",
                  pricePerShare: pricePerShare.toString()
                }
              });

            case 9:
              _context20.next = 11;
              return this.yearn.vaults.get([vaultAddress]);

            case 11:
              _yield$this$yearn$vau2 = _context20.sent;
              vault = _yield$this$yearn$vau2[0];
              return _context20.abrupt("return", vault);

            case 14:
            case "end":
              return _context20.stop();
          }
        }
      }, _callee20, this);
    }));

    function getZappableVault(_x27) {
      return _getZappableVault.apply(this, arguments);
    }

    return getZappableVault;
  }();

  _proto.getZapProtocol = function getZapProtocol(_ref21) {
    var vaultAddress = _ref21.vaultAddress;
    return PickleJars.includes(vaultAddress) ? exports.ZapProtocol.PICKLE : exports.ZapProtocol.YEARN;
  };

  _proto.getZapperZapOutSimulationArgs = /*#__PURE__*/function () {
    var _getZapperZapOutSimulationArgs = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee21(_ref22) {
      var _this7 = this;

      var withdrawArgs, underlyingTokenAddress, _yield$this$getWithdr, needsApproving, root, forkId, simulateFn;

      return runtime_1.wrap(function _callee21$(_context21) {
        while (1) {
          switch (_context21.prev = _context21.next) {
            case 0:
              withdrawArgs = _ref22.withdrawArgs, underlyingTokenAddress = _ref22.token.address;

              if (withdrawArgs.options.slippage) {
                _context21.next = 3;
                break;
              }

              throw new SdkError("slippage needs to be specified for a zap", SdkError.NO_SLIPPAGE);

            case 3:
              _context21.next = 5;
              return this.getWithdrawApprovalData(withdrawArgs);

            case 5:
              _yield$this$getWithdr = _context21.sent;
              needsApproving = _yield$this$getWithdr.needsApproving;
              root = _yield$this$getWithdr.root;
              forkId = _yield$this$getWithdr.forkId;

              simulateFn = function simulateFn(save) {
                return _this7.zapOut(_extends({}, withdrawArgs, {
                  underlyingTokenAddress: underlyingTokenAddress,
                  skipGasEstimate: needsApproving,
                  options: _extends({}, withdrawArgs.options, {
                    root: root,
                    forkId: forkId,
                    save: save
                  })
                }));
              };

              return _context21.abrupt("return", {
                simulateFn: simulateFn,
                forkId: forkId
              });

            case 11:
            case "end":
              return _context21.stop();
          }
        }
      }, _callee21, this);
    }));

    function getZapperZapOutSimulationArgs(_x28) {
      return _getZapperZapOutSimulationArgs.apply(this, arguments);
    }

    return getZapperZapOutSimulationArgs;
  }();

  _proto.handleZapOutSimulation = /*#__PURE__*/function () {
    var _handleZapOutSimulation = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee22(_ref23) {
      var zapOutWith, token, withdrawArgs, _yield$this$getZapper3, simulateFn, _forkId2;

      return runtime_1.wrap(function _callee22$(_context22) {
        while (1) {
          switch (_context22.prev = _context22.next) {
            case 0:
              zapOutWith = _ref23.zapOutWith, token = _ref23.token, withdrawArgs = _ref23.withdrawArgs;

              if (!(zapOutWith === "zapperZapOut")) {
                _context22.next = 8;
                break;
              }

              _context22.next = 4;
              return this.getZapperZapOutSimulationArgs({
                withdrawArgs: withdrawArgs,
                token: token
              });

            case 4:
              _yield$this$getZapper3 = _context22.sent;
              simulateFn = _yield$this$getZapper3.simulateFn;
              _forkId2 = _yield$this$getZapper3.forkId;
              return _context22.abrupt("return", this.simulationExecutor.executeSimulationWithReSimulationOnFailure(simulateFn, _forkId2));

            case 8:
              if (!(zapOutWith === "ftmApeZap")) {
                _context22.next = 10;
                break;
              }

              throw new SdkError("ftmApeZap not implemented yet!");

            case 10:
              throw new SdkError("zapOutWith \"" + zapOutWith + "\" not supported yet!");

            case 11:
            case "end":
              return _context22.stop();
          }
        }
      }, _callee22, this);
    }));

    function handleZapOutSimulation(_x29) {
      return _handleZapOutSimulation.apply(this, arguments);
    }

    return handleZapOutSimulation;
  }();

  return SimulationInterface;
}(ServiceInterface);

var getLocalizedString = function getLocalizedString(_ref) {
  var _ref2, _obj$localization$loc, _obj$localization$loc2;

  var obj = _ref.obj,
      property = _ref.property,
      locale = _ref.locale,
      fallback = _ref.fallback;
  return (_ref2 = (_obj$localization$loc = obj == null ? void 0 : (_obj$localization$loc2 = obj.localization[locale]) == null ? void 0 : _obj$localization$loc2.description) != null ? _obj$localization$loc : obj && property && obj[property]) != null ? _ref2 : fallback;
};

var VaultAbi = ["function strategies(address) view returns (uint256 performanceFee, uint256 activation, uint256 debtRatio, uint256 rateLimit, uint256 lastReport, uint256 totalDebt, uint256 totalGain, uint256 totalLoss)", "function token() view returns (address)", "event StrategyAdded(address indexed strategy, uint256 debtRatio, uint256 minDebtPerHarvest, uint256 maxDebtPerHarvest, uint256 performanceFee)"];
var TokenAbi = ["function symbol() view returns (string)"];
var StrategyInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(StrategyInterface, _ServiceInterface);

  function StrategyInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.cachedFetcher = new CachedFetcher("strategies/metadata/get", _this.ctx, _this.chainId);
    return _this;
  }

  var _proto = StrategyInterface.prototype;

  _proto.vaultsStrategiesMetadata = /*#__PURE__*/function () {
    var _vaultsStrategiesMetadata = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(vaultAddresses) {
      var cached, vaults, vaultStrategiesMetadata;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.cachedFetcher.fetch();

            case 2:
              cached = _context.sent;

              if (!cached) {
                _context.next = 5;
                break;
              }

              return _context.abrupt("return", cached);

            case 5:
              if (!vaultAddresses) {
                _context.next = 9;
                break;
              }

              vaults = vaultAddresses;
              _context.next = 12;
              break;

            case 9:
              _context.next = 11;
              return this.yearn.services.lens.adapters.vaults.v2.assetsStatic().then(function (assets) {
                return assets.map(function (asset) {
                  return asset.address;
                });
              });

            case 11:
              vaults = _context.sent;

            case 12:
              _context.prev = 12;
              _context.next = 15;
              return this.fetchMetadataFromApi(vaults);

            case 15:
              vaultStrategiesMetadata = _context.sent;
              _context.next = 21;
              break;

            case 18:
              _context.prev = 18;
              _context.t0 = _context["catch"](12);
              console.error(_context.t0);

            case 21:
              if (vaultStrategiesMetadata) {
                _context.next = 25;
                break;
              }

              _context.next = 24;
              return this.fetchMetadataFromChain(vaults);

            case 24:
              vaultStrategiesMetadata = _context.sent;

            case 25:
              return _context.abrupt("return", vaultStrategiesMetadata);

            case 26:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this, [[12, 18]]);
    }));

    function vaultsStrategiesMetadata(_x) {
      return _vaultsStrategiesMetadata.apply(this, arguments);
    }

    return vaultsStrategiesMetadata;
  }();

  _proto.fetchMetadataFromApi = /*#__PURE__*/function () {
    var _fetchMetadataFromApi = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(vaultAddresses) {
      var _this2 = this;

      var vaultsData, strategiesMetadata, vaultsStrategiesMetadataPromises;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return this.fetchVaultsData();

            case 2:
              vaultsData = _context3.sent;
              _context3.next = 5;
              return this.yearn.services.meta.strategies();

            case 5:
              strategiesMetadata = _context3.sent;
              vaultsStrategiesMetadataPromises = vaultAddresses.map( /*#__PURE__*/function () {
                var _ref = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(vaultAddress) {
                  var vaultDatum, vaultContract;
                  return runtime_1.wrap(function _callee2$(_context2) {
                    while (1) {
                      switch (_context2.prev = _context2.next) {
                        case 0:
                          vaultDatum = vaultsData.find(function (datum) {
                            return datum.address === vaultAddress;
                          });

                          if (vaultDatum) {
                            _context2.next = 3;
                            break;
                          }

                          return _context2.abrupt("return", undefined);

                        case 3:
                          vaultContract = new contracts.Contract(vaultDatum.address, VaultAbi, _this2.ctx.provider.read);
                          return _context2.abrupt("return", _this2.fetchVaultStrategiesMetadata(vaultDatum.strategies, strategiesMetadata, vaultContract, vaultDatum.token.symbol));

                        case 5:
                        case "end":
                          return _context2.stop();
                      }
                    }
                  }, _callee2);
                }));

                return function (_x3) {
                  return _ref.apply(this, arguments);
                };
              }());
              return _context3.abrupt("return", Promise.all(vaultsStrategiesMetadataPromises).then(function (vaultsStrategyData) {
                return vaultsStrategyData.flatMap(function (data) {
                  return data ? [data] : [];
                });
              }));

            case 8:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function fetchMetadataFromApi(_x2) {
      return _fetchMetadataFromApi.apply(this, arguments);
    }

    return fetchMetadataFromApi;
  }();

  _proto.fetchMetadataFromChain = /*#__PURE__*/function () {
    var _fetchMetadataFromChain = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(vaultAddresses) {
      var _this3 = this;

      var strategiesMetadata, provider, vaultsStrategiesMetadataPromises;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              _context5.next = 2;
              return this.yearn.services.meta.strategies();

            case 2:
              strategiesMetadata = _context5.sent;
              provider = this.ctx.provider.read;
              vaultsStrategiesMetadataPromises = vaultAddresses.map( /*#__PURE__*/function () {
                var _ref2 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(vaultAddress) {
                  var vaultContract, strategiesPromise, _yield$Promise$all, strategies, underlyingTokenAddress, underlyingTokenContract, underlyingTokenSymbol;

                  return runtime_1.wrap(function _callee4$(_context4) {
                    while (1) {
                      switch (_context4.prev = _context4.next) {
                        case 0:
                          vaultContract = new contracts.Contract(vaultAddress, VaultAbi, provider);
                          strategiesPromise = _this3.yearn.services.helper.assetStrategiesAddresses(vaultAddress).then(function (addresses) {
                            return addresses.map(function (strat) {
                              return {
                                address: strat
                              };
                            });
                          });
                          _context4.next = 4;
                          return Promise.all([strategiesPromise, vaultContract.token()]);

                        case 4:
                          _yield$Promise$all = _context4.sent;
                          strategies = _yield$Promise$all[0];
                          underlyingTokenAddress = _yield$Promise$all[1];
                          underlyingTokenContract = new contracts.Contract(underlyingTokenAddress, TokenAbi, provider);
                          _context4.next = 10;
                          return underlyingTokenContract.symbol();

                        case 10:
                          underlyingTokenSymbol = _context4.sent;
                          return _context4.abrupt("return", _this3.fetchVaultStrategiesMetadata(strategies, strategiesMetadata, vaultContract, underlyingTokenSymbol));

                        case 12:
                        case "end":
                          return _context4.stop();
                      }
                    }
                  }, _callee4);
                }));

                return function (_x5) {
                  return _ref2.apply(this, arguments);
                };
              }());
              return _context5.abrupt("return", Promise.all(vaultsStrategiesMetadataPromises).then(function (vaultsStrategyData) {
                return vaultsStrategyData.flatMap(function (data) {
                  return data ? [data] : [];
                });
              }));

            case 6:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function fetchMetadataFromChain(_x4) {
      return _fetchMetadataFromChain.apply(this, arguments);
    }

    return fetchMetadataFromChain;
  }();

  _proto.fetchVaultStrategiesMetadata = /*#__PURE__*/function () {
    var _fetchVaultStrategiesMetadata = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(strategies, strategiesMetadata, vaultContract, underlyingTokenSymbol) {
      var _this4 = this;

      var metadata, result;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              if (!(strategies.length === 0)) {
                _context7.next = 2;
                break;
              }

              return _context7.abrupt("return", undefined);

            case 2:
              _context7.next = 4;
              return Promise.all(strategies.map( /*#__PURE__*/function () {
                var _ref3 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(strategy) {
                  var _metadatum$protocols;

                  var debtRatio, struct, metadatum, metadata;
                  return runtime_1.wrap(function _callee6$(_context6) {
                    while (1) {
                      switch (_context6.prev = _context6.next) {
                        case 0:
                          _context6.prev = 0;
                          _context6.next = 3;
                          return vaultContract.strategies(strategy.address);

                        case 3:
                          struct = _context6.sent;
                          debtRatio = struct.debtRatio;
                          _context6.next = 10;
                          break;

                        case 7:
                          _context6.prev = 7;
                          _context6.t0 = _context6["catch"](0);
                          return _context6.abrupt("return", undefined);

                        case 10:
                          if (!debtRatio.lte(bignumber.BigNumber.from("0"))) {
                            _context6.next = 12;
                            break;
                          }

                          return _context6.abrupt("return", undefined);

                        case 12:
                          metadatum = strategiesMetadata.find(function (strategiesMetadata) {
                            return strategiesMetadata.addresses.includes(strategy.address);
                          });
                          metadata = {
                            address: strategy.address,
                            name: (metadatum == null ? void 0 : metadatum.name) || strategy.name || "Strategy",
                            description: getLocalizedString({
                              obj: metadatum,
                              property: "description",
                              locale: _this4.ctx.locale,
                              fallback: "Vault strategy missing"
                            }),
                            protocols: (_metadatum$protocols = metadatum == null ? void 0 : metadatum.protocols) != null ? _metadatum$protocols : []
                          };
                          metadata.description = metadata == null ? void 0 : metadata.description.replace(/{{token}}/g, underlyingTokenSymbol);
                          return _context6.abrupt("return", {
                            data: metadata,
                            debtRatio: debtRatio
                          });

                        case 16:
                        case "end":
                          return _context6.stop();
                      }
                    }
                  }, _callee6, null, [[0, 7]]);
                }));

                return function (_x10) {
                  return _ref3.apply(this, arguments);
                };
              }())).then(function (metadataAndDebtRatio) {
                return metadataAndDebtRatio.flatMap(function (data) {
                  return data ? [data] : [];
                }).sort(function (lhs, rhs) {
                  if (lhs.debtRatio.lt(rhs.debtRatio)) {
                    return 1;
                  } else if (lhs.debtRatio.eq(rhs.debtRatio)) {
                    return 0;
                  } else {
                    return -1;
                  }
                }).map(function (metadata) {
                  return metadata.data;
                });
              });

            case 4:
              metadata = _context7.sent;

              if (!(metadata.length === 0)) {
                _context7.next = 7;
                break;
              }

              return _context7.abrupt("return", undefined);

            case 7:
              result = {
                vaultAddress: vaultContract.address,
                strategiesMetadata: metadata
              };
              return _context7.abrupt("return", result);

            case 9:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7);
    }));

    function fetchVaultStrategiesMetadata(_x6, _x7, _x8, _x9) {
      return _fetchVaultStrategiesMetadata.apply(this, arguments);
    }

    return fetchVaultStrategiesMetadata;
  }();

  _proto.fetchVaultsData = /*#__PURE__*/function () {
    var _fetchVaultsData = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8() {
      var res;
      return runtime_1.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              _context8.next = 2;
              return fetch$1("https://api.yearn.finance/v1/chains/" + this.chainId + "/vaults/all");

            case 2:
              res = _context8.sent;

              if (res.ok) {
                _context8.next = 5;
                break;
              }

              throw new Error("An error has occured fetching vaults data: " + res.status);

            case 5:
              _context8.next = 7;
              return res.json();

            case 7:
              return _context8.abrupt("return", _context8.sent);

            case 8:
            case "end":
              return _context8.stop();
          }
        }
      }, _callee8, this);
    }));

    function fetchVaultsData() {
      return _fetchVaultsData.apply(this, arguments);
    }

    return fetchVaultsData;
  }();

  return StrategyInterface;
}(ServiceInterface);

var TokenAbi$1 = ["function approve(address _spender, uint256 _value) public", "function allowance(address _owner, address _spender) public view returns (uint256)"];
var TokenInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(TokenInterface, _ServiceInterface);

  function TokenInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.cachedFetcherSupported = new CachedFetcher("tokens/supported", _this.ctx, _this.chainId);
    _this.cachedFetcher = new CachedFetcher("tokens/metadata", _this.ctx, _this.chainId);
    return _this;
  }
  /**
   * Get exchange rate between two tokens.
   * @param from
   * @param to
   * @returns exchange rate
   */


  var _proto = TokenInterface.prototype;

  _proto.price =
  /*#__PURE__*/
  function () {
    var _price = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(from, to) {
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              return _context.abrupt("return", this.yearn.services.oracle.getPriceFromRouter(from, to));

            case 1:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function price(_x, _x2) {
      return _price.apply(this, arguments);
    }

    return price;
  }();

  _proto.priceUsdc = /*#__PURE__*/function () {
    var _priceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(tokens, overrides) {
      var _this2 = this;

      var entries;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (Chains[this.chainId]) {
                _context3.next = 2;
                break;
              }

              throw new SdkError("the chain " + this.chainId + " hasn't been implemented yet");

            case 2:
              if (!Array.isArray(tokens)) {
                _context3.next = 7;
                break;
              }

              _context3.next = 5;
              return Promise.all(tokens.map( /*#__PURE__*/function () {
                var _ref = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(token) {
                  var price;
                  return runtime_1.wrap(function _callee2$(_context2) {
                    while (1) {
                      switch (_context2.prev = _context2.next) {
                        case 0:
                          _context2.next = 2;
                          return _this2.yearn.services.oracle.getPriceUsdc(token, overrides);

                        case 2:
                          price = _context2.sent;
                          return _context2.abrupt("return", [token, price]);

                        case 4:
                        case "end":
                          return _context2.stop();
                      }
                    }
                  }, _callee2);
                }));

                return function (_x5) {
                  return _ref.apply(this, arguments);
                };
              }()));

            case 5:
              entries = _context3.sent;
              return _context3.abrupt("return", Object.fromEntries(entries));

            case 7:
              return _context3.abrupt("return", this.yearn.services.oracle.getPriceUsdc(tokens, overrides));

            case 8:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function priceUsdc(_x3, _x4) {
      return _priceUsdc.apply(this, arguments);
    }

    return priceUsdc;
  }()
  /**
   * Fetch token balance for a particular account and token addresses.
   *
   * @param account user wallet address
   * @param tokenAddresses list of token addresses
   *
   * @returns list of balances for the supported tokens
   */
  ;

  _proto.balances =
  /*#__PURE__*/
  function () {
    var _balances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(account, tokenAddresses) {
      var tokens, addresses, balances, zapperBalances, balance, priceUsdc, _balance, _priceUsdc2, vaultBalances, ironBankBalances;

      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return this.supported();

            case 2:
              tokens = _context4.sent;

              if (tokenAddresses) {
                tokens = tokens.filter(function (_ref2) {
                  var address = _ref2.address;
                  return tokenAddresses.includes(address);
                });
              }

              addresses = tokens.reduce(function (acc, _ref3) {
                var address = _ref3.address,
                    dataSource = _ref3.dataSource;
                acc[dataSource].add(address);
                return acc;
              }, {
                zapper: new Set(),
                vaults: new Set(),
                ironBank: new Set(),
                labs: new Set(),
                sdk: new Set()
              });
              balances = {
                zapper: [],
                vaults: [],
                ironBank: [],
                labs: [],
                sdk: []
              };

              if (!isEthereum(this.chainId)) {
                _context4.next = 30;
                break;
              }

              _context4.prev = 7;
              _context4.next = 10;
              return this.yearn.services.zapper.balances(account);

            case 10:
              zapperBalances = _context4.sent;
              balances.zapper = zapperBalances.filter(function (_ref4) {
                var address = _ref4.address;
                return addresses.zapper.has(address);
              });
              _context4.next = 17;
              break;

            case 14:
              _context4.prev = 14;
              _context4.t0 = _context4["catch"](7);
              console.error(_context4.t0);

            case 17:
              _context4.prev = 17;
              _context4.next = 20;
              return this.ctx.provider.read.getBalance(account);

            case 20:
              balance = _context4.sent;
              _context4.next = 23;
              return this.yearn.services.oracle.getPriceUsdc(EthAddress);

            case 23:
              priceUsdc = _context4.sent;
              balances.sdk = [{
                address: EthAddress,
                token: ETH_TOKEN,
                balance: balance.toString(),
                balanceUsdc: new BigNumber__default(balance.toString()).div(Math.pow(10, 18)).times(new BigNumber__default(priceUsdc)).toString(),
                priceUsdc: priceUsdc
              }];
              _context4.next = 30;
              break;

            case 27:
              _context4.prev = 27;
              _context4.t1 = _context4["catch"](17);
              console.error(_context4.t1);

            case 30:
              if (!isFantom(this.chainId)) {
                _context4.next = 38;
                break;
              }

              _context4.next = 33;
              return this.ctx.provider.read.getBalance(account);

            case 33:
              _balance = _context4.sent;
              _context4.next = 36;
              return this.yearn.services.oracle.getPriceUsdc(WrappedFantomAddress);

            case 36:
              _priceUsdc2 = _context4.sent;
              balances.sdk = [{
                address: account,
                token: FANTOM_TOKEN,
                balance: _balance.toString(),
                balanceUsdc: new BigNumber__default(_balance.toString()).div(Math.pow(10, 18)).times(new BigNumber__default(_priceUsdc2)).toString(),
                priceUsdc: _priceUsdc2
              }];

            case 38:
              if (!allSupportedChains.includes(this.chainId)) {
                _context4.next = 48;
                break;
              }

              _context4.next = 41;
              return this.yearn.vaults.balances(account);

            case 41:
              vaultBalances = _context4.sent;
              balances.vaults = vaultBalances.filter(function (_ref5) {
                var address = _ref5.address,
                    balance = _ref5.balance;
                return balance !== "0" && addresses.vaults.has(address);
              });
              _context4.next = 45;
              return this.yearn.ironBank.balances(account);

            case 45:
              ironBankBalances = _context4.sent;
              balances.ironBank = ironBankBalances.filter(function (_ref6) {
                var address = _ref6.address;
                return addresses.ironBank.has(address);
              });
              return _context4.abrupt("return", [].concat(balances.vaults, balances.ironBank, balances.zapper, balances.sdk));

            case 48:
              console.error("the chain " + this.chainId + " hasn't been implemented yet");
              return _context4.abrupt("return", []);

            case 50:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this, [[7, 14], [17, 27]]);
    }));

    function balances(_x6, _x7) {
      return _balances.apply(this, arguments);
    }

    return balances;
  }()
  /**
   * Fetch all the tokens supported along with some basic metadata.
   * @returns list of tokens supported.
   */
  ;

  _proto.supported =
  /*#__PURE__*/
  function () {
    var _supported = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5() {
      var cached, zapperTokens, vaultsTokens, ironBankTokens, vaultsAndIronBankTokens, priceUsdc, allSupportedTokens, zapperTokensUniqueAddresses;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              if (allSupportedChains.includes(this.chainId)) {
                _context5.next = 3;
                break;
              }

              console.error("the chain " + this.chainId + " hasn't been implemented yet");
              return _context5.abrupt("return", []);

            case 3:
              _context5.next = 5;
              return this.cachedFetcherSupported.fetch();

            case 5:
              cached = _context5.sent;

              if (!cached) {
                _context5.next = 8;
                break;
              }

              return _context5.abrupt("return", cached);

            case 8:
              // Zapper only supported in Ethereum
              zapperTokens = [];

              if (!isEthereum(this.chainId)) {
                _context5.next = 19;
                break;
              }

              _context5.prev = 10;
              _context5.next = 13;
              return this.getZapperTokensWithIcons();

            case 13:
              zapperTokens = _context5.sent;
              _context5.next = 19;
              break;

            case 16:
              _context5.prev = 16;
              _context5.t0 = _context5["catch"](10);
              console.error(_context5.t0);

            case 19:
              _context5.next = 21;
              return this.yearn.vaults.tokens();

            case 21:
              vaultsTokens = _context5.sent;
              _context5.next = 24;
              return this.yearn.ironBank.tokens();

            case 24:
              ironBankTokens = _context5.sent;
              vaultsAndIronBankTokens = mergeByAddress(vaultsTokens, ironBankTokens);

              if (!isFantom(this.chainId)) {
                _context5.next = 31;
                break;
              }

              _context5.next = 29;
              return this.yearn.services.oracle.getPriceUsdc(WrappedFantomAddress);

            case 29:
              priceUsdc = _context5.sent;
              vaultsAndIronBankTokens.push(_extends({}, FANTOM_TOKEN, {
                priceUsdc: priceUsdc
              }));

            case 31:
              if (zapperTokens.length) {
                _context5.next = 33;
                break;
              }

              return _context5.abrupt("return", vaultsAndIronBankTokens);

            case 33:
              allSupportedTokens = mergeByAddress(vaultsAndIronBankTokens, zapperTokens);
              zapperTokensUniqueAddresses = new Set(zapperTokens.map(function (_ref7) {
                var address = _ref7.address;
                return address;
              }));
              return _context5.abrupt("return", allSupportedTokens.map(function (token) {
                var isZapperToken = zapperTokensUniqueAddresses.has(token.address);
                return _extends({}, token, isZapperToken && {
                  supported: _extends({}, token.supported, {
                    zapper: true,
                    zapperZapIn: true,
                    zapperZapOut: Object.values(SUPPORTED_ZAP_OUT_ADDRESSES_MAINNET).includes(token.address)
                  })
                });
              }));

            case 36:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this, [[10, 16]]);
    }));

    function supported() {
      return _supported.apply(this, arguments);
    }

    return supported;
  }()
  /**
   * TODO: Should get a single token directly instead of filtering
   * @param address then token address
   * @returns the token
   */
  ;

  _proto.findByAddress =
  /*#__PURE__*/
  function () {
    var _findByAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(address) {
      var supportedTokens;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              _context6.next = 2;
              return this.supported();

            case 2:
              supportedTokens = _context6.sent;
              return _context6.abrupt("return", supportedTokens.find(function (token) {
                return token.address === address;
              }));

            case 4:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function findByAddress(_x8) {
      return _findByAddress.apply(this, arguments);
    }

    return findByAddress;
  }()
  /**
   * Fetch the token amount that spender is allowed to spend on behalf of owner
   * @param ownerAddress
   * @param tokenAddress
   * @param spenderAddress
   * @returns TokenAllowance
   */
  ;

  _proto.allowance =
  /*#__PURE__*/
  function () {
    var _allowance = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(ownerAddress, tokenAddress, spenderAddress) {
      var allowance, tokenContract, allowanceAmount;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              allowance = {
                owner: ownerAddress,
                token: tokenAddress,
                spender: spenderAddress,
                amount: constants.MaxUint256.toString()
              };

              if (!(isNativeToken(tokenAddress) || tokenAddress === spenderAddress)) {
                _context7.next = 3;
                break;
              }

              return _context7.abrupt("return", allowance);

            case 3:
              tokenContract = new contracts.Contract(tokenAddress, TokenAbi$1, this.ctx.provider.read);
              _context7.next = 6;
              return tokenContract.allowance(ownerAddress, spenderAddress);

            case 6:
              allowanceAmount = _context7.sent;
              return _context7.abrupt("return", _extends({}, allowance, {
                amount: allowanceAmount.toString()
              }));

            case 8:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function allowance(_x9, _x10, _x11) {
      return _allowance.apply(this, arguments);
    }

    return allowance;
  }()
  /**
   * Returns the populated transaction to approve the token amount that spender is allowed to spend on behalf of owner
   * @param ownerAddress
   * @param tokenAddress
   * @param spenderAddress
   * @param amount
   * @param overrides
   * @returns PopulatedTransaction
   */
  ;

  _proto.populateApprove =
  /*#__PURE__*/
  function () {
    var _populateApprove = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(ownerAddress, tokenAddress, spenderAddress, amount, overrides) {
      var signer, tokenContract;
      return runtime_1.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              if (!isNativeToken(tokenAddress)) {
                _context8.next = 3;
                break;
              }

              throw new SdkError("Native tokens cant be approved: " + tokenAddress);

            case 3:
              if (!(tokenAddress === spenderAddress)) {
                _context8.next = 5;
                break;
              }

              throw new SdkError("Cant approve token as its spender: " + tokenAddress);

            case 5:
              signer = this.ctx.provider.write.getSigner(ownerAddress);
              tokenContract = new contracts.Contract(tokenAddress, TokenAbi$1, signer);
              return _context8.abrupt("return", tokenContract.populateTransaction.approve(spenderAddress, amount, overrides));

            case 8:
            case "end":
              return _context8.stop();
          }
        }
      }, _callee8, this);
    }));

    function populateApprove(_x12, _x13, _x14, _x15, _x16) {
      return _populateApprove.apply(this, arguments);
    }

    return populateApprove;
  }()
  /**
   * Approve the token amount that spender is allowed to spend on behalf of owner
   * @param ownerAddress
   * @param tokenAddress
   * @param spenderAddress
   * @param amount
   * @param overrides
   * @returns TransactionResponse
   */
  ;

  _proto.approve =
  /*#__PURE__*/
  function () {
    var _approve = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(ownerAddress, tokenAddress, spenderAddress, amount, overrides) {
      var tx;
      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context9.next = 3;
              return this.populateApprove(ownerAddress, tokenAddress, spenderAddress, amount, overrides);

            case 3:
              tx = _context9.sent;
              return _context9.abrupt("return", this.yearn.services.transaction.sendTransaction(tx));

            case 5:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function approve(_x17, _x18, _x19, _x20, _x21) {
      return _approve.apply(this, arguments);
    }

    return approve;
  }()
  /**
   * Fetches supported zapper tokens and sets their icon
   * @returns zapper tokens with icons
   */
  ;

  _proto.getZapperTokensWithIcons =
  /*#__PURE__*/
  function () {
    var _getZapperTokensWithIcons = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10() {
      var _this3 = this;

      var zapperTokens, zapperTokensAddresses, zapperTokensIcons, setIcon;
      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              _context10.next = 2;
              return this.yearn.services.zapper.supportedTokens();

            case 2:
              zapperTokens = _context10.sent;
              zapperTokensAddresses = zapperTokens.map(function (_ref8) {
                var address = _ref8.address;
                return address;
              });
              _context10.next = 6;
              return this.yearn.services.asset.ready.then(function () {
                return _this3.yearn.services.asset.icon(zapperTokensAddresses);
              });

            case 6:
              zapperTokensIcons = _context10.sent;

              setIcon = function setIcon(token) {
                var icon = zapperTokensIcons[token.address];
                return icon ? _extends({}, token, {
                  icon: icon
                }) : token;
              };

              return _context10.abrupt("return", zapperTokens.map(setIcon));

            case 9:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function getZapperTokensWithIcons() {
      return _getZapperTokensWithIcons.apply(this, arguments);
    }

    return getZapperTokensWithIcons;
  }();

  _proto.icon = function icon(address) {
    return this.yearn.services.asset.icon(address);
  };

  _proto.metadata = /*#__PURE__*/function () {
    var _metadata = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11(addresses) {
      var result, cached;
      return runtime_1.wrap(function _callee11$(_context11) {
        while (1) {
          switch (_context11.prev = _context11.next) {
            case 0:
              _context11.next = 2;
              return this.cachedFetcher.fetch();

            case 2:
              cached = _context11.sent;

              if (!cached) {
                _context11.next = 7;
                break;
              }

              result = cached;
              _context11.next = 10;
              break;

            case 7:
              _context11.next = 9;
              return this.yearn.services.meta.tokens();

            case 9:
              result = _context11.sent;

            case 10:
              if (!addresses) {
                _context11.next = 14;
                break;
              }

              return _context11.abrupt("return", result.filter(function (metadata) {
                return addresses.includes(metadata.address);
              }));

            case 14:
              return _context11.abrupt("return", result);

            case 15:
            case "end":
              return _context11.stop();
          }
        }
      }, _callee11, this);
    }));

    function metadata(_x22) {
      return _metadata.apply(this, arguments);
    }

    return metadata;
  }();

  return TokenInterface;
}(ServiceInterface);

/**
 * Helper function to set the zap properties on an Addressable
 * @param addressables an array of objects with an address prop
 * @param supportedVaultAddresses the supported vault addresses
 * @returns the updated metadata
 */

function mergeZapPropsWithAddressables(_ref) {
  var addressables = _ref.addressables,
      supportedVaultAddresses = _ref.supportedVaultAddresses,
      zapInType = _ref.zapInType,
      zapOutType = _ref.zapOutType;
  var supportedVaultAddressesSet = new Set(supportedVaultAddresses);
  return addressables.map(function (addressable) {
    try {
      var address$1 = address.getAddress(addressable.address);
      var isZappable = supportedVaultAddressesSet.has(address$1);
      return _extends({}, addressable, {
        allowZapIn: isZappable,
        allowZapOut: isZappable,
        zapInWith: isZappable ? zapInType : undefined,
        zapOutWith: isZappable ? zapOutType : undefined
      });
    } catch (error) {
      return addressable;
    }
  });
}

var VaultAbi$1 = ["function deposit(uint256 amount) public", "function withdraw(uint256 amount) public"];
var VaultInterface = /*#__PURE__*/function (_ServiceInterface) {
  _inheritsLoose(VaultInterface, _ServiceInterface);

  function VaultInterface() {
    var _this;

    _this = _ServiceInterface.apply(this, arguments) || this;
    _this.cachedFetcherGet = new CachedFetcher("vaults/get", _this.ctx, _this.chainId);
    _this.cachedFetcherGetDynamic = new CachedFetcher("vaults/getDynamic", _this.ctx, _this.chainId);
    _this.cachedFetcherTokens = new CachedFetcher("vaults/tokens", _this.ctx, _this.chainId);
    return _this;
  }
  /**
   * Get all yearn vaults.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */


  var _proto = VaultInterface.prototype;

  _proto.get =
  /*#__PURE__*/
  function () {
    var _get = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses, overrides) {
      var _this2 = this;

      var cached, vaultMetadataOverridesPromise, _yield$Promise$all, vaultMetadataOverrides, assetsStatic, assetsDynamic, allAddresses, chunks, promises, strategiesMetadataPromise, assetsHistoricEarningsPromise, _yield$Promise$all2, strategiesMetadata, assetsHistoricEarnings, assetsWithOrder, _loop, _iterator, _step, _ret;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.cachedFetcherGet.fetch();

            case 2:
              cached = _context2.sent;

              if (!cached) {
                _context2.next = 9;
                break;
              }

              if (!addresses) {
                _context2.next = 8;
                break;
              }

              return _context2.abrupt("return", cached.filter(function (vault) {
                return addresses.includes(vault.address);
              }));

            case 8:
              return _context2.abrupt("return", cached);

            case 9:
              vaultMetadataOverridesPromise = this.yearn.services.meta.vaults()["catch"](function (error) {
                console.error(error);
                return Promise.resolve([]);
              });
              _context2.next = 12;
              return Promise.all([vaultMetadataOverridesPromise, this.getStatic(addresses, overrides)]);

            case 12:
              _yield$Promise$all = _context2.sent;
              vaultMetadataOverrides = _yield$Promise$all[0];
              assetsStatic = _yield$Promise$all[1];
              assetsDynamic = [];
              _context2.prev = 16;
              _context2.next = 19;
              return this.getDynamic(addresses, vaultMetadataOverrides, overrides);

            case 19:
              assetsDynamic = _context2.sent;
              _context2.next = 30;
              break;

            case 22:
              _context2.prev = 22;
              _context2.t0 = _context2["catch"](16);
              allAddresses = assetsStatic.map(function (asset) {
                return asset.address;
              });
              chunks = chunkArray(allAddresses, 30);
              promises = chunks.map( /*#__PURE__*/function () {
                var _ref = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(chunk) {
                  return runtime_1.wrap(function _callee$(_context) {
                    while (1) {
                      switch (_context.prev = _context.next) {
                        case 0:
                          return _context.abrupt("return", _this2.getDynamic(chunk, vaultMetadataOverrides, overrides));

                        case 1:
                        case "end":
                          return _context.stop();
                      }
                    }
                  }, _callee);
                }));

                return function (_x3) {
                  return _ref.apply(this, arguments);
                };
              }());
              _context2.next = 29;
              return Promise.all(promises).then(function (chunks) {
                return chunks.flat();
              });

            case 29:
              assetsDynamic = _context2.sent;

            case 30:
              strategiesMetadataPromise = this.yearn.strategies.vaultsStrategiesMetadata(assetsDynamic.map(function (asset) {
                return asset.address;
              }))["catch"](function (error) {
                console.error(error);
                return Promise.resolve([]);
              });
              assetsHistoricEarningsPromise = this.yearn.earnings.assetsHistoricEarnings()["catch"](function (error) {
                console.error(error);
                return Promise.resolve([]);
              });
              _context2.next = 34;
              return Promise.all([strategiesMetadataPromise, assetsHistoricEarningsPromise]);

            case 34:
              _yield$Promise$all2 = _context2.sent;
              strategiesMetadata = _yield$Promise$all2[0];
              assetsHistoricEarnings = _yield$Promise$all2[1];
              assetsWithOrder = [];

              _loop = function _loop() {
                var _overrides$order, _assetsHistoricEarnin;

                var asset = _step.value;
                var dynamic = assetsDynamic.find(function (_ref2) {
                  var address = _ref2.address;
                  return asset.address === address;
                });

                if (!dynamic) {
                  throw new SdkError("Dynamic asset does not exist for " + asset.address);
                }

                var overrides = vaultMetadataOverrides.find(function (override) {
                  return override.address === asset.address;
                });

                if (overrides != null && overrides.hideAlways) {
                  return "continue";
                }

                var order = (_overrides$order = overrides == null ? void 0 : overrides.order) != null ? _overrides$order : Math.max();
                dynamic.metadata.displayName = dynamic.metadata.displayName || asset.name;
                dynamic.metadata.strategies = strategiesMetadata.find(function (metadata) {
                  return metadata.vaultAddress === asset.address;
                });
                dynamic.metadata.historicEarnings = (_assetsHistoricEarnin = assetsHistoricEarnings.find(function (earnings) {
                  return earnings.assetAddress === asset.address;
                })) == null ? void 0 : _assetsHistoricEarnin.dayData;
                assetsWithOrder.push({
                  vault: _extends({}, asset, dynamic),
                  order: order
                });
              };

              _iterator = _createForOfIteratorHelperLoose(assetsStatic);

            case 40:
              if ((_step = _iterator()).done) {
                _context2.next = 46;
                break;
              }

              _ret = _loop();

              if (!(_ret === "continue")) {
                _context2.next = 44;
                break;
              }

              return _context2.abrupt("continue", 44);

            case 44:
              _context2.next = 40;
              break;

            case 46:
              return _context2.abrupt("return", assetsWithOrder.sort(function (lhs, rhs) {
                return lhs.order - rhs.order;
              }).map(function (asset) {
                return asset.vault;
              }));

            case 47:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this, [[16, 22]]);
    }));

    function get(_x, _x2) {
      return _get.apply(this, arguments);
    }

    return get;
  }()
  /**
   * Get static part of yearn vaults.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.getStatic =
  /*#__PURE__*/
  function () {
    var _getStatic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(addresses, overrides) {
      var adapters;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              adapters = Object.values(this.yearn.services.lens.adapters.vaults);
              _context4.next = 3;
              return Promise.all(adapters.map( /*#__PURE__*/function () {
                var _ref3 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(adapter) {
                  return runtime_1.wrap(function _callee3$(_context3) {
                    while (1) {
                      switch (_context3.prev = _context3.next) {
                        case 0:
                          _context3.next = 2;
                          return adapter.assetsStatic(addresses, overrides);

                        case 2:
                          return _context3.abrupt("return", _context3.sent);

                        case 3:
                        case "end":
                          return _context3.stop();
                      }
                    }
                  }, _callee3);
                }));

                return function (_x6) {
                  return _ref3.apply(this, arguments);
                };
              }())).then(function (arr) {
                return arr.flat();
              });

            case 3:
              return _context4.abrupt("return", _context4.sent);

            case 4:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function getStatic(_x4, _x5) {
      return _getStatic.apply(this, arguments);
    }

    return getStatic;
  }()
  /**
   * Get dynamic part of yearn vaults.
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.getDynamic =
  /*#__PURE__*/
  function () {
    var _getDynamic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(addresses, vaultMetadataOverrides, overrides) {
      var _this3 = this;

      var cached, metadataOverrides, vaultTokenMarketData, ftmApeZappableVault, adapters;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              _context6.next = 2;
              return this.cachedFetcherGetDynamic.fetch();

            case 2:
              cached = _context6.sent;

              if (!cached) {
                _context6.next = 5;
                break;
              }

              return _context6.abrupt("return", addresses ? cached.filter(function (vault) {
                return addresses.includes(vault.address);
              }) : cached);

            case 5:
              if (!vaultMetadataOverrides) {
                _context6.next = 9;
                break;
              }

              _context6.t0 = vaultMetadataOverrides;
              _context6.next = 12;
              break;

            case 9:
              _context6.next = 11;
              return this.yearn.services.meta.vaults()["catch"](function (error) {
                console.error(error);
                return Promise.resolve([]);
              });

            case 11:
              _context6.t0 = _context6.sent;

            case 12:
              metadataOverrides = _context6.t0;

              if (!isEthereum(this.chainId)) {
                _context6.next = 18;
                break;
              }

              _context6.next = 16;
              return this.yearn.services.zapper.supportedVaultAddresses();

            case 16:
              vaultTokenMarketData = _context6.sent;
              metadataOverrides = mergeZapPropsWithAddressables({
                addressables: metadataOverrides,
                supportedVaultAddresses: vaultTokenMarketData,
                zapInType: "zapperZapIn",
                zapOutType: "zapperZapOut"
              });

            case 18:
              if (isFantom(this.chainId)) {
                ftmApeZappableVault = [FANTOM_TOKEN.address]; // hardcoded for now

                metadataOverrides = mergeZapPropsWithAddressables({
                  addressables: metadataOverrides,
                  supportedVaultAddresses: ftmApeZappableVault,
                  zapInType: "ftmApeZap",
                  zapOutType: "ftmApeZap"
                });
              }

              adapters = Object.values(this.yearn.services.lens.adapters.vaults);
              _context6.next = 22;
              return Promise.all(adapters.map( /*#__PURE__*/function () {
                var _ref4 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(adapter) {
                  var data, assetsApy;
                  return runtime_1.wrap(function _callee5$(_context5) {
                    while (1) {
                      switch (_context5.prev = _context5.next) {
                        case 0:
                          _context5.next = 2;
                          return adapter.assetsDynamic(addresses, overrides);

                        case 2:
                          data = _context5.sent;
                          _context5.next = 5;
                          return _this3.yearn.services.vision.apy(data.map(function (dynamic) {
                            return dynamic.address;
                          }));

                        case 5:
                          assetsApy = _context5.sent;
                          return _context5.abrupt("return", data.map(function (dynamic) {
                            var overrides = metadataOverrides.find(function (override) {
                              return override.address === dynamic.address;
                            });
                            dynamic.metadata.apy = assetsApy[dynamic.address];

                            if (dynamic.tokenId === WethAddress) {
                              var _this3$yearn$services;

                              var icon = (_this3$yearn$services = _this3.yearn.services.asset.icon(EthAddress)) != null ? _this3$yearn$services : "";
                              dynamic.metadata.displayIcon = icon;
                              dynamic.metadata.displayName = "ETH";
                              dynamic.metadata.defaultDisplayToken = EthAddress;
                            } else {
                              var _this3$yearn$services2;

                              var _icon = (_this3$yearn$services2 = _this3.yearn.services.asset.icon(dynamic.tokenId)) != null ? _this3$yearn$services2 : "";

                              dynamic.metadata.displayIcon = _icon;

                              var alias = _this3.yearn.services.asset.alias(dynamic.tokenId);

                              dynamic.metadata.displayName = alias ? alias.symbol : "";
                              dynamic.metadata.defaultDisplayToken = dynamic.tokenId;
                            }

                            if (overrides) {
                              _this3.fillMetadataOverrides(dynamic, overrides);
                            }

                            return dynamic;
                          }));

                        case 7:
                        case "end":
                          return _context5.stop();
                      }
                    }
                  }, _callee5);
                }));

                return function (_x10) {
                  return _ref4.apply(this, arguments);
                };
              }())).then(function (arr) {
                return arr.flat();
              });

            case 22:
              return _context6.abrupt("return", _context6.sent);

            case 23:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function getDynamic(_x7, _x8, _x9) {
      return _getDynamic.apply(this, arguments);
    }

    return getDynamic;
  }()
  /**
   * Get yearn vault positions for a particular address.
   * @param address
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.positionsOf =
  /*#__PURE__*/
  function () {
    var _positionsOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(address, addresses, overrides) {
      var _this4 = this;

      var adapters;
      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              adapters = Object.values(this.yearn.services.lens.adapters.vaults);
              _context9.next = 3;
              return Promise.all(adapters.map( /*#__PURE__*/function () {
                var _ref5 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(adapter) {
                  var allAddresses, chunks, promises;
                  return runtime_1.wrap(function _callee8$(_context8) {
                    while (1) {
                      switch (_context8.prev = _context8.next) {
                        case 0:
                          _context8.prev = 0;
                          _context8.next = 3;
                          return adapter.positionsOf(address, addresses, overrides);

                        case 3:
                          return _context8.abrupt("return", _context8.sent);

                        case 6:
                          _context8.prev = 6;
                          _context8.t0 = _context8["catch"](0);

                          if (!addresses) {
                            _context8.next = 12;
                            break;
                          }

                          allAddresses = addresses;
                          _context8.next = 15;
                          break;

                        case 12:
                          _context8.next = 14;
                          return _this4.getStatic(addresses, overrides).then(function (assets) {
                            return assets.map(function (asset) {
                              return asset.address;
                            });
                          });

                        case 14:
                          allAddresses = _context8.sent;

                        case 15:
                          chunks = chunkArray(allAddresses, 30);
                          promises = chunks.map( /*#__PURE__*/function () {
                            var _ref6 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(chunk) {
                              return runtime_1.wrap(function _callee7$(_context7) {
                                while (1) {
                                  switch (_context7.prev = _context7.next) {
                                    case 0:
                                      return _context7.abrupt("return", adapter.positionsOf(address, chunk, overrides));

                                    case 1:
                                    case "end":
                                      return _context7.stop();
                                  }
                                }
                              }, _callee7);
                            }));

                            return function (_x15) {
                              return _ref6.apply(this, arguments);
                            };
                          }());
                          _context8.next = 19;
                          return Promise.all(promises).then(function (chunks) {
                            return chunks.flat();
                          });

                        case 19:
                          return _context8.abrupt("return", _context8.sent);

                        case 20:
                        case "end":
                          return _context8.stop();
                      }
                    }
                  }, _callee8, null, [[0, 6]]);
                }));

                return function (_x14) {
                  return _ref5.apply(this, arguments);
                };
              }())).then(function (arr) {
                return arr.flat();
              });

            case 3:
              return _context9.abrupt("return", _context9.sent);

            case 4:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function positionsOf(_x11, _x12, _x13) {
      return _positionsOf.apply(this, arguments);
    }

    return positionsOf;
  }()
  /**
   * Get the Vaults User Summary for a particular address.
   * @param address
   * @returns
   */
  ;

  _proto.summaryOf =
  /*#__PURE__*/
  function () {
    var _summaryOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(address) {
      var _yield$this$yearn$ear, earnings, holdings, grossApy, estimatedYearlyYield;

      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              _context10.next = 2;
              return this.yearn.earnings.accountAssetsData(address);

            case 2:
              _yield$this$yearn$ear = _context10.sent;
              earnings = _yield$this$yearn$ear.earnings;
              holdings = _yield$this$yearn$ear.holdings;
              grossApy = _yield$this$yearn$ear.grossApy;
              estimatedYearlyYield = _yield$this$yearn$ear.estimatedYearlyYield;
              return _context10.abrupt("return", {
                earnings: earnings,
                holdings: holdings,
                grossApy: grossApy,
                estimatedYearlyYield: estimatedYearlyYield
              });

            case 8:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function summaryOf(_x16) {
      return _summaryOf.apply(this, arguments);
    }

    return summaryOf;
  }()
  /**
   * Get the Vault User Metadata for a particular address.
   * @param address
   * @param addresses filter, if provided only those addresses' Vault User Metadata are returned
   * @returns
   */
  ;

  _proto.metadataOf =
  /*#__PURE__*/
  function () {
    var _metadataOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11(address, addresses) {
      var _yield$this$yearn$ear2, earningsAssetData;

      return runtime_1.wrap(function _callee11$(_context11) {
        while (1) {
          switch (_context11.prev = _context11.next) {
            case 0:
              _context11.next = 2;
              return this.yearn.earnings.accountAssetsData(address);

            case 2:
              _yield$this$yearn$ear2 = _context11.sent;
              earningsAssetData = _yield$this$yearn$ear2.earningsAssetData;

              if (addresses) {
                _context11.next = 6;
                break;
              }

              return _context11.abrupt("return", earningsAssetData);

            case 6:
              return _context11.abrupt("return", earningsAssetData.filter(function (asset) {
                return addresses.includes(asset.assetAddress);
              }));

            case 7:
            case "end":
              return _context11.stop();
          }
        }
      }, _callee11, this);
    }));

    function metadataOf(_x17, _x18) {
      return _metadataOf.apply(this, arguments);
    }

    return metadataOf;
  }()
  /**
   * Get all yearn vault's underlying token balances for a particular address.
   * @param address
   * @param overrides
   * @returns
   */
  ;

  _proto.balances =
  /*#__PURE__*/
  function () {
    var _balances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee12(address, overrides) {
      var tokens, balances;
      return runtime_1.wrap(function _callee12$(_context12) {
        while (1) {
          switch (_context12.prev = _context12.next) {
            case 0:
              _context12.next = 2;
              return this.tokens();

            case 2:
              tokens = _context12.sent;
              _context12.next = 5;
              return this.yearn.services.helper.tokenBalances(address, tokens.map(function (token) {
                return token.address;
              }), overrides);

            case 5:
              balances = _context12.sent;
              return _context12.abrupt("return", balances.map(function (balance) {
                var token = tokens.find(function (token) {
                  return token.address === balance.address;
                });

                if (!token) {
                  throw new SdkError("Token does not exist for Balance(" + balance.address + ")");
                }

                return _extends({}, balance, {
                  token: token
                });
              }));

            case 7:
            case "end":
              return _context12.stop();
          }
        }
      }, _callee12, this);
    }));

    function balances(_x19, _x20) {
      return _balances.apply(this, arguments);
    }

    return balances;
  }()
  /**
   * Get all yearn vault's underlying tokens.
   * @param overrides
   * @returns
   */
  ;

  _proto.tokens =
  /*#__PURE__*/
  function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee15(overrides) {
      var _this5 = this;

      var cached, adapters;
      return runtime_1.wrap(function _callee15$(_context15) {
        while (1) {
          switch (_context15.prev = _context15.next) {
            case 0:
              _context15.next = 2;
              return this.cachedFetcherTokens.fetch();

            case 2:
              cached = _context15.sent;

              if (!cached) {
                _context15.next = 5;
                break;
              }

              return _context15.abrupt("return", cached);

            case 5:
              adapters = Object.values(this.yearn.services.lens.adapters.vaults);
              _context15.next = 8;
              return this.yearn.services.asset.ready;

            case 8:
              _context15.next = 10;
              return Promise.all(adapters.map( /*#__PURE__*/function () {
                var _ref7 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee14(adapter) {
                  var tokenAddresses, icons, tokensPromise, tokensMetadataPromise, _yield$Promise$all3, tokens, tokensMetadata;

                  return runtime_1.wrap(function _callee14$(_context14) {
                    while (1) {
                      switch (_context14.prev = _context14.next) {
                        case 0:
                          _context14.next = 2;
                          return adapter.tokens(overrides);

                        case 2:
                          tokenAddresses = _context14.sent;
                          icons = _this5.yearn.services.asset.icon(tokenAddresses.concat(EthAddress));
                          tokensPromise = _this5.yearn.services.helper.tokens(tokenAddresses, overrides);
                          tokensMetadataPromise = _this5.yearn.tokens.metadata(tokenAddresses);
                          _context14.next = 8;
                          return Promise.all([tokensPromise, tokensMetadataPromise]);

                        case 8:
                          _yield$Promise$all3 = _context14.sent;
                          tokens = _yield$Promise$all3[0];
                          tokensMetadata = _yield$Promise$all3[1];
                          return _context14.abrupt("return", Promise.all(tokens.map( /*#__PURE__*/function () {
                            var _ref8 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee13(token) {
                              var _this5$yearn$services;

                              var tokenMetadata, result, symbolOverride;
                              return runtime_1.wrap(function _callee13$(_context13) {
                                while (1) {
                                  switch (_context13.prev = _context13.next) {
                                    case 0:
                                      tokenMetadata = tokensMetadata.find(function (metadata) {
                                        return metadata.address === token.address;
                                      });
                                      _context13.t0 = _extends;
                                      _context13.t1 = {};
                                      _context13.t2 = token;
                                      _context13.t3 = icons[token.address];
                                      _context13.t4 = {
                                        vaults: true
                                      };
                                      _context13.next = 8;
                                      return _this5.yearn.services.oracle.getPriceUsdc(token.address, overrides);

                                    case 8:
                                      _context13.t5 = _context13.sent;
                                      _context13.t6 = tokenMetadata;
                                      _context13.t7 = {
                                        icon: _context13.t3,
                                        dataSource: "vaults",
                                        supported: _context13.t4,
                                        priceUsdc: _context13.t5,
                                        metadata: _context13.t6
                                      };
                                      result = (0, _context13.t0)(_context13.t1, _context13.t2, _context13.t7);
                                      symbolOverride = (_this5$yearn$services = _this5.yearn.services.asset.alias(token.address)) == null ? void 0 : _this5$yearn$services.symbol;

                                      if (symbolOverride) {
                                        result.symbol = symbolOverride;
                                      }

                                      if (tokenMetadata) {
                                        _this5.fillTokenMetadataOverrides(result, tokenMetadata);
                                      }

                                      return _context13.abrupt("return", result);

                                    case 16:
                                    case "end":
                                      return _context13.stop();
                                  }
                                }
                              }, _callee13);
                            }));

                            return function (_x23) {
                              return _ref8.apply(this, arguments);
                            };
                          }())));

                        case 12:
                        case "end":
                          return _context14.stop();
                      }
                    }
                  }, _callee14);
                }));

                return function (_x22) {
                  return _ref7.apply(this, arguments);
                };
              }())).then(function (arr) {
                return arr.flat();
              });

            case 10:
              return _context15.abrupt("return", _context15.sent);

            case 11:
            case "end":
              return _context15.stop();
          }
        }
      }, _callee15, this);
    }));

    function tokens(_x21) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }()
  /**
   * Fetch the token amount that has been allowed to be used for deposits
   * @param accountAddress
   * @param vaultAddress
   * @param tokenAddress
   * @returns TokenAllowance
   */
  ;

  _proto.getDepositAllowance =
  /*#__PURE__*/
  function () {
    var _getDepositAllowance = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee16(accountAddress, vaultAddress, tokenAddress) {
      var spenderAddress;
      return runtime_1.wrap(function _callee16$(_context16) {
        while (1) {
          switch (_context16.prev = _context16.next) {
            case 0:
              _context16.next = 2;
              return this.getDepositContractAddress(vaultAddress, tokenAddress);

            case 2:
              spenderAddress = _context16.sent;
              return _context16.abrupt("return", this.yearn.tokens.allowance(accountAddress, tokenAddress, spenderAddress));

            case 4:
            case "end":
              return _context16.stop();
          }
        }
      }, _callee16, this);
    }));

    function getDepositAllowance(_x24, _x25, _x26) {
      return _getDepositAllowance.apply(this, arguments);
    }

    return getDepositAllowance;
  }()
  /**
   * Fetch the token amount that has been allowed to be used for withdraw
   * @param accountAddress
   * @param vaultAddress
   * @param tokenAddress
   * @returns TokenAllowance
   */
  ;

  _proto.getWithdrawAllowance =
  /*#__PURE__*/
  function () {
    var _getWithdrawAllowance = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee17(accountAddress, vaultAddress, tokenAddress) {
      var spenderAddress;
      return runtime_1.wrap(function _callee17$(_context17) {
        while (1) {
          switch (_context17.prev = _context17.next) {
            case 0:
              _context17.next = 2;
              return this.getWithdrawContractAddress(vaultAddress, tokenAddress);

            case 2:
              spenderAddress = _context17.sent;
              return _context17.abrupt("return", this.yearn.tokens.allowance(accountAddress, vaultAddress, spenderAddress));

            case 4:
            case "end":
              return _context17.stop();
          }
        }
      }, _callee17, this);
    }));

    function getWithdrawAllowance(_x27, _x28, _x29) {
      return _getWithdrawAllowance.apply(this, arguments);
    }

    return getWithdrawAllowance;
  }()
  /**
   * Approve the token amount to allow to be used for deposits
   * @param accountAddress
   * @param vaultAddress
   * @param tokenAddress
   * @param amount
   * @param overrides
   * @returns TransactionResponse
   */
  ;

  _proto.approveDeposit =
  /*#__PURE__*/
  function () {
    var _approveDeposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee18(accountAddress, vaultAddress, tokenAddress, amount, overrides) {
      var spenderAddress;
      return runtime_1.wrap(function _callee18$(_context18) {
        while (1) {
          switch (_context18.prev = _context18.next) {
            case 0:
              _context18.next = 2;
              return this.getDepositContractAddress(vaultAddress, tokenAddress);

            case 2:
              spenderAddress = _context18.sent;
              return _context18.abrupt("return", this.yearn.tokens.approve(accountAddress, tokenAddress, spenderAddress, amount != null ? amount : constants.MaxUint256.toString(), overrides));

            case 4:
            case "end":
              return _context18.stop();
          }
        }
      }, _callee18, this);
    }));

    function approveDeposit(_x30, _x31, _x32, _x33, _x34) {
      return _approveDeposit.apply(this, arguments);
    }

    return approveDeposit;
  }()
  /**
   * Approve the token amount to allow to be used for withdraw
   * @param accountAddress
   * @param vaultAddress
   * @param tokenAddress
   * @param amount
   * @param overrides
   * @returns TransactionResponse
   */
  ;

  _proto.approveWithdraw =
  /*#__PURE__*/
  function () {
    var _approveWithdraw = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee19(accountAddress, vaultAddress, tokenAddress, amount, overrides) {
      var spenderAddress;
      return runtime_1.wrap(function _callee19$(_context19) {
        while (1) {
          switch (_context19.prev = _context19.next) {
            case 0:
              _context19.next = 2;
              return this.getWithdrawContractAddress(vaultAddress, tokenAddress);

            case 2:
              spenderAddress = _context19.sent;
              return _context19.abrupt("return", this.yearn.tokens.approve(accountAddress, vaultAddress, spenderAddress, amount != null ? amount : constants.MaxUint256.toString(), overrides));

            case 4:
            case "end":
              return _context19.stop();
          }
        }
      }, _callee19, this);
    }));

    function approveWithdraw(_x35, _x36, _x37, _x38, _x39) {
      return _approveWithdraw.apply(this, arguments);
    }

    return approveWithdraw;
  }();

  _proto.getDepositContractAddress = /*#__PURE__*/function () {
    var _getDepositContractAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee20(vaultAddress, tokenAddress) {
      var willZapToPickleJar, willDepositUnderlyingToken, shouldUsePartnerService, _this$yearn$services$, partnerTrackingContractAddress, zapContractId, zapContractAddress;

      return runtime_1.wrap(function _callee20$(_context20) {
        while (1) {
          switch (_context20.prev = _context20.next) {
            case 0:
              if (!isNativeToken(tokenAddress)) {
                _context20.next = 2;
                break;
              }

              return _context20.abrupt("return", vaultAddress);

            case 2:
              willZapToPickleJar = this.isZappingIntoPickleJar({
                vault: vaultAddress
              });
              willDepositUnderlyingToken = false;

              if (willZapToPickleJar) {
                _context20.next = 8;
                break;
              }

              _context20.next = 7;
              return this.isUnderlyingToken(vaultAddress, tokenAddress);

            case 7:
              willDepositUnderlyingToken = _context20.sent;

            case 8:
              shouldUsePartnerService = this.shouldUsePartnerService(vaultAddress);

              if (!(willDepositUnderlyingToken && shouldUsePartnerService)) {
                _context20.next = 16;
                break;
              }

              _context20.next = 12;
              return (_this$yearn$services$ = this.yearn.services.partner) == null ? void 0 : _this$yearn$services$.address;

            case 12:
              partnerTrackingContractAddress = _context20.sent;

              if (partnerTrackingContractAddress) {
                _context20.next = 15;
                break;
              }

              throw new SdkError("Partner Tracking Contract Address not defined");

            case 15:
              return _context20.abrupt("return", partnerTrackingContractAddress);

            case 16:
              if (!willDepositUnderlyingToken) {
                _context20.next = 18;
                break;
              }

              return _context20.abrupt("return", vaultAddress);

            case 18:
              zapContractId = willZapToPickleJar ? ContractAddressId.pickleZapIn : ContractAddressId.zapperZapIn;
              _context20.next = 21;
              return this.yearn.addressProvider.addressById(zapContractId);

            case 21:
              zapContractAddress = _context20.sent;
              return _context20.abrupt("return", zapContractAddress);

            case 23:
            case "end":
              return _context20.stop();
          }
        }
      }, _callee20, this);
    }));

    function getDepositContractAddress(_x40, _x41) {
      return _getDepositContractAddress.apply(this, arguments);
    }

    return getDepositContractAddress;
  }();

  _proto.getWithdrawContractAddress = /*#__PURE__*/function () {
    var _getWithdrawContractAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee21(vaultAddress, tokenAddress) {
      var willWithdrawToUnderlyingToken, zapContractAddress;
      return runtime_1.wrap(function _callee21$(_context21) {
        while (1) {
          switch (_context21.prev = _context21.next) {
            case 0:
              _context21.next = 2;
              return this.isUnderlyingToken(vaultAddress, tokenAddress);

            case 2:
              willWithdrawToUnderlyingToken = _context21.sent;

              if (!willWithdrawToUnderlyingToken) {
                _context21.next = 5;
                break;
              }

              return _context21.abrupt("return", vaultAddress);

            case 5:
              _context21.next = 7;
              return this.yearn.addressProvider.addressById(ContractAddressId.zapperZapOut);

            case 7:
              zapContractAddress = _context21.sent;
              return _context21.abrupt("return", zapContractAddress);

            case 9:
            case "end":
              return _context21.stop();
          }
        }
      }, _callee21, this);
    }));

    function getWithdrawContractAddress(_x42, _x43) {
      return _getWithdrawContractAddress.apply(this, arguments);
    }

    return getWithdrawContractAddress;
  }();

  _proto.isUnderlyingToken = /*#__PURE__*/function () {
    var _isUnderlyingToken = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee22(vaultAddress, tokenAddress) {
      var _yield$this$getStatic, vault;

      return runtime_1.wrap(function _callee22$(_context22) {
        while (1) {
          switch (_context22.prev = _context22.next) {
            case 0:
              _context22.next = 2;
              return this.getStatic([vaultAddress]);

            case 2:
              _yield$this$getStatic = _context22.sent;
              vault = _yield$this$getStatic[0];
              return _context22.abrupt("return", vault.token === tokenAddress);

            case 5:
            case "end":
              return _context22.stop();
          }
        }
      }, _callee22, this);
    }));

    function isUnderlyingToken(_x44, _x45) {
      return _isUnderlyingToken.apply(this, arguments);
    }

    return isUnderlyingToken;
  }()
  /**
   * Deposit into a yearn vault
   * @param vault
   * @param token
   * @param amount
   * @param account
   * @param overrides
   * @returns transaction
   */
  ;

  _proto.deposit =
  /*#__PURE__*/
  function () {
    var _deposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee24(vault, token, amount, account, options, overrides) {
      var _this6 = this;

      var signer, _yield$this$getStatic2, vaultRef;

      return runtime_1.wrap(function _callee24$(_context24) {
        while (1) {
          switch (_context24.prev = _context24.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              if (overrides === void 0) {
                overrides = {};
              }

              signer = this.ctx.provider.write.getSigner(account);

              if (!this.isZappingIntoPickleJar({
                vault: vault
              })) {
                _context24.next = 5;
                break;
              }

              return _context24.abrupt("return", this.zapIn(vault, token, amount, account, options, exports.ZapProtocol.PICKLE, overrides));

            case 5:
              _context24.next = 7;
              return this.getStatic([vault], overrides);

            case 7:
              _yield$this$getStatic2 = _context24.sent;
              vaultRef = _yield$this$getStatic2[0];

              if (!(vaultRef.token !== token)) {
                _context24.next = 11;
                break;
              }

              return _context24.abrupt("return", this.zapIn(vault, token, amount, account, options, exports.ZapProtocol.YEARN, overrides));

            case 11:
              return _context24.abrupt("return", this.executeVaultContractTransaction( /*#__PURE__*/function () {
                var _ref9 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee23(overrides) {
                  var populatedTransaction;
                  return runtime_1.wrap(function _callee23$(_context23) {
                    while (1) {
                      switch (_context23.prev = _context23.next) {
                        case 0:
                          _context23.next = 2;
                          return _this6.populateDepositTransaction({
                            vault: vault,
                            amount: amount,
                            overrides: overrides,
                            signer: signer
                          });

                        case 2:
                          populatedTransaction = _context23.sent;

                          if (populatedTransaction) {
                            _context23.next = 5;
                            break;
                          }

                          throw new SdkError("deposit transaction failed");

                        case 5:
                          return _context23.abrupt("return", _this6.yearn.services.transaction.sendTransaction(populatedTransaction));

                        case 6:
                        case "end":
                          return _context23.stop();
                      }
                    }
                  }, _callee23);
                }));

                return function (_x52) {
                  return _ref9.apply(this, arguments);
                };
              }(), overrides));

            case 12:
            case "end":
              return _context24.stop();
          }
        }
      }, _callee24, this);
    }));

    function deposit(_x46, _x47, _x48, _x49, _x50, _x51) {
      return _deposit.apply(this, arguments);
    }

    return deposit;
  }()
  /**
   * Withdraw from a yearn vault.
   * @param vault
   * @param token
   * @param amount
   * @param account
   * @param overrides
   * @returns transaction
   */
  ;

  _proto.withdraw =
  /*#__PURE__*/
  function () {
    var _withdraw = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee26(vault, token, amount, account, options, overrides) {
      var _this7 = this;

      var _yield$this$getStatic3, vaultRef, signer, vaultContract, makeTransaction, zapOutParams, transactionRequest;

      return runtime_1.wrap(function _callee26$(_context26) {
        while (1) {
          switch (_context26.prev = _context26.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              if (overrides === void 0) {
                overrides = {};
              }

              _context26.next = 4;
              return this.getStatic([vault], overrides);

            case 4:
              _yield$this$getStatic3 = _context26.sent;
              vaultRef = _yield$this$getStatic3[0];
              signer = this.ctx.provider.write.getSigner(account);

              if (!(vaultRef.token === token)) {
                _context26.next = 13;
                break;
              }

              vaultContract = new contracts.Contract(vault, VaultAbi$1, signer);

              makeTransaction = /*#__PURE__*/function () {
                var _ref10 = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee25(overrides) {
                  var tx;
                  return runtime_1.wrap(function _callee25$(_context25) {
                    while (1) {
                      switch (_context25.prev = _context25.next) {
                        case 0:
                          _context25.next = 2;
                          return vaultContract.populateTransaction.withdraw(amount, overrides);

                        case 2:
                          tx = _context25.sent;
                          return _context25.abrupt("return", _this7.yearn.services.transaction.sendTransaction(tx));

                        case 4:
                        case "end":
                          return _context25.stop();
                      }
                    }
                  }, _callee25);
                }));

                return function makeTransaction(_x59) {
                  return _ref10.apply(this, arguments);
                };
              }();

              return _context26.abrupt("return", this.executeVaultContractTransaction(makeTransaction, overrides));

            case 13:
              if (!(options.slippage === undefined)) {
                _context26.next = 15;
                break;
              }

              throw new SdkError("zap operations should have a slippage set");

            case 15:
              _context26.next = 17;
              return this.yearn.services.zapper.zapOut(account, token, amount, vault, "0", options.slippage, false, undefined, options.signature);

            case 17:
              zapOutParams = _context26.sent;
              transactionRequest = {
                to: zapOutParams.to,
                from: zapOutParams.from,
                gasPrice: bignumber.BigNumber.from(zapOutParams.gasPrice),
                gasLimit: bignumber.BigNumber.from(zapOutParams.gas),
                data: zapOutParams.data,
                value: bignumber.BigNumber.from(zapOutParams.value)
              };
              return _context26.abrupt("return", this.executeZapperTransaction(transactionRequest, overrides, bignumber.BigNumber.from(zapOutParams.gasPrice)));

            case 20:
            case "end":
              return _context26.stop();
          }
        }
      }, _callee26, this);
    }));

    function withdraw(_x53, _x54, _x55, _x56, _x57, _x58) {
      return _withdraw.apply(this, arguments);
    }

    return withdraw;
  }();

  _proto.zapIn = /*#__PURE__*/function () {
    var _zapIn = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee27(vault, token, amount, account, options, zapProtocol, overrides) {
      var _this$yearn$services$2;

      var zapInParams, transactionRequest;
      return runtime_1.wrap(function _callee27$(_context27) {
        while (1) {
          switch (_context27.prev = _context27.next) {
            case 0:
              if (options === void 0) {
                options = {};
              }

              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              if (overrides === void 0) {
                overrides = {};
              }

              if (!(options.slippage === undefined)) {
                _context27.next = 5;
                break;
              }

              throw new SdkError("zap operations should have a slippage set");

            case 5:
              _context27.next = 7;
              return this.yearn.services.zapper.zapIn(account, token, amount, vault, "0", options.slippage, false, zapProtocol, (_this$yearn$services$2 = this.yearn.services.partner) == null ? void 0 : _this$yearn$services$2.partnerId);

            case 7:
              zapInParams = _context27.sent;
              transactionRequest = {
                to: zapInParams.to,
                from: zapInParams.from,
                data: zapInParams.data,
                value: bignumber.BigNumber.from(zapInParams.value),
                gasLimit: bignumber.BigNumber.from(zapInParams.gas)
              };
              return _context27.abrupt("return", this.executeZapperTransaction(transactionRequest, overrides, bignumber.BigNumber.from(zapInParams.gasPrice)));

            case 10:
            case "end":
              return _context27.stop();
          }
        }
      }, _callee27, this);
    }));

    function zapIn(_x60, _x61, _x62, _x63, _x64, _x65, _x66) {
      return _zapIn.apply(this, arguments);
    }

    return zapIn;
  }();

  _proto.executeZapperTransaction = /*#__PURE__*/function () {
    var _executeZapperTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee28(transactionRequest, overrides, fallbackGasPrice) {
      var combinedParams, _combinedParams;

      return runtime_1.wrap(function _callee28$(_context28) {
        while (1) {
          switch (_context28.prev = _context28.next) {
            case 0:
              _context28.prev = 0;
              combinedParams = _extends({}, transactionRequest, overrides);
              combinedParams.gasPrice = undefined;
              _context28.next = 5;
              return this.yearn.services.transaction.sendTransaction(combinedParams);

            case 5:
              return _context28.abrupt("return", _context28.sent);

            case 8:
              _context28.prev = 8;
              _context28.t0 = _context28["catch"](0);

              if (!(_context28.t0.code === -32602)) {
                _context28.next = 18;
                break;
              }

              _combinedParams = _extends({}, transactionRequest, overrides);
              _combinedParams.maxFeePerGas = undefined;
              _combinedParams.maxPriorityFeePerGas = undefined;
              _combinedParams.gasPrice = overrides.gasPrice || fallbackGasPrice;
              _context28.next = 17;
              return this.yearn.services.transaction.sendTransaction(_combinedParams);

            case 17:
              return _context28.abrupt("return", _context28.sent);

            case 18:
              throw _context28.t0;

            case 19:
            case "end":
              return _context28.stop();
          }
        }
      }, _callee28, this, [[0, 8]]);
    }));

    function executeZapperTransaction(_x67, _x68, _x69) {
      return _executeZapperTransaction.apply(this, arguments);
    }

    return executeZapperTransaction;
  }();

  _proto.executeVaultContractTransaction = /*#__PURE__*/function () {
    var _executeVaultContractTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee29(makeTransaction, overrides) {
      var originalGasPrice, tx, _tx;

      return runtime_1.wrap(function _callee29$(_context29) {
        while (1) {
          switch (_context29.prev = _context29.next) {
            case 0:
              originalGasPrice = overrides.gasPrice;
              _context29.prev = 1;
              overrides.gasPrice = undefined;
              _context29.next = 5;
              return makeTransaction(overrides);

            case 5:
              tx = _context29.sent;
              return _context29.abrupt("return", tx);

            case 9:
              _context29.prev = 9;
              _context29.t0 = _context29["catch"](1);

              if (!(_context29.t0.code === -32602)) {
                _context29.next = 19;
                break;
              }

              overrides.maxFeePerGas = undefined;
              overrides.maxPriorityFeePerGas = undefined;
              overrides.gasPrice = originalGasPrice;
              _context29.next = 17;
              return makeTransaction(overrides);

            case 17:
              _tx = _context29.sent;
              return _context29.abrupt("return", _tx);

            case 19:
              throw _context29.t0;

            case 20:
            case "end":
              return _context29.stop();
          }
        }
      }, _callee29, null, [[1, 9]]);
    }));

    function executeVaultContractTransaction(_x70, _x71) {
      return _executeVaultContractTransaction.apply(this, arguments);
    }

    return executeVaultContractTransaction;
  }();

  _proto.fillTokenMetadataOverrides = function fillTokenMetadataOverrides(token, overrides) {
    if (overrides.tokenIconOverride) {
      token.icon = overrides.tokenIconOverride;
    }

    if (overrides.tokenSymbolOverride) {
      token.symbol = overrides.tokenSymbolOverride;
    }

    if (overrides.tokenNameOverride) {
      token.name = overrides.tokenNameOverride;
    }
  };

  _proto.fillMetadataOverrides = function fillMetadataOverrides(dynamic, overrides) {
    if (overrides.displayName) {
      dynamic.metadata.displayName = overrides.displayName;
    }

    if (overrides.vaultSymbolOverride) {
      dynamic.metadata.symbol = overrides.vaultSymbolOverride;
    }

    if (overrides.vaultIconOverride) {
      dynamic.metadata.displayIcon = overrides.vaultIconOverride;
    }

    if (overrides.apyTypeOverride) {
      if (!dynamic.metadata.apy) {
        dynamic.metadata.apy = this.makeEmptyApy();
      }

      dynamic.metadata.apy.type = overrides.apyTypeOverride;
    }

    if (overrides.apyOverride) {
      if (!dynamic.metadata.apy) {
        dynamic.metadata.apy = this.makeEmptyApy();
      }

      dynamic.metadata.apy.net_apy = overrides.apyOverride;
      dynamic.metadata.apy.type = "override";
    }

    dynamic.metadata.depositsDisabled = overrides.depositsDisabled;
    dynamic.metadata.withdrawalsDisabled = overrides.withdrawalsDisabled;
    dynamic.metadata.allowZapIn = overrides.allowZapIn;
    dynamic.metadata.allowZapOut = overrides.allowZapOut;
    dynamic.metadata.zapInWith = overrides.zapInWith;
    dynamic.metadata.zapOutWith = overrides.zapOutWith;
    dynamic.metadata.migrationContract = overrides.migrationContract;
    dynamic.metadata.migrationTargetVault = overrides.migrationTargetVault;
    dynamic.metadata.vaultNameOverride = overrides.vaultNameOverride;
    dynamic.metadata.vaultDetailPageAssets = overrides.vaultDetailPageAssets;
    dynamic.metadata.hideIfNoDeposits = dynamic.metadata.emergencyShutdown || overrides.retired || overrides.migrationAvailable || false;
    dynamic.metadata.migrationAvailable = dynamic.metadata.migrationAvailable || overrides.migrationAvailable || false;
  };

  _proto.shouldUsePartnerService = function shouldUsePartnerService(vault) {
    var _this$yearn$services$3;

    return !!((_this$yearn$services$3 = this.yearn.services.partner) != null && _this$yearn$services$3.isAllowed(vault));
  };

  _proto.makeEmptyApy = function makeEmptyApy() {
    var apy = {
      type: "manual_override",
      gross_apr: 0,
      net_apy: 0,
      fees: {
        performance: null,
        withdrawal: null,
        management: null,
        keep_crv: null,
        cvx_keep_crv: null
      },
      points: null,
      composite: null
    };
    return apy;
  };

  _proto.populateDepositTransaction = /*#__PURE__*/function () {
    var _populateDepositTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee30(_ref11) {
      var vault, amount, overrides, signer, _this$yearn$services$4, vaultContract;

      return runtime_1.wrap(function _callee30$(_context30) {
        while (1) {
          switch (_context30.prev = _context30.next) {
            case 0:
              vault = _ref11.vault, amount = _ref11.amount, overrides = _ref11.overrides, signer = _ref11.signer;

              if (!this.shouldUsePartnerService(vault)) {
                _context30.next = 3;
                break;
              }

              return _context30.abrupt("return", (_this$yearn$services$4 = this.yearn.services.partner) == null ? void 0 : _this$yearn$services$4.populateDepositTransaction(vault, amount, overrides));

            case 3:
              vaultContract = new contracts.Contract(vault, VaultAbi$1, signer);
              return _context30.abrupt("return", vaultContract.populateTransaction.deposit(amount, overrides));

            case 5:
            case "end":
              return _context30.stop();
          }
        }
      }, _callee30, this);
    }));

    function populateDepositTransaction(_x72) {
      return _populateDepositTransaction.apply(this, arguments);
    }

    return populateDepositTransaction;
  }();

  _proto.isZappingIntoPickleJar = function isZappingIntoPickleJar(_ref12) {
    var vault = _ref12.vault;
    return PickleJars.includes(vault);
  };

  return VaultInterface;
}(ServiceInterface);

/**
 * Storing ABIs in Human-Readable ABI format.
 * https://blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917
 */
var TokenAbi$2 = "tuple(address address, string name, string symbol, uint256 decimals)";
var TokenPriceAbi = "tuple(address address, uint256 priceUsdc)";
var TokenBalanceAbi = "tuple(\n  address address, \n  uint256 priceUsdc, \n  uint256 balance,\n  uint256 balanceUsdc\n)";
var AllowanceAbi = "tuple(address owner, address spender, uint256 amount, address token)";
var AssetStaticAbi = "tuple(\n  address address,\n  string typeId,\n  address token,\n  string name,\n  string version,\n  string symbol,\n  uint8 decimals,\n)";
var AssetDynamicAbi = function AssetDynamicAbi(Metadata) {
  return "tuple(\n  address address, \n  string typeId,\n  address tokenId,\n  tuple(uint256 amount, uint256 amountUsdc) underlyingTokenBalance,\n  " + Metadata + " metadata\n)";
};
var PositionAbi = "tuple(address assetAddress, address tokenAddress, string typeId, uint256 balance," + "tuple(uint256 amount, uint256 amountUsdc) underlyingTokenBalance," + "tuple(address owner, address spender, uint256 amount)[] tokenAllowances," + "tuple(address owner, address spender, uint256 amount)[] assetAllowances)";
var AdapterAbi = function AdapterAbi(Metadata) {
  return ["function assetsStatic() public view returns (" + AssetStaticAbi + "[] memory)", "function assetsStatic(address[] memory) public view returns (" + AssetStaticAbi + "[] memory)", "function assetsDynamic() public view returns (" + AssetDynamicAbi(Metadata) + "[] memory)", "function assetsDynamic(address[] memory) public view returns (" + AssetDynamicAbi(Metadata) + "[] memory)", "function assetsPositionsOf(address) public view returns (" + PositionAbi + "[] memory)", "function assetsPositionsOf(address, address[] memory) public view returns (" + PositionAbi + "[] memory)", "function assetsTokensAddresses() public view returns (address[] memory)"];
};
var AddressMetadataAbi = "tuple(string addrId, address addr)";

/* eslint-disable @typescript-eslint/no-explicit-any */

function struct(tuple) {
  if (typeof tuple !== "object") return tuple;
  var keys = Object.keys(tuple); // check if tuple is actually an array
  // [1, 2, 3] => array vs [1, 2, 3, "a": 1, "b": 2, "c": 3] => object
  // NOTE: [] are not picked up as array (see *)

  var properties = keys.filter(function (key) {
    return isNaN(Number(key));
  }); // eslint-disable-next-line @typescript-eslint/no-use-before-define

  if (properties.length === 0) return structArray(tuple);
  var copy = {};
  properties.forEach(function (property) {
    var value = tuple[property];

    if (typeof value === "object" && !bignumber$1.isBigNumberish(value)) {
      // recursive!
      copy[property] = struct(value);
    } else if (Array.isArray(value)) {
      // (*) all empty arrays are picked up here
      copy[property] = value;
    } else if (bignumber$1.isBigNumberish(value)) {
      // all BigNumbers are converted to strings
      copy[property] = value.toString();
    } else {
      copy[property] = value;
    }
  });
  return copy;
} // convert arrays

function structArray(tuples) {
  return tuples.map(function (tuple) {
    return struct(tuple);
  });
}

var CyTokenMetadataAbi = "tuple(\n  uint256 totalSuppliedUsdc,\n  uint256 totalBorrowedUsdc,\n  uint256 lendAprBips,\n  uint256 borrowAprBips,\n  uint256 liquidity,\n  uint256 liquidityUsdc,\n  uint256 totalCollateralTokens,\n  uint256 collateralFactor,\n  uint256 collateralCap,\n  bool isActive,\n  uint256 reserveFactor,\n  uint256 exchangeRate\n)";
var CyTokenUserMetadataAbi = "tuple(\n  address assetAddress,\n  bool enteredMarket,\n  uint256 supplyBalanceUsdc,\n  uint256 borrowBalanceUsdc,\n  uint256 collateralBalanceUsdc,\n  uint256 borrowLimitUsdc\n)";
var IronBankUserSummaryAbi = "tuple(\n  uint256 supplyBalanceUsdc,\n  uint256 borrowBalanceUsdc,\n  uint256 borrowLimitUsdc,\n  uint256 utilizationRatioBips\n)";
var CustomAbi = ["function adapterPositionOf(address) external view returns (" + IronBankUserSummaryAbi + " memory)", "function assetsUserMetadata(address) public view returns (" + CyTokenUserMetadataAbi + "[] memory)", "function blocksPerYear() public view returns (uint256)"];
var IronBankAdapter = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(IronBankAdapter, _ContractService);

  function IronBankAdapter() {
    return _ContractService.apply(this, arguments) || this;
  }

  var _proto = IronBankAdapter.prototype;

  /**
   * Get the static part of IronBank assets.
   * @param addresses filter, if not provided all assets are returned
   * @param overrides
   * @returns static
   */
  _proto.assetsStatic =
  /*#__PURE__*/
  function () {
    var _assetsStatic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context.next = 3;
              return this.contract;

            case 3:
              contract = _context.sent;

              if (!addresses) {
                _context.next = 6;
                break;
              }

              return _context.abrupt("return", contract.read["assetsStatic(address[])"](addresses, overrides).then(structArray));

            case 6:
              return _context.abrupt("return", contract.read["assetsStatic()"](overrides).then(structArray));

            case 7:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function assetsStatic(_x, _x2) {
      return _assetsStatic.apply(this, arguments);
    }

    return assetsStatic;
  }()
  /**
   * Get the dynamic part of IronBank assets.
   * @param addresses filter, if not provided all assets are returned
   * @param overrides
   * @returns dynamic
   */
  ;

  _proto.assetsDynamic =
  /*#__PURE__*/
  function () {
    var _assetsDynamic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses, overrides) {
      var contract, assetsPromise, _yield$Promise$all, assets, blocksPerYear, _iterator, _step, asset;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context2.next = 3;
              return this.contract;

            case 3:
              contract = _context2.sent;
              assetsPromise = addresses ? contract.read["assetsDynamic(address[])"](addresses, overrides).then(structArray) : contract.read["assetsDynamic()"](overrides).then(structArray);
              _context2.next = 7;
              return Promise.all([assetsPromise, this.blocksPerYear()]);

            case 7:
              _yield$Promise$all = _context2.sent;
              assets = _yield$Promise$all[0];
              blocksPerYear = _yield$Promise$all[1];

              for (_iterator = _createForOfIteratorHelperLoose(assets); !(_step = _iterator()).done;) {
                asset = _step.value;
                asset.metadata.lendApyBips = this.aprBipsToApyBips(asset.metadata.lendAprBips, blocksPerYear);
                asset.metadata.borrowApyBips = this.aprBipsToApyBips(asset.metadata.borrowAprBips, blocksPerYear);
              }

              return _context2.abrupt("return", assets);

            case 12:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function assetsDynamic(_x3, _x4) {
      return _assetsDynamic.apply(this, arguments);
    }

    return assetsDynamic;
  }()
  /**
   * Get all IronBankMarket asset positions for a particular address.
   * @param address
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.positionsOf =
  /*#__PURE__*/
  function () {
    var _positionsOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(address, addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context3.next = 3;
              return this.contract;

            case 3:
              contract = _context3.sent;

              if (!addresses) {
                _context3.next = 6;
                break;
              }

              return _context3.abrupt("return", contract.read["assetsPositionsOf(address,address[])"](address, addresses, overrides).then(structArray));

            case 6:
              return _context3.abrupt("return", contract.read["assetsPositionsOf(address)"](address, overrides).then(structArray));

            case 7:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function positionsOf(_x5, _x6, _x7) {
      return _positionsOf.apply(this, arguments);
    }

    return positionsOf;
  }()
  /**
   * Get the IronBank Position for a particular address.
   * @param address
   * @param overrides
   * @returns
   */
  ;

  _proto.generalPositionOf =
  /*#__PURE__*/
  function () {
    var _generalPositionOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(address, overrides) {
      var contract;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context4.next = 3;
              return this.contract;

            case 3:
              contract = _context4.sent;
              return _context4.abrupt("return", contract.read.adapterPositionOf(address, overrides).then(struct));

            case 5:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function generalPositionOf(_x8, _x9) {
      return _generalPositionOf.apply(this, arguments);
    }

    return generalPositionOf;
  }()
  /**
   * Get the IronBank User Metadata for a particular address.
   * @param address
   * @param overrides
   * @returns
   */
  ;

  _proto.assetsUserMetadata =
  /*#__PURE__*/
  function () {
    var _assetsUserMetadata = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(address, addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context5.next = 3;
              return this.contract;

            case 3:
              contract = _context5.sent;

              if (!addresses) {
                _context5.next = 6;
                break;
              }

              return _context5.abrupt("return", contract.read["assetsUserMetadata(address,address[])"](address, addresses, overrides).then(structArray));

            case 6:
              return _context5.abrupt("return", contract.read["assetsUserMetadata(address)"](address, overrides).then(structArray));

            case 7:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function assetsUserMetadata(_x10, _x11, _x12) {
      return _assetsUserMetadata.apply(this, arguments);
    }

    return assetsUserMetadata;
  }()
  /**
   * Get all IronBank underlying token addresses.
   * @param overrides
   * @returns
   */
  ;

  _proto.tokens =
  /*#__PURE__*/
  function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(overrides) {
      var contract;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context6.next = 3;
              return this.contract;

            case 3:
              contract = _context6.sent;
              return _context6.abrupt("return", contract.read.assetsTokensAddresses(overrides));

            case 5:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function tokens(_x13) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }();

  _proto.blocksPerYear = /*#__PURE__*/function () {
    var _blocksPerYear = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(overrides) {
      var contract, blocks;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context7.next = 3;
              return this.contract;

            case 3:
              contract = _context7.sent;
              _context7.next = 6;
              return contract.read["blocksPerYear"](overrides);

            case 6:
              blocks = _context7.sent;
              return _context7.abrupt("return", blocks.toString());

            case 8:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function blocksPerYear(_x14) {
      return _blocksPerYear.apply(this, arguments);
    }

    return blocksPerYear;
  }();

  _proto.aprBipsToApyBips = function aprBipsToApyBips(aprBips, period) {
    var bn = BigNumber.BigNumber.clone({
      POW_PRECISION: 6
    });
    var apy = new bn(aprBips).div(new bn(10).pow(4)).div(period).plus(1).pow(period).minus(1).multipliedBy(new bn(10).pow(4)).toFixed(0);
    return apy;
  };

  _createClass(IronBankAdapter, [{
    key: "contract",
    get: function get() {
      return this._getContract(IronBankAdapter.abi, IronBankAdapter.contractId, this.ctx);
    }
  }]);

  return IronBankAdapter;
}(ContractService);
IronBankAdapter.abi = /*#__PURE__*/AdapterAbi(CyTokenMetadataAbi).concat(CustomAbi);
IronBankAdapter.contractId = ContractAddressId.adapter_ironbank;

var VaultV2MetadataAbi = "tuple(\n  uint256 pricePerShare,\n  bool migrationAvailable,\n  address latestVaultAddress,\n  uint256 depositLimit,\n  bool emergencyShutdown\n)";
var RegistryV2Adapter = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(RegistryV2Adapter, _ContractService);

  function RegistryV2Adapter() {
    return _ContractService.apply(this, arguments) || this;
  }

  var _proto = RegistryV2Adapter.prototype;

  /**
   * Get the static part of Vault assets.
   * @param addresses filter, if not provided all assets are returned
   * @param overrides
   * @returns static
   */
  _proto.assetsStatic =
  /*#__PURE__*/
  function () {
    var _assetsStatic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context.next = 3;
              return this.contract;

            case 3:
              contract = _context.sent;

              if (!addresses) {
                _context.next = 6;
                break;
              }

              return _context.abrupt("return", contract.read["assetsStatic(address[])"](addresses, overrides).then(structArray));

            case 6:
              return _context.abrupt("return", contract.read["assetsStatic()"]().then(structArray));

            case 7:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function assetsStatic(_x, _x2) {
      return _assetsStatic.apply(this, arguments);
    }

    return assetsStatic;
  }()
  /**
   * Get the dynamic part of Vault assets.
   * @param addresses filter, if not provided all assets are returned
   * @param overrides
   * @returns dynamic
   */
  ;

  _proto.assetsDynamic =
  /*#__PURE__*/
  function () {
    var _assetsDynamic = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context2.next = 3;
              return this.contract;

            case 3:
              contract = _context2.sent;

              if (!addresses) {
                _context2.next = 6;
                break;
              }

              return _context2.abrupt("return", contract.read["assetsDynamic(address[])"](addresses, overrides).then(structArray).then(function (assets) {
                return assets.map(function (asset) {
                  return _extends({}, asset, {
                    metadata: _extends({
                      controller: ZeroAddress,
                      totalAssets: "0",
                      totalSupply: "0"
                    }, asset.metadata)
                  });
                });
              }));

            case 6:
              return _context2.abrupt("return", contract.read["assetsDynamic()"]().then(structArray).then(function (assets) {
                return assets.map(function (asset) {
                  return _extends({}, asset, {
                    metadata: _extends({
                      controller: ZeroAddress,
                      totalAssets: "0",
                      totalSupply: "0"
                    }, asset.metadata)
                  });
                });
              }));

            case 7:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function assetsDynamic(_x3, _x4) {
      return _assetsDynamic.apply(this, arguments);
    }

    return assetsDynamic;
  }()
  /**
   * Get all Vault asset positions for a particular address.
   * @param address
   * @param addresses filter, if not provided all positions are returned
   * @param overrides
   * @returns
   */
  ;

  _proto.positionsOf =
  /*#__PURE__*/
  function () {
    var _positionsOf = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(address, addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context3.next = 3;
              return this.contract;

            case 3:
              contract = _context3.sent;

              if (!addresses) {
                _context3.next = 6;
                break;
              }

              return _context3.abrupt("return", contract.read["assetsPositionsOf(address,address[])"](address, addresses, overrides).then(structArray));

            case 6:
              return _context3.abrupt("return", contract.read["assetsPositionsOf(address)"](address, overrides).then(structArray));

            case 7:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function positionsOf(_x5, _x6, _x7) {
      return _positionsOf.apply(this, arguments);
    }

    return positionsOf;
  }()
  /**
   * Get all Vault underlying token addresses.
   * @param overrides
   * @returns
   */
  ;

  _proto.tokens =
  /*#__PURE__*/
  function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(overrides) {
      var contract;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context4.next = 3;
              return this.contract;

            case 3:
              contract = _context4.sent;
              return _context4.abrupt("return", contract.read.assetsTokensAddresses(overrides));

            case 5:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function tokens(_x8) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }();

  _createClass(RegistryV2Adapter, [{
    key: "contract",
    get: function get() {
      return this._getContract(RegistryV2Adapter.abi, RegistryV2Adapter.contractId, this.ctx);
    }
  }]);

  return RegistryV2Adapter;
}(ContractService);
RegistryV2Adapter.abi = /*#__PURE__*/AdapterAbi(VaultV2MetadataAbi);
RegistryV2Adapter.contractId = ContractAddressId.adapter_registry_v2;

var YearnAliases = "https://raw.githubusercontent.com/yearn/yearn-assets/master/icons/aliases.json";

var YearnAssets = function YearnAssets(chainId) {
  return "https://api.github.com/repos/yearn/yearn-assets/contents/icons/multichain-tokens/" + chainId;
};

var TrustAssets = "https://raw.githack.com/trustwallet/assets/master/blockchains/ethereum/tokenlist.json";

var YearnAsset = function YearnAsset(address, chainId) {
  return "https://raw.githack.com/yearn/yearn-assets/master/icons/multichain-tokens/" + chainId + "/" + address + "/logo-128.png";
};

var YearnAssetAlt = function YearnAssetAlt(address, chainId) {
  return "https://raw.githack.com/yearn/yearn-assets/master/icons/multichain-tokens/" + chainId + "/" + address + "/logo-alt-128.png";
};

var TrustAsset = function TrustAsset(address) {
  return "https://raw.githack.com/trustwallet/assets/master/blockchains/ethereum/assets/" + address + "/logo.png";
};
/**
 * [[AssetService]] fetches correct icons & aliases related to eth addresses
 * from trusted asset sources
 */


var AssetService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(AssetService, _Service);

  function AssetService(chainId, ctx, state) {
    var _this;

    _this = _Service.call(this, chainId, ctx) || this;
    _this.alts = [WethAddress];

    if (state) {
      _this.supported = state.supported;
      _this.aliases = state.aliases;
      _this.ready = Promise.resolve();
    } else {
      _this.supported = new Map();
      _this.aliases = new Map();
      _this.ready = _this.initialize();
    }

    return _this;
  }

  AssetService.deserializeState = function deserializeState(data) {
    var obj = JSON.parse(data);
    var supported = new Map(JSON.parse(obj.supported));
    var aliases = new Map(JSON.parse(obj.aliases));
    return {
      supported: supported,
      aliases: aliases
    };
  };

  var _proto = AssetService.prototype;

  _proto.makeSerializedState = /*#__PURE__*/function () {
    var _makeSerializedState = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
      var supportedJson, aliasesJson;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.ready;

            case 2:
              supportedJson = JSON.stringify(Array.from(this.supported.entries()));
              aliasesJson = JSON.stringify(Array.from(this.aliases.entries()));
              return _context.abrupt("return", JSON.stringify({
                supported: supportedJson,
                aliases: aliasesJson
              }));

            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function makeSerializedState() {
      return _makeSerializedState.apply(this, arguments);
    }

    return makeSerializedState;
  }();

  _proto.initialize = /*#__PURE__*/function () {
    var _initialize = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2() {
      var aliases, _iterator, _step, alias, trust, _iterator2, _step2, token, yearn, _iterator3, _step3, _token;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (!(this.chainId === 1 || this.chainId === 1337)) {
                _context2.next = 9;
                break;
              }

              _context2.next = 3;
              return fetch$1(YearnAliases).then(handleHttpError).then(function (res) {
                return res.json();
              })["catch"](function (error) {
                console.error(error);
                return [];
              });

            case 3:
              aliases = _context2.sent;

              for (_iterator = _createForOfIteratorHelperLoose(aliases); !(_step = _iterator()).done;) {
                alias = _step.value;
                this.aliases.set(alias.address, alias);
              }

              _context2.next = 7;
              return fetch$1(TrustAssets).then(handleHttpError).then(function (res) {
                return res.json();
              }).then(function (res) {
                return res.tokens;
              })["catch"](function (error) {
                console.error(error);
                return [];
              });

            case 7:
              trust = _context2.sent;

              for (_iterator2 = _createForOfIteratorHelperLoose(trust); !(_step2 = _iterator2()).done;) {
                token = _step2.value;
                this.supported.set(token.address, TrustAsset(token.address));
              }

            case 9:
              _context2.next = 11;
              return fetch$1(YearnAssets(this.chainId)).then(handleHttpError).then(function (res) {
                return res.json();
              })["catch"](function (error) {
                console.error(error);
                return [];
              });

            case 11:
              yearn = _context2.sent;

              for (_iterator3 = _createForOfIteratorHelperLoose(yearn); !(_step3 = _iterator3()).done;) {
                _token = _step3.value;
                this.supported.set(_token.name, YearnAsset(_token.name, this.chainId));

                if (this.alts.includes(_token.name)) {
                  this.supported.set(_token.name, YearnAssetAlt(_token.name, this.chainId));
                } else {
                  this.supported.set(_token.name, YearnAsset(_token.name, this.chainId));
                }
              }

            case 13:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function initialize() {
      return _initialize.apply(this, arguments);
    }

    return initialize;
  }();

  _proto.icon = function icon(address) {
    var _this2 = this;

    if (!Array.isArray(address)) {
      return this.supported.get(address);
    }

    return Object.fromEntries(address.map(function (address) {
      return [address, _this2.supported.get(address)];
    }));
  };

  _proto.alias = function alias(address) {
    var _this3 = this;

    if (!Array.isArray(address)) {
      return this.aliases.get(address);
    }

    return Object.fromEntries(address.map(function (address) {
      return [address, _this3.aliases.get(address)];
    }));
  };

  return AssetService;
}(Service);

/**
 * [[LensService]] provides access to all yearn's adapters for assets and user positions.
 */

var LensService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(LensService, _Service);

  function LensService(chainId, ctx, addressProvider) {
    var _this;

    _this = _Service.call(this, chainId, ctx) || this;
    _this.addressProvider = addressProvider;
    return _this;
  }

  _createClass(LensService, [{
    key: "adapters",
    get: function get() {
      return {
        vaults: {
          v2: new RegistryV2Adapter(this.chainId, this.ctx, this.addressProvider)
        },
        ironBank: new IronBankAdapter(this.chainId, this.ctx, this.addressProvider)
      };
    }
  }]);

  return LensService;
}(Service);

var OracleAbi = [// Oracle general
"function calculations() external view returns (address[] memory)", "function getPriceUsdcRecommended(address) public view returns (uint256)", "function usdcAddress() public view returns (address)", "function getNormalizedValueUsdc(address,uint256) view returns (uint256)", // Calculations Curve
"function isCurveLpToken(address) public view returns (bool)", "function getCurvePriceUsdc(address) public view returns (uint256)", "function getBasePrice(address) public view returns (uint256)", "function getVirtualPrice(address) public view returns (uint256)", "function curveRegistryAddress() public view returns (address)", // Calculations Iron Bank
"function isIronBankMarket(address) public view returns (bool)", "function getIronBankMarketPriceUsdc(address) public view returns (uint256)", "function getIronBankMarkets() public view returns (address[] memory)", // Calculations Sushiswap
"function isLpToken(address) public view returns (bool)", "function getPriceFromRouter(address, address) public view returns (uint256)", "function getPriceFromRouterUsdc(address) public view returns (uint256)", "function getLpTokenTotalLiquidityUsdc(address) public view returns (uint256)", "function getLpTokenPriceUsdc(address) public view returns (uint256)"];
/**
 * [[OracleService]] is the main pricing engine, used by all price calculations.
 * It's implemented in the form of a contract that lives on all networks
 * supported by yearn.
 */

var OracleService = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(OracleService, _ContractService);

  function OracleService() {
    return _ContractService.apply(this, arguments) || this;
  }

  var _proto = OracleService.prototype;

  /**
   * Fetch all the active Oracle calculations.
   * @param overrides
   * @returns list of calculations contract addresses
   */
  _proto.getCalculations =
  /*#__PURE__*/
  function () {
    var _getCalculations = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(overrides) {
      var contract;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context.next = 3;
              return this.contract;

            case 3:
              contract = _context.sent;
              return _context.abrupt("return", contract.read.calculations(overrides));

            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function getCalculations(_x) {
      return _getCalculations.apply(this, arguments);
    }

    return getCalculations;
  }()
  /**
   * Get the suggested Usdc exchange rate for an token.
   * @param token
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getPriceUsdc =
  /*#__PURE__*/
  function () {
    var _getPriceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context2.next = 3;
              return this.contract;

            case 3:
              contract = _context2.sent;
              return _context2.abrupt("return", contract.read.getPriceUsdcRecommended(token, overrides).then(_int));

            case 5:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function getPriceUsdc(_x2, _x3) {
      return _getPriceUsdc.apply(this, arguments);
    }

    return getPriceUsdc;
  }()
  /**
   * Get the normalized Usdc value for the token and corresponding quantity.
   * @param token
   * @param amount
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getNormalizedValueUsdc =
  /*#__PURE__*/
  function () {
    var _getNormalizedValueUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(token, amount, overrides) {
      var contract;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context3.next = 3;
              return this.contract;

            case 3:
              contract = _context3.sent;
              return _context3.abrupt("return", contract.read.getNormalizedValueUsdc(token, amount, overrides).then(_int));

            case 5:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function getNormalizedValueUsdc(_x4, _x5, _x6) {
      return _getNormalizedValueUsdc.apply(this, arguments);
    }

    return getNormalizedValueUsdc;
  }()
  /**
   * Get the token address that lens considers Usdc.
   * @param overrides
   * @returns address
   */
  ;

  _proto.getUsdcAddress =
  /*#__PURE__*/
  function () {
    var _getUsdcAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(overrides) {
      var contract;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context4.next = 3;
              return this.contract;

            case 3:
              contract = _context4.sent;
              return _context4.abrupt("return", contract.read.usdcAddress(overrides));

            case 5:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function getUsdcAddress(_x7) {
      return _getUsdcAddress.apply(this, arguments);
    }

    return getUsdcAddress;
  }() // Calculations Curve

  /**
   * Test if a token address is a curve liquidity provider token.
   * @param lpToken
   * @param overrides
   * @returns test result
   */
  ;

  _proto.isCurveLpToken =
  /*#__PURE__*/
  function () {
    var _isCurveLpToken = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(lpToken, overrides) {
      var contract;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context5.next = 3;
              return this.contract;

            case 3:
              contract = _context5.sent;
              return _context5.abrupt("return", contract.read.isCurveLpToken(lpToken, overrides));

            case 5:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function isCurveLpToken(_x8, _x9) {
      return _isCurveLpToken.apply(this, arguments);
    }

    return isCurveLpToken;
  }()
  /**
   * Get Usdc exchange rate for a curve liquidity provider token.
   * @param lpToken
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getCurvePriceUsdc =
  /*#__PURE__*/
  function () {
    var _getCurvePriceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(lpToken, overrides) {
      var contract;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context6.next = 3;
              return this.contract;

            case 3:
              contract = _context6.sent;
              return _context6.abrupt("return", contract.read.getCurvePriceUsdc(lpToken, overrides).then(_int));

            case 5:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function getCurvePriceUsdc(_x10, _x11) {
      return _getCurvePriceUsdc.apply(this, arguments);
    }

    return getCurvePriceUsdc;
  }()
  /**
   * Get Usdc exchange rate of underlying token of the curve liquidity provider
   * token's pool.
   * @param lpToken
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getBasePrice =
  /*#__PURE__*/
  function () {
    var _getBasePrice = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(lpToken, overrides) {
      var contract;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context7.next = 3;
              return this.contract;

            case 3:
              contract = _context7.sent;
              return _context7.abrupt("return", contract.read.getBasePrice(lpToken, overrides).then(_int));

            case 5:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function getBasePrice(_x12, _x13) {
      return _getBasePrice.apply(this, arguments);
    }

    return getBasePrice;
  }()
  /**
   * Get virtual price for a curve liquidity provider token.
   * @param lpToken
   * @param overrides
   * @returns virtual price
   */
  ;

  _proto.getVirtualPrice =
  /*#__PURE__*/
  function () {
    var _getVirtualPrice = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(lpToken, overrides) {
      var contract;
      return runtime_1.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context8.next = 3;
              return this.contract;

            case 3:
              contract = _context8.sent;
              return _context8.abrupt("return", contract.read.getVirtualPrice(lpToken, overrides).then(_int));

            case 5:
            case "end":
              return _context8.stop();
          }
        }
      }, _callee8, this);
    }));

    function getVirtualPrice(_x14, _x15) {
      return _getVirtualPrice.apply(this, arguments);
    }

    return getVirtualPrice;
  }()
  /**
   * Get the contract address that lens considers as Curve Registry.
   * @param overrides
   * @returns
   */
  ;

  _proto.getCurveRegistryAddress =
  /*#__PURE__*/
  function () {
    var _getCurveRegistryAddress = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(overrides) {
      var contract;
      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context9.next = 3;
              return this.contract;

            case 3:
              contract = _context9.sent;
              return _context9.abrupt("return", contract.read.usdcAddress(overrides).then(_int));

            case 5:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function getCurveRegistryAddress(_x16) {
      return _getCurveRegistryAddress.apply(this, arguments);
    }

    return getCurveRegistryAddress;
  }() // Calculations: Iron Bank

  /**
   * Test if a token address is an iron bank market.
   * @param token
   * @param overrides
   * @returns test result
   */
  ;

  _proto.isIronBankMarket =
  /*#__PURE__*/
  function () {
    var _isIronBankMarket = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context10.next = 3;
              return this.contract;

            case 3:
              contract = _context10.sent;
              return _context10.abrupt("return", contract.read.isIronBankMarket(token, overrides));

            case 5:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function isIronBankMarket(_x17, _x18) {
      return _isIronBankMarket.apply(this, arguments);
    }

    return isIronBankMarket;
  }()
  /**
   * Get Usdc exchange rate for an iron bank market token.
   * @param token
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getIronBankMarketPriceUsdc =
  /*#__PURE__*/
  function () {
    var _getIronBankMarketPriceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee11(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee11$(_context11) {
        while (1) {
          switch (_context11.prev = _context11.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context11.next = 3;
              return this.contract;

            case 3:
              contract = _context11.sent;
              return _context11.abrupt("return", contract.read.getIronBankMarketPriceUsdc(token, overrides).then(_int));

            case 5:
            case "end":
              return _context11.stop();
          }
        }
      }, _callee11, this);
    }));

    function getIronBankMarketPriceUsdc(_x19, _x20) {
      return _getIronBankMarketPriceUsdc.apply(this, arguments);
    }

    return getIronBankMarketPriceUsdc;
  }()
  /**
   * Get all the iron bank market addresses.
   * @param overrides
   * @returns list of iron bank market addresses
   */
  ;

  _proto.getIronBankMarkets =
  /*#__PURE__*/
  function () {
    var _getIronBankMarkets = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee12(overrides) {
      var contract;
      return runtime_1.wrap(function _callee12$(_context12) {
        while (1) {
          switch (_context12.prev = _context12.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context12.next = 3;
              return this.contract;

            case 3:
              contract = _context12.sent;
              return _context12.abrupt("return", contract.read.getIronBankMarkets(overrides));

            case 5:
            case "end":
              return _context12.stop();
          }
        }
      }, _callee12, this);
    }));

    function getIronBankMarkets(_x21) {
      return _getIronBankMarkets.apply(this, arguments);
    }

    return getIronBankMarkets;
  }() // Calculations: Sushiswap

  /**
   * Test if a token address is a sushiswap liquidity provider token.
   * @param token
   * @param overrides
   * @returns test result
   */
  ;

  _proto.isLpToken =
  /*#__PURE__*/
  function () {
    var _isLpToken = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee13(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee13$(_context13) {
        while (1) {
          switch (_context13.prev = _context13.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context13.next = 3;
              return this.contract;

            case 3:
              contract = _context13.sent;
              return _context13.abrupt("return", contract.read.isLpToken(token, overrides));

            case 5:
            case "end":
              return _context13.stop();
          }
        }
      }, _callee13, this);
    }));

    function isLpToken(_x22, _x23) {
      return _isLpToken.apply(this, arguments);
    }

    return isLpToken;
  }()
  /**
   * Get exchange rate between two tokens from the sushiswap router.
   * @param token0
   * @param token1
   * @param overrides
   * @returns exchange rate
   */
  ;

  _proto.getPriceFromRouter =
  /*#__PURE__*/
  function () {
    var _getPriceFromRouter = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee14(token0, token1, overrides) {
      var contract;
      return runtime_1.wrap(function _callee14$(_context14) {
        while (1) {
          switch (_context14.prev = _context14.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context14.next = 3;
              return this.contract;

            case 3:
              contract = _context14.sent;
              return _context14.abrupt("return", contract.read.getPriceFromRouter(token0, token1, overrides).then(_int));

            case 5:
            case "end":
              return _context14.stop();
          }
        }
      }, _callee14, this);
    }));

    function getPriceFromRouter(_x24, _x25, _x26) {
      return _getPriceFromRouter.apply(this, arguments);
    }

    return getPriceFromRouter;
  }()
  /**
   * Get Usdc exchange rate for a token.
   * @param token
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getPriceFromRouterUsdc =
  /*#__PURE__*/
  function () {
    var _getPriceFromRouterUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee15(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee15$(_context15) {
        while (1) {
          switch (_context15.prev = _context15.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context15.next = 3;
              return this.contract;

            case 3:
              contract = _context15.sent;
              return _context15.abrupt("return", contract.read.getPriceFromRouterUsdc(token, overrides).then(_int));

            case 5:
            case "end":
              return _context15.stop();
          }
        }
      }, _callee15, this);
    }));

    function getPriceFromRouterUsdc(_x27, _x28) {
      return _getPriceFromRouterUsdc.apply(this, arguments);
    }

    return getPriceFromRouterUsdc;
  }()
  /**
   * Get total liquidity for a liquidity provider token in Usdc
   * @param token
   * @param overrides
   * @returns Usdc liquidity (6 decimals)
   */
  ;

  _proto.getLpTokenTotalLiquidityUsdc =
  /*#__PURE__*/
  function () {
    var _getLpTokenTotalLiquidityUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee16(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee16$(_context16) {
        while (1) {
          switch (_context16.prev = _context16.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context16.next = 3;
              return this.contract;

            case 3:
              contract = _context16.sent;
              return _context16.abrupt("return", contract.read.getLpTokenTotalLiquidityUsdc(token, overrides).then(_int));

            case 5:
            case "end":
              return _context16.stop();
          }
        }
      }, _callee16, this);
    }));

    function getLpTokenTotalLiquidityUsdc(_x29, _x30) {
      return _getLpTokenTotalLiquidityUsdc.apply(this, arguments);
    }

    return getLpTokenTotalLiquidityUsdc;
  }()
  /**
   * Get Usdc exchange rate for a sushiswap liquidity provider token.
   * @param token
   * @param overrides
   * @returns Usdc exchange rate (6 decimals)
   */
  ;

  _proto.getLpTokenPriceUsdc =
  /*#__PURE__*/
  function () {
    var _getLpTokenPriceUsdc = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee17(token, overrides) {
      var contract;
      return runtime_1.wrap(function _callee17$(_context17) {
        while (1) {
          switch (_context17.prev = _context17.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context17.next = 3;
              return this.contract;

            case 3:
              contract = _context17.sent;
              return _context17.abrupt("return", contract.read.getLpTokenPriceUsdc(token, overrides).then(_int));

            case 5:
            case "end":
              return _context17.stop();
          }
        }
      }, _callee17, this);
    }));

    function getLpTokenPriceUsdc(_x31, _x32) {
      return _getLpTokenPriceUsdc.apply(this, arguments);
    }

    return getLpTokenPriceUsdc;
  }();

  _createClass(OracleService, [{
    key: "contract",
    get: function get() {
      return this._getContract(OracleService.abi, OracleService.contractId, this.ctx);
    }
  }]);

  return OracleService;
}(ContractService);
OracleService.abi = OracleAbi;
OracleService.contractId = ContractAddressId.oracle;

var SubgraphService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(SubgraphService, _Service);

  function SubgraphService(chainId, ctx) {
    var _ctx$subgraph, _ctx$subgraph2, _ctx$subgraph3;

    var _this;

    _this = _Service.call(this, chainId, ctx) || this;

    switch (chainId) {
      case 1:
      case 1337:
        // no fallback for mainnet as the hosted version has been deprecated.
        _this.yearnSubgraphEndpoint = (_ctx$subgraph = ctx.subgraph) == null ? void 0 : _ctx$subgraph.mainnetSubgraphEndpoint;
        break;

      case 250:
        _this.yearnSubgraphEndpoint = ((_ctx$subgraph2 = ctx.subgraph) == null ? void 0 : _ctx$subgraph2.fantomSubgraphEndpoint) || "https://api.thegraph.com/subgraphs/name/yearn/yearn-vaults-v2-fantom";
        break;

      case 42161:
        _this.yearnSubgraphEndpoint = ((_ctx$subgraph3 = ctx.subgraph) == null ? void 0 : _ctx$subgraph3.arbitrumSubgraphEndpoint) || "https://api.thegraph.com/subgraphs/name/yearn/yearn-vaults-v2-arbitrum";
        break;

      default:
        throw new SdkError("No subgraph name for chain " + chainId);
    }

    return _this;
  }

  var _proto = SubgraphService.prototype;

  _proto.fetchQuery = /*#__PURE__*/function () {
    var _fetchQuery = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(query, variables) {
      var body;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (variables === void 0) {
                variables = {};
              }

              if (this.yearnSubgraphEndpoint) {
                _context.next = 3;
                break;
              }

              throw new SdkError("the subgraph service has not been configured to be able to make queries, configure it in the `Context` object");

            case 3:
              // the subgraph only works with lowercased addresses
              Object.keys(variables).forEach(function (key) {
                var variable = variables[key];

                if (typeof variable === "string") {
                  variables[key] = variable.toLowerCase();
                } else if (Array.isArray(variable)) {
                  for (var _iterator = _createForOfIteratorHelperLoose(variable.entries()), _step; !(_step = _iterator()).done;) {
                    var _step$value = _step.value,
                        index = _step$value[0],
                        value = _step$value[1];

                    if (typeof value === "string") {
                      variable[index] = value.toLowerCase();
                    }
                  }
                }
              });
              body = {
                query: query,
                variables: variables
              };
              _context.next = 7;
              return fetch(this.yearnSubgraphEndpoint, {
                method: "POST",
                headers: {
                  "Content-Type": "application/json"
                },
                body: JSON.stringify(body)
              }).then(function (res) {
                return res.json();
              }).then(function (json) {
                if (json.errors) {
                  throw new SdkError("Subgraph Error - " + JSON.stringify(json.errors));
                }

                return json;
              });

            case 7:
              return _context.abrupt("return", _context.sent);

            case 8:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function fetchQuery(_x, _x2) {
      return _fetchQuery.apply(this, arguments);
    }

    return fetchQuery;
  }();

  return SubgraphService;
}(Service);

var TelegramService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(TelegramService, _Service);

  function TelegramService() {
    return _Service.apply(this, arguments) || this;
  }

  var _proto = TelegramService.prototype;

  _proto.sendMessage = function sendMessage(text) {
    if (!this.ctx.simulation.telegramChatId || !this.ctx.simulation.telegramBotId) {
      return;
    }

    var params = new URLSearchParams({
      chat_id: this.ctx.simulation.telegramChatId,
      text: text,
      disable_web_page_preview: "true"
    });
    var url = "https://api.telegram.org/bot" + this.ctx.simulation.telegramBotId + "/sendMessage?" + params;
    fetch(url);
  };

  return TelegramService;
}(Service);

/**
 * Fix for backscratcher vaults returning different casing and property names so it's all normalized.
 */

function convertCompositeApyToSnakeCase(apy) {
  return apy ? _extends({}, apy, {
    composite: apy.composite ? _extends({}, apy.composite, {
      boost: apy.composite.boost ? apy.composite.boost : apy.composite.currentBoost,
      pool_apy: apy.composite.pool_apy ? apy.composite.pool_apy : apy.composite.poolApy,
      boosted_apr: apy.composite.boosted_apr ? apy.composite.boosted_apr : apy.composite.boostedApy,
      base_apr: apy.composite.base_apr ? apy.composite.base_apr : apy.composite.baseApy
    }) : null
  }) : undefined;
}
/**
 * [[VisionService]] provides access to off chain apy calculations for yearn
 * products.
 */

var VisionService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(VisionService, _Service);

  function VisionService() {
    return _Service.apply(this, arguments) || this;
  }

  var _proto = VisionService.prototype;

  _proto.apy = /*#__PURE__*/function () {
    var _apy = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses) {
      var url, vaults, map, _loop, _iterator, _step, vault;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              url = "https://d28fcsszptni1s.cloudfront.net/v1/chains/" + this.chainId + "/vaults/all";
              _context.next = 3;
              return fetch(url).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 3:
              vaults = _context.sent;
              // fix backscratcher apys
              vaults = vaults.map(function (vault) {
                return vault.apy && vault.apy.type === "backscratcher" ? _extends({}, vault, {
                  apy: convertCompositeApyToSnakeCase(vault.apy)
                }) : vault;
              });

              if (!Array.isArray(addresses)) {
                _context.next = 12;
                break;
              }

              map = new Map();

              _loop = function _loop() {
                var address = _step.value;
                var vault = vaults.find(function (vault) {
                  return vault.address === address;
                });
                map.set(address, vault ? vault.apy : undefined);
              };

              for (_iterator = _createForOfIteratorHelperLoose(addresses); !(_step = _iterator()).done;) {
                _loop();
              }

              return _context.abrupt("return", Object.fromEntries(map));

            case 12:
              if (!addresses) {
                _context.next = 19;
                break;
              }

              vault = vaults.find(function (vault) {
                return vault.address === addresses;
              });

              if (vault) {
                _context.next = 16;
                break;
              }

              return _context.abrupt("return", undefined);

            case 16:
              return _context.abrupt("return", vault.apy);

            case 19:
              return _context.abrupt("return", Object.fromEntries(vaults.map(function (vault) {
                return [vault.address, vault.apy];
              })));

            case 20:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function apy(_x) {
      return _apy.apply(this, arguments);
    }

    return apy;
  }();

  return VisionService;
}(Service);

var ZAPPER_AFFILIATE_ADDRESS = "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52";
/**
 * [[ZapperService]] interacts with the zapper api to gather more insight for
 * tokens and user positions.
 */

var ZapperService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(ZapperService, _Service);

  function ZapperService() {
    return _Service.apply(this, arguments) || this;
  }

  var _proto = ZapperService.prototype;

  /**
   * Fetch all the tokens supported by the zapper protocol along with some basic
   * metadata.
   * @returns list of tokens supported by the zapper protocol.
   */
  _proto.supportedTokens =
  /*#__PURE__*/
  function () {
    var _supportedTokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee() {
      var url, zapperTokens, network, visibleZapperTokens;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              url = "https://api.zapper.fi/v2/prices";
              _context.next = 3;
              return fetch(url, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 3:
              zapperTokens = _context.sent;
              network = Chains[this.chainId];
              visibleZapperTokens = zapperTokens.filter(function (zapperToken) {
                return !zapperToken.hide;
              });
              return _context.abrupt("return", visibleZapperTokens.map(function (zapperToken) {
                var address$1 = zapperToken.address === ZeroAddress ? EthAddress : address.getAddress(zapperToken.address);
                return {
                  address: address$1,
                  decimals: String(zapperToken.decimals),
                  // addresses in the icon url should always be lowercase to be fetched correctly
                  icon: "https://assets.yearn.network/tokens/" + network + "/" + zapperToken.address + ".png",
                  name: zapperToken.symbol,
                  priceUsdc: usdc(zapperToken.price),
                  dataSource: "zapper",
                  supported: {
                    zapper: true
                  },
                  symbol: zapperToken.symbol
                };
              }));

            case 7:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function supportedTokens() {
      return _supportedTokens.apply(this, arguments);
    }

    return supportedTokens;
  }();

  _proto.balances = /*#__PURE__*/function () {
    var _balances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses) {
      var url, params, _yield$fetch$then$the, balances;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              url = "https://api.zapper.fi/v2/apps/tokens/balances";
              params = new URLSearchParams({
                "addresses[]": Array.isArray(addresses) ? addresses.join() : addresses
              });
              _context2.next = 4;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 4:
              _yield$fetch$then$the = _context2.sent;
              balances = _yield$fetch$then$the.balances;
              Object.keys(balances).forEach(function (address$1) {
                var copy = balances[address$1];
                delete balances[address$1];

                if (copy.products.length === 0) {
                  balances[address.getAddress(address$1)] = [];
                } else {
                  var assets = copy.products[0].assets;
                  balances[address.getAddress(address$1)] = assets.map(function (balance) {
                    var address$1 = balance.address === ZeroAddress ? EthAddress : address.getAddress(String(balance.address));
                    return {
                      address: address$1,
                      token: {
                        address: address$1,
                        name: balance.symbol,
                        symbol: balance.symbol,
                        decimals: balance.decimals
                      },
                      balance: balance.balanceRaw,
                      balanceUsdc: usdc(balance.balanceUSD),
                      priceUsdc: usdc(balance.price)
                    };
                  });
                }
              });

              if (Array.isArray(addresses)) {
                _context2.next = 9;
                break;
              }

              return _context2.abrupt("return", balances[addresses]);

            case 9:
              return _context2.abrupt("return", balances);

            case 10:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function balances(_x) {
      return _balances.apply(this, arguments);
    }

    return balances;
  }()
  /**
   * Fetches vault token market data for the Yearn application
   * @returns list of zapper supported vault addresses
   */
  ;

  _proto.supportedVaultAddresses =
  /*#__PURE__*/
  function () {
    var _supportedVaultAddresses = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3() {
      var url, params, vaultTokenMarketData;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              if (isEthereum(this.chainId)) {
                _context3.next = 2;
                break;
              }

              throw new SdkError("Only Ethereum is supported for token market data, got " + this.chainId);

            case 2:
              url = "https://api.zapper.fi/v2/apps/yearn/tokens";
              params = new URLSearchParams({
                network: "ethereum",
                groupId: "vault"
              });
              _context3.next = 6;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 6:
              vaultTokenMarketData = _context3.sent;
              return _context3.abrupt("return", vaultTokenMarketData.map(function (vaultTokenMarketData) {
                return address.getAddress(vaultTokenMarketData.address);
              }).filter(function (address) {
                return !!address;
              }));

            case 8:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function supportedVaultAddresses() {
      return _supportedVaultAddresses.apply(this, arguments);
    }

    return supportedVaultAddresses;
  }()
  /**
   * Fetch up to date gas prices in gwei
   * @returns gas prices
   */
  ;

  _proto.gas =
  /*#__PURE__*/
  function () {
    var _gas = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4() {
      var url, params, gas;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              url = "https://api.zapper.fi/v2/gas-prices";
              params = new URLSearchParams({
                eip1559: "false"
              });
              _context4.next = 4;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 4:
              gas = _context4.sent;
              return _context4.abrupt("return", gas);

            case 6:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function gas() {
      return _gas.apply(this, arguments);
    }

    return gas;
  }()
  /**
   * Fetches the data needed to check token ZapIn contract approval state
   * @param from - the address that is depositing
   * @param token - the token to be sold to pay for the deposit
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   */
  ;

  _proto.zapInApprovalState =
  /*#__PURE__*/
  function () {
    var _zapInApprovalState = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(from, token, zapProtocol) {
      var url, params, response;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              url = "https://api.zapper.fi/v2/zap-in/vault/" + zapProtocol + "/approval-state";
              params = new URLSearchParams({
                ownerAddress: from,
                sellTokenAddress: token
              });
              _context5.next = 5;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 5:
              response = _context5.sent;
              return _context5.abrupt("return", response);

            case 7:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function zapInApprovalState(_x2, _x3, _x4) {
      return _zapInApprovalState.apply(this, arguments);
    }

    return zapInApprovalState;
  }()
  /**
   * Fetches the data needed to approve ZapIn Contract for a token
   * @param from - the address that is depositing
   * @param token - the token to be sold to pay for the deposit
   * @param gasPrice
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   */
  ;

  _proto.zapInApprovalTransaction =
  /*#__PURE__*/
  function () {
    var _zapInApprovalTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(from, token, gasPrice, zapProtocol) {
      var url, params, response;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              url = "https://api.zapper.fi/v2/zap-in/vault/" + zapProtocol + "/approval-transaction";
              params = new URLSearchParams({
                gasPrice: gasPrice,
                ownerAddress: from,
                sellTokenAddress: token
              });
              _context6.next = 5;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 5:
              response = _context6.sent;
              return _context6.abrupt("return", response);

            case 7:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function zapInApprovalTransaction(_x5, _x6, _x7, _x8) {
      return _zapInApprovalTransaction.apply(this, arguments);
    }

    return zapInApprovalTransaction;
  }()
  /**
   * Fetches the data needed to check token ZapOut contract approval state
   * @param from - the address that is withdrawing
   * @param token - the vault token to be withdrawn
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   */
  ;

  _proto.zapOutApprovalState =
  /*#__PURE__*/
  function () {
    var _zapOutApprovalState = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee7(from, token, zapProtocol) {
      var url, params, response;
      return runtime_1.wrap(function _callee7$(_context7) {
        while (1) {
          switch (_context7.prev = _context7.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              url = "https://api.zapper.fi/v2/zap-out/vault/" + zapProtocol + "/approval-state";
              params = new URLSearchParams({
                ownerAddress: from,
                sellTokenAddress: token
              });
              _context7.next = 5;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 5:
              response = _context7.sent;
              return _context7.abrupt("return", response);

            case 7:
            case "end":
              return _context7.stop();
          }
        }
      }, _callee7, this);
    }));

    function zapOutApprovalState(_x9, _x10, _x11) {
      return _zapOutApprovalState.apply(this, arguments);
    }

    return zapOutApprovalState;
  }()
  /**
   * Fetches the data needed to approve ZapOut Contract for a token
   * @param from - the address that is withdrawing
   * @param token - the vault token to be withdrawn
   * @param gasPrice
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   */
  ;

  _proto.zapOutApprovalTransaction =
  /*#__PURE__*/
  function () {
    var _zapOutApprovalTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee8(from, token, gasPrice, zapProtocol) {
      var url, params, response;
      return runtime_1.wrap(function _callee8$(_context8) {
        while (1) {
          switch (_context8.prev = _context8.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              url = "https://api.zapper.fi/v2/zap-out/vault/" + zapProtocol + "/approval-transaction";
              params = new URLSearchParams({
                gasPrice: gasPrice,
                ownerAddress: from,
                sellTokenAddress: token
              });
              _context8.next = 5;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 5:
              response = _context8.sent;
              return _context8.abrupt("return", response);

            case 7:
            case "end":
              return _context8.stop();
          }
        }
      }, _callee8, this);
    }));

    function zapOutApprovalTransaction(_x12, _x13, _x14, _x15) {
      return _zapOutApprovalTransaction.apply(this, arguments);
    }

    return zapOutApprovalTransaction;
  }()
  /**
   * Fetches the data needed to zap into a vault
   * @param from - the address that is depositing
   * @param token - the token to be sold to pay for the deposit
   * @param amount - the amount of tokens to be sold
   * @param vault - the vault to zap into
   * @param gasPrice
   * @param slippagePercentage - slippage as a decimal
   * @param skipGasEstimate - provide the gasLimit in the response. Should be set to true when simulating a zap without approval
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   */
  ;

  _proto.zapIn =
  /*#__PURE__*/
  function () {
    var _zapIn = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee9(from, token, amount, vault, gasPrice, slippagePercentage, skipGasEstimate, zapProtocol, partnerId) {
      var sellToken, url, params, response;
      return runtime_1.wrap(function _callee9$(_context9) {
        while (1) {
          switch (_context9.prev = _context9.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              sellToken = token;

              if (EthAddress === token) {
                // If Ether is being sent, the sellTokenAddress should be the zero address
                sellToken = ZeroAddress;
              }

              url = "https://api.zapper.fi/v2/zap-in/vault/" + zapProtocol + "/transaction";
              params = new URLSearchParams(_extends({
                affiliateAddress: ZAPPER_AFFILIATE_ADDRESS,
                ownerAddress: from,
                sellTokenAddress: sellToken,
                sellAmount: amount,
                poolAddress: vault,
                gasPrice: gasPrice,
                slippagePercentage: slippagePercentage.toString(),
                skipGasEstimate: skipGasEstimate ? "true" : "false"
              }, partnerId && {
                partnerId: partnerId
              } || {}));
              _context9.next = 7;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 7:
              response = _context9.sent;
              return _context9.abrupt("return", response);

            case 9:
            case "end":
              return _context9.stop();
          }
        }
      }, _callee9, this);
    }));

    function zapIn(_x16, _x17, _x18, _x19, _x20, _x21, _x22, _x23, _x24) {
      return _zapIn.apply(this, arguments);
    }

    return zapIn;
  }()
  /**
   * Fetches the data needed to zap out of a vault
   * @param from - the address that is withdrawing
   * @param token - the token that'll be received
   * @param amount - the amount of tokens to sell
   * @param vault - the vault to zap out of
   * @param gasPrice
   * @param slippagePercentage - slippage as a decimal
   * @param skipGasEstimate - provide the gasLimit in the response. Should be set to true when simulating a zap without approval
   * @param zapProtocol the protocol to use with zapper e.g. Yearn, Pickle
   * @param signature - the account valid secp256k1 signature of Permit encoded from r, s, v. (https://eips.ethereum.org/EIPS/eip-2612)
   */
  ;

  _proto.zapOut =
  /*#__PURE__*/
  function () {
    var _zapOut = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee10(from, token, amount, vault, gasPrice, slippagePercentage, skipGasEstimate, zapProtocol, signature) {
      var toToken, url, params, response;
      return runtime_1.wrap(function _callee10$(_context10) {
        while (1) {
          switch (_context10.prev = _context10.next) {
            case 0:
              if (zapProtocol === void 0) {
                zapProtocol = exports.ZapProtocol.YEARN;
              }

              toToken = token;

              if (EthAddress === token) {
                // If Ether is being received, the toTokenAddress should be the zero address
                toToken = ZeroAddress;
              }

              url = "https://api.zapper.fi/v2/zap-out/vault/" + zapProtocol + "/transaction";
              params = new URLSearchParams(_extends({
                affiliateAddress: ZAPPER_AFFILIATE_ADDRESS,
                ownerAddress: from,
                toTokenAddress: toToken,
                sellAmount: amount,
                poolAddress: vault,
                gasPrice: gasPrice,
                slippagePercentage: slippagePercentage.toString(),
                skipGasEstimate: skipGasEstimate ? "true" : "false"
              }, signature && {
                signature: signature
              }));
              _context10.next = 7;
              return fetch(url + "?" + params, {
                headers: {
                  Authorization: "Basic " + this.ctx.zapper
                }
              }).then(handleHttpError).then(function (res) {
                return res.json();
              });

            case 7:
              response = _context10.sent;
              return _context10.abrupt("return", response);

            case 9:
            case "end":
              return _context10.stop();
          }
        }
      }, _callee10, this);
    }));

    function zapOut(_x25, _x26, _x27, _x28, _x29, _x30, _x31, _x32, _x33) {
      return _zapOut.apply(this, arguments);
    }

    return zapOut;
  }();

  return ZapperService;
}(Service);

/**
 * [[AddressProviderService]] fetches addresses of various contracts based on the
 * network and feeds them to the Yearn SDK.
 */

var AddressProvider = /*#__PURE__*/function (_Service) {
  _inheritsLoose(AddressProvider, _Service);

  function AddressProvider(chainId, ctx) {
    var _this;

    _this = _Service.call(this, chainId, ctx) || this;
    _this.contract = new WrappedContract(AddressProvider.addressByChain(chainId), AddressProvider.abi, ctx);
    _this.cachedAddressesById = new Map();
    return _this;
  }

  AddressProvider.addressByChain = function addressByChain(chainId) {
    switch (chainId) {
      case 1:
      case 1337:
        return "0xe11dC9f2Ab122dC5978EACA41483Da0D7D7e6128";

      case 250:
        return "0xac5A9E4135A3A26497F3890bFb602b06Ee592B61";

      case 42161:
        return "0xcAd10033C86B0C1ED6bfcCAa2FF6779938558E9f";

      default:
        throw new Error("Unsupported chain id: " + chainId);
    }
  };

  var _proto = AddressProvider.prototype;

  _proto.addressById = /*#__PURE__*/function () {
    var _addressById = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(id) {
      var _ref, cachedAddress, timestamp, address;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _ref = this.cachedAddressesById.get(id) || {}, cachedAddress = _ref.address, timestamp = _ref.timestamp;

              if (!(cachedAddress && this.isCacheFresh({
                timestamp: timestamp
              }))) {
                _context.next = 3;
                break;
              }

              return _context.abrupt("return", cachedAddress);

            case 3:
              _context.prev = 3;
              _context.next = 6;
              return this.contract.read.addressById(id);

            case 6:
              address = _context.sent;
              return _context.abrupt("return", this.setCachedAddressById({
                id: id,
                address: address
              }));

            case 10:
              _context.prev = 10;
              _context.t0 = _context["catch"](3);
              throw new SdkError("Failed to read contract address for " + id + ": " + _context.t0);

            case 13:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this, [[3, 10]]);
    }));

    function addressById(_x) {
      return _addressById.apply(this, arguments);
    }

    return addressById;
  }();

  _proto.setCachedAddressById = function setCachedAddressById(_ref2) {
    var id = _ref2.id,
        address = _ref2.address;
    var NOW = new Date(Date.now()).getTime();

    if (!this.cachedAddressesById.has(id)) {
      this.cachedAddressesById.set(id, {
        address: address,
        timestamp: NOW
      });
      return address;
    }

    var _ref3 = this.cachedAddressesById.get(id) || {},
        timestamp = _ref3.timestamp;

    if (!this.isCacheFresh({
      timestamp: timestamp
    })) {
      this.cachedAddressesById.set(id, {
        address: address,
        timestamp: NOW
      });
    }

    return address;
  };

  _proto.addressesMetadataByIdStartsWith = /*#__PURE__*/function () {
    var _addressesMetadataByIdStartsWith = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(prefix) {
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              return _context2.abrupt("return", this.contract.read.addressById(prefix).then(structArray));

            case 1:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function addressesMetadataByIdStartsWith(_x2) {
      return _addressesMetadataByIdStartsWith.apply(this, arguments);
    }

    return addressesMetadataByIdStartsWith;
  }();

  _proto.isCacheFresh = function isCacheFresh(_ref4) {
    var timestamp = _ref4.timestamp;

    if (!timestamp) {
      return false;
    }

    return new Date(Date.now()).getTime() - timestamp <= 30000;
  };

  return AddressProvider;
}(Service);
AddressProvider.abi = ["function addressById(string) public view returns (address)", "function addressPositionById(string) public view returns (int256)", "function addresses() public view returns (address[] memory)", "function addressesIds() public view returns (string[] memory)", "function addressesMetadata() public view returns (" + AddressMetadataAbi + "[] memory)", "function addressesMetadataByIdStartsWith(string) public view returns (" + AddressMetadataAbi + "[] memory)"];

/**
 * [[AllowListService]] is used to interface with yearn's deployed AllowList contract. The purpose of it is to be able to
 * validate that all interactions that are about to be written to the blockchain follow the set of rules that the AllowList defines on chain.
 * It should be used to validate any transaction before it is written. For example, it can be used to check that an approval transaction that the sdk makes
 * is approving a token that is an underlying asset of a vault, and also that the first parameter in the approval transaction is the address of a valid yearn vault.
 * Similarly, for a deposit transaction, it can be used to check whether the vault is a valid yearn vault
 */

var AllowListService = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(AllowListService, _ContractService);

  function AllowListService() {
    return _ContractService.apply(this, arguments) || this;
  }

  var _proto = AllowListService.prototype;

  /**
   * Uses yearn's on chain AllowList to verify whether the calldata being sent to the target contract by the sdk is valid. This should be used prior to any
   * write method, including token approvals. This method will raise an error if the parameters are not valid.
   * @param targetAddress The contract that is being interacted with e.g. for approving depositing usdc into a vault this would be usdc.
   *                      For depositing/withdrawing from a vault it'd be the vault contract itself
   * @param callData The data from the tx that should be validated. This should be from a tx that has been populated and is about to be sent
   */
  _proto.validateCalldata =
  /*#__PURE__*/
  function () {
    var _validateCalldata = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(targetAddress, callData) {
      var contract, valid;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (targetAddress) {
                _context.next = 2;
                break;
              }

              return _context.abrupt("return", {
                success: false,
                error: "can't validate a tx that isn't targeting an address"
              });

            case 2:
              if (callData) {
                _context.next = 4;
                break;
              }

              return _context.abrupt("return", {
                success: false,
                error: "can't validate a tx that has no call data"
              });

            case 4:
              _context.prev = 4;
              _context.next = 7;
              return this.contract;

            case 7:
              contract = _context.sent;

              if (!(!contract || contract.address === ZeroAddress)) {
                _context.next = 10;
                break;
              }

              throw new Error("Contract missing");

            case 10:
              _context.next = 16;
              break;

            case 12:
              _context.prev = 12;
              _context.t0 = _context["catch"](4);
              // temporary workaround after deprecating the `disableAllowlist` param
              // if allowlist has no onchain contract address, we skip validation altogether
              console.warn("AllowList on-chain contract address missing. Skipping validation...");
              return _context.abrupt("return", {
                success: true
              });

            case 16:
              _context.prev = 16;
              _context.next = 19;
              return contract.read.validateCalldataByOrigin(AllowListService.originName, targetAddress, callData);

            case 19:
              valid = _context.sent;

              if (valid) {
                _context.next = 22;
                break;
              }

              return _context.abrupt("return", {
                success: false,
                error: "tx is not permitted by the allow list"
              });

            case 22:
              return _context.abrupt("return", {
                success: true
              });

            case 25:
              _context.prev = 25;
              _context.t1 = _context["catch"](16);
              return _context.abrupt("return", {
                success: false,
                error: "failed to read from the allow list whether the transaction is valid"
              });

            case 28:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this, [[4, 12], [16, 25]]);
    }));

    function validateCalldata(_x, _x2) {
      return _validateCalldata.apply(this, arguments);
    }

    return validateCalldata;
  }();

  _createClass(AllowListService, [{
    key: "contract",
    get: function get() {
      return this._getContract(AllowListService.abi, AllowListService.contractId, this.ctx);
    }
  }]);

  return AllowListService;
}(ContractService);
AllowListService.abi = ["function validateCalldataByOrigin(string memory originName, address targetAddress, bytes calldata data) public view returns (bool)"];
AllowListService.contractId = ContractAddressId.allowlist;
/**
 * This is used by the AllowListFactory to resolve which set of rules are applicable to which organization
 */

AllowListService.originName = "yearn.finance";

var HelperAbi = ["function tokensMetadata(address[] memory) public view returns (" + TokenAbi$2 + "[] memory)", "function tokensPrices(address[] memory) public view returns (" + TokenPriceAbi + "[] memory)", "function tokensBalances(address, address[] memory) public view returns (" + TokenBalanceAbi + "[] memory)", "function allowances(address, address[] memory, address[] memory) external view returns (" + AllowanceAbi + "[] memory)", "function assetStrategiesAddresses(address) public view returns (address[])"];
/**
 * [[HelperService]] is a generalized containers for all the utilities that are
 * used in the lens codebase and in the SDK.
 */

var HelperService = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(HelperService, _ContractService);

  function HelperService() {
    return _ContractService.apply(this, arguments) || this;
  }

  var _proto = HelperService.prototype;

  /**
   * Get a list of [[ERC20]] objects for a list of token addresses.
   * @param addresses
   * @param overrides
   * @returns list of erc20 object
   */
  _proto.tokens =
  /*#__PURE__*/
  function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context.next = 3;
              return this.contract;

            case 3:
              contract = _context.sent;
              return _context.abrupt("return", contract.read.tokensMetadata(addresses, overrides).then(structArray));

            case 5:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function tokens(_x, _x2) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }()
  /**
   * Get a list of token prices for a list of token addresses.
   * @param addresses
   * @param overrides
   * @returns list of token prices
   */
  ;

  _proto.tokenPrices =
  /*#__PURE__*/
  function () {
    var _tokenPrices = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(addresses, overrides) {
      var contract;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context2.next = 3;
              return this.contract;

            case 3:
              contract = _context2.sent;
              return _context2.abrupt("return", contract.read.tokensPrices(addresses, overrides).then(structArray));

            case 5:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function tokenPrices(_x3, _x4) {
      return _tokenPrices.apply(this, arguments);
    }

    return tokenPrices;
  }()
  /**
   * Get a list of token balances from a list of token addresses for a
   * particular address.
   * @param address
   * @param tokens
   * @param overrides
   * @returns list of token balances
   */
  ;

  _proto.tokenBalances =
  /*#__PURE__*/
  function () {
    var _tokenBalances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(address, tokens, overrides) {
      var chunks, contract, promises;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              chunks = chunkArray(tokens, 30);
              _context4.next = 4;
              return this.contract;

            case 4:
              contract = _context4.sent;
              promises = chunks.map( /*#__PURE__*/function () {
                var _ref = _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(chunk) {
                  return runtime_1.wrap(function _callee3$(_context3) {
                    while (1) {
                      switch (_context3.prev = _context3.next) {
                        case 0:
                          return _context3.abrupt("return", contract.read.tokensBalances(address, chunk, overrides).then(structArray));

                        case 1:
                        case "end":
                          return _context3.stop();
                      }
                    }
                  }, _callee3);
                }));

                return function (_x8) {
                  return _ref.apply(this, arguments);
                };
              }());
              return _context4.abrupt("return", Promise.all(promises).then(function (chunks) {
                return chunks.flat();
              }));

            case 7:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function tokenBalances(_x5, _x6, _x7) {
      return _tokenBalances.apply(this, arguments);
    }

    return tokenBalances;
  }()
  /**
   * Get a list of token allowances for a list of token addresses and spenders
   * for a particular address.
   * @param address
   * @param tokens
   * @param spenders
   * @param overrides
   * @returns
   */
  ;

  _proto.tokenAllowances =
  /*#__PURE__*/
  function () {
    var _tokenAllowances = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(address, tokens, spenders, overrides) {
      var contract;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context5.next = 3;
              return this.contract;

            case 3:
              contract = _context5.sent;
              return _context5.abrupt("return", contract.read.allowances(address, tokens, spenders, overrides).then(structArray));

            case 5:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this);
    }));

    function tokenAllowances(_x9, _x10, _x11, _x12) {
      return _tokenAllowances.apply(this, arguments);
    }

    return tokenAllowances;
  }();

  _proto.assetStrategiesAddresses = /*#__PURE__*/function () {
    var _assetStrategiesAddresses = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee6(address, overrides) {
      var contract;
      return runtime_1.wrap(function _callee6$(_context6) {
        while (1) {
          switch (_context6.prev = _context6.next) {
            case 0:
              if (overrides === void 0) {
                overrides = {};
              }

              _context6.next = 3;
              return this.contract;

            case 3:
              contract = _context6.sent;
              return _context6.abrupt("return", contract.read.assetStrategiesAddresses(address, overrides));

            case 5:
            case "end":
              return _context6.stop();
          }
        }
      }, _callee6, this);
    }));

    function assetStrategiesAddresses(_x13, _x14) {
      return _assetStrategiesAddresses.apply(this, arguments);
    }

    return assetStrategiesAddresses;
  }();

  _createClass(HelperService, [{
    key: "contract",
    get: function get() {
      return this._getContract(HelperService.abi, HelperService.contractId, this.ctx);
    }
  }]);

  return HelperService;
}(ContractService);
HelperService.abi = HelperAbi;
HelperService.contractId = ContractAddressId.helper;

var META_URL = "https://meta.yearn.network";
/**
 * [[MetaService]] fetches meta data about things such as vaults and tokens
 * from yearn-meta
 */

var MetaService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(MetaService, _Service);

  function MetaService() {
    return _Service.apply(this, arguments) || this;
  }

  var _proto = MetaService.prototype;

  _proto.tokens = /*#__PURE__*/function () {
    var _tokens = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(addresses) {
      var _this = this;

      var tokensMetadata;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return fetch(META_URL + "/tokens/" + this.chainId + "/all").then(function (res) {
                return res.json();
              });

            case 2:
              tokensMetadata = _context.sent;

              if (addresses) {
                _context.next = 5;
                break;
              }

              return _context.abrupt("return", tokensMetadata.map(function (tokenMetadata) {
                return _extends({}, tokenMetadata, {
                  description: getLocalizedString({
                    obj: tokenMetadata,
                    property: "description",
                    locale: _this.ctx.locale,
                    fallback: "Token description missing"
                  })
                });
              }));

            case 5:
              return _context.abrupt("return", tokensMetadata.filter(function (tokenMetadata) {
                return addresses.includes(tokenMetadata.address);
              }).map(function (tokenMetadata) {
                return _extends({}, tokenMetadata, {
                  description: getLocalizedString({
                    obj: tokenMetadata,
                    property: "description",
                    locale: _this.ctx.locale,
                    fallback: "Token description missing"
                  })
                });
              }));

            case 6:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function tokens(_x) {
      return _tokens.apply(this, arguments);
    }

    return tokens;
  }();

  _proto.token = /*#__PURE__*/function () {
    var _token = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(address) {
      var response, returnedValue;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.prev = 0;
              _context2.next = 3;
              return fetch(META_URL + "/tokens/" + this.chainId + "/" + address);

            case 3:
              response = _context2.sent;

              if (response.ok) {
                _context2.next = 6;
                break;
              }

              throw new SdkError("Failed to fetch token with address \"" + address + "\". HTTP error: " + response.status);

            case 6:
              _context2.next = 8;
              return response.json();

            case 8:
              returnedValue = _context2.sent;
              returnedValue.description = getLocalizedString({
                obj: returnedValue,
                property: "description",
                locale: this.ctx.locale,
                fallback: "Token description missing"
              });
              return _context2.abrupt("return", returnedValue);

            case 13:
              _context2.prev = 13;
              _context2.t0 = _context2["catch"](0);
              console.error(_context2.t0);

            case 16:
              return _context2.abrupt("return", null);

            case 17:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this, [[0, 13]]);
    }));

    function token(_x2) {
      return _token.apply(this, arguments);
    }

    return token;
  }();

  _proto.strategies = /*#__PURE__*/function () {
    var _strategies = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3() {
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              return _context3.abrupt("return", fetch(META_URL + "/strategies/" + this.chainId + "/all").then(function (res) {
                return res.json();
              }));

            case 1:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function strategies() {
      return _strategies.apply(this, arguments);
    }

    return strategies;
  }();

  _proto.vaults = /*#__PURE__*/function () {
    var _vaults = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4(addresses) {
      var vaultsMetadata;
      return runtime_1.wrap(function _callee4$(_context4) {
        while (1) {
          switch (_context4.prev = _context4.next) {
            case 0:
              _context4.next = 2;
              return fetch(META_URL + "/vaults/" + this.chainId + "/all").then(function (res) {
                return res.json();
              });

            case 2:
              vaultsMetadata = _context4.sent;

              if (addresses) {
                _context4.next = 5;
                break;
              }

              return _context4.abrupt("return", vaultsMetadata);

            case 5:
              return _context4.abrupt("return", vaultsMetadata.filter(function (vaultMetadata) {
                return addresses.includes(vaultMetadata.address);
              }));

            case 6:
            case "end":
              return _context4.stop();
          }
        }
      }, _callee4, this);
    }));

    function vaults(_x3) {
      return _vaults.apply(this, arguments);
    }

    return vaults;
  }();

  _proto.vault = /*#__PURE__*/function () {
    var _vault = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee5(address) {
      var response;
      return runtime_1.wrap(function _callee5$(_context5) {
        while (1) {
          switch (_context5.prev = _context5.next) {
            case 0:
              _context5.prev = 0;
              _context5.next = 3;
              return fetch(META_URL + "/vaults/" + this.chainId + "/" + address);

            case 3:
              response = _context5.sent;

              if (response.ok) {
                _context5.next = 6;
                break;
              }

              throw new SdkError("Failed to fetch token with address \"" + address + "\". HTTP error: " + response.status);

            case 6:
              return _context5.abrupt("return", response.json());

            case 9:
              _context5.prev = 9;
              _context5.t0 = _context5["catch"](0);
              console.error(_context5.t0);

            case 12:
              return _context5.abrupt("return", null);

            case 13:
            case "end":
              return _context5.stop();
          }
        }
      }, _callee5, this, [[0, 9]]);
    }));

    function vault(_x4) {
      return _vault.apply(this, arguments);
    }

    return vault;
  }();

  return MetaService;
}(Service);

var YVECRV$1 = "0xc5bDdf9843308380375a611c18B50Fb9341f502A";
var PSLPYVBOOSTETH$1 = "0xCeD67a187b923F0E5ebcc77C7f2F7da20099e378";
/**
 * [[PartnerService]] provides access to yearns partner contract.
 * It's implemented in the form of a contract that lives on all networks
 * supported by yearn.
 */

var PartnerService = /*#__PURE__*/function (_ContractService) {
  _inheritsLoose(PartnerService, _ContractService);

  function PartnerService(chainId, ctx, addressProvider, partnerId) {
    var _this;

    _this = _ContractService.call(this, chainId, ctx, addressProvider) || this;
    _this.partnerId = partnerId;
    return _this;
  }

  var _proto = PartnerService.prototype;

  _proto.isAllowed = function isAllowed(vault) {
    return !PartnerService.IGNORED_ADDRESSES.includes(vault);
  };

  _proto.deposit = /*#__PURE__*/function () {
    var _deposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(vault, amount, overrides) {
      var contract;
      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.contract;

            case 2:
              contract = _context.sent;
              return _context.abrupt("return", contract.write.deposit(vault, this.partnerId, amount, overrides));

            case 4:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function deposit(_x, _x2, _x3) {
      return _deposit.apply(this, arguments);
    }

    return deposit;
  }();

  _proto.populateDepositTransaction = /*#__PURE__*/function () {
    var _populateDepositTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(vault, amount, overrides) {
      var contract;
      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              _context2.next = 2;
              return this.contract;

            case 2:
              contract = _context2.sent;
              return _context2.abrupt("return", contract.write.populateTransaction.deposit(vault, this.partnerId, amount, overrides));

            case 4:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function populateDepositTransaction(_x4, _x5, _x6) {
      return _populateDepositTransaction.apply(this, arguments);
    }

    return populateDepositTransaction;
  }();

  _proto.encodeDeposit = /*#__PURE__*/function () {
    var _encodeDeposit = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee3(vault, amount) {
      var contract;
      return runtime_1.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              _context3.next = 2;
              return this.contract;

            case 2:
              contract = _context3.sent;
              return _context3.abrupt("return", contract.write["interface"].encodeFunctionData("deposit", [vault, this.partnerId, amount]));

            case 4:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3, this);
    }));

    function encodeDeposit(_x7, _x8) {
      return _encodeDeposit.apply(this, arguments);
    }

    return encodeDeposit;
  }();

  _createClass(PartnerService, [{
    key: "contract",
    get: function get() {
      return this._getContract(PartnerService.abi, PartnerService.contractId, this.ctx);
    }
  }, {
    key: "address",
    get: function get() {
      var _this2 = this;

      return _asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee4() {
        var partnerAddress;
        return runtime_1.wrap(function _callee4$(_context4) {
          while (1) {
            switch (_context4.prev = _context4.next) {
              case 0:
                _context4.next = 2;
                return _this2.addressProvider.addressById(PartnerService.contractId);

              case 2:
                partnerAddress = _context4.sent;
                return _context4.abrupt("return", partnerAddress !== ZeroAddress ? partnerAddress : undefined);

              case 4:
              case "end":
                return _context4.stop();
            }
          }
        }, _callee4);
      }))();
    }
  }]);

  return PartnerService;
}(ContractService);
PartnerService.abi = ["function deposit(address vault, address partnerId, uint256 amount) external returns (uint256)"];
PartnerService.IGNORED_ADDRESSES = [YVECRV$1, PSLPYVBOOSTETH$1];
PartnerService.contractId = ContractAddressId.partner;

var TransactionService = /*#__PURE__*/function (_Service) {
  _inheritsLoose(TransactionService, _Service);

  function TransactionService(chainId, ctx, allowListService) {
    var _this;

    _this = _Service.call(this, chainId, ctx) || this;
    _this.allowListService = allowListService;
    return _this;
  }

  var _proto = TransactionService.prototype;

  _proto.sendTransaction = /*#__PURE__*/function () {
    var _sendTransaction = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee(transaction) {
      var _yield$this$validateT, success, error, signer;

      return runtime_1.wrap(function _callee$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              _context.next = 2;
              return this.validateTx(transaction);

            case 2:
              _yield$this$validateT = _context.sent;
              success = _yield$this$validateT.success;
              error = _yield$this$validateT.error;

              if (success) {
                _context.next = 7;
                break;
              }

              throw new SdkError(error || "transaction is not valid");

            case 7:
              signer = this.ctx.provider.write.getSigner();
              return _context.abrupt("return", signer.sendTransaction(transaction));

            case 9:
            case "end":
              return _context.stop();
          }
        }
      }, _callee, this);
    }));

    function sendTransaction(_x) {
      return _sendTransaction.apply(this, arguments);
    }

    return sendTransaction;
  }();

  _proto.validateTx = /*#__PURE__*/function () {
    var _validateTx = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/runtime_1.mark(function _callee2(transaction) {
      var _yield$Promise$all, to, data;

      return runtime_1.wrap(function _callee2$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              if (this.allowListService) {
                _context2.next = 2;
                break;
              }

              return _context2.abrupt("return", Promise.resolve({
                success: true,
                error: undefined
              }));

            case 2:
              _context2.next = 4;
              return Promise.all([transaction.to, transaction.data]);

            case 4:
              _yield$Promise$all = _context2.sent;
              to = _yield$Promise$all[0];
              data = _yield$Promise$all[1];
              _context2.next = 9;
              return this.allowListService.validateCalldata(to, data);

            case 9:
              return _context2.abrupt("return", _context2.sent);

            case 10:
            case "end":
              return _context2.stop();
          }
        }
      }, _callee2, this);
    }));

    function validateTx(_x2) {
      return _validateTx.apply(this, arguments);
    }

    return validateTx;
  }();

  return TransactionService;
}(Service);

/**
 * [[Yearn]] is a wrapper for all the services and interfaces of the SDK.
 *
 * Yearn namespace can be instantiated as a class or with an asynchronous
 * initializer, providing configuration options that will then be used by all
 * the services and interfaces:
 *
 * ```typescript
 * import { Yearn } from "@yfi/sdk";
 *
 * const provider = new JsonRpcProvider("http://localhost:8545");
 * const yearn = new Yearn(1, { provider });
 * ```
 */

var Yearn = /*#__PURE__*/function () {
  /**
   * Create a new SDK instance.
   * @param chainId
   * @param context plain object containing all the optional configuration
   * @param assetServiceState the asset service does some expensive computation at initialization, passing the state from a previous sdk instance can prevent this
   */
  function Yearn(chainId, context, assetServiceState) {
    this._ctxValue = context;
    this.context = new Context(context);
    this.addressProvider = new AddressProvider(chainId, this.context);
    var allowListService = new AllowListService(chainId, this.context, this.addressProvider);
    this.services = this._initServices(chainId, this.context, this.addressProvider, allowListService, assetServiceState);
    this.adapters = this._initAdapters(chainId);
    this.vaults = new VaultInterface(this, chainId, this.context);
    this.tokens = new TokenInterface(this, chainId, this.context);
    this.earnings = new EarningsInterface(this, chainId, this.context);
    this.fees = new FeesInterface(this, chainId, this.context);
    this.ironBank = new IronBankInterface(this, chainId, this.context);
    this.simulation = new SimulationInterface(this, chainId, this.context);
    this.strategies = new StrategyInterface(this, chainId, this.context);
    this.ready = Promise.all([this.services.asset.ready]);
  }

  var _proto = Yearn.prototype;

  _proto.setChainId = function setChainId(chainId) {
    this.addressProvider = new AddressProvider(chainId, this.context);
    var allowListService = new AllowListService(chainId, this.context, this.addressProvider);
    this.services = this._initServices(chainId, this.context, this.addressProvider, allowListService);
    this.adapters = this._initAdapters(chainId);
    this.vaults = new VaultInterface(this, chainId, this.context);
    this.tokens = new TokenInterface(this, chainId, this.context);
    this.earnings = new EarningsInterface(this, chainId, this.context);
    this.fees = new FeesInterface(this, chainId, this.context);
    this.ironBank = new IronBankInterface(this, chainId, this.context);
    this.simulation = new SimulationInterface(this, chainId, this.context);
    this.strategies = new StrategyInterface(this, chainId, this.context);
    this.ready = Promise.all([this.services.asset.ready]);
  };

  _proto._initServices = function _initServices(chainId, ctx, addressProvider, allowlistService, assetServiceState) {
    return {
      lens: new LensService(chainId, ctx, addressProvider),
      oracle: new OracleService(chainId, ctx, addressProvider),
      zapper: new ZapperService(chainId, ctx),
      asset: new AssetService(chainId, ctx, assetServiceState),
      vision: new VisionService(chainId, ctx),
      subgraph: new SubgraphService(chainId, ctx),
      pickle: new PickleService(chainId, ctx),
      helper: new HelperService(chainId, ctx, addressProvider),
      telegram: new TelegramService(chainId, ctx),
      meta: new MetaService(chainId, ctx),
      allowList: allowlistService,
      transaction: new TransactionService(chainId, ctx, allowlistService),
      partner: ctx.partnerId ? new PartnerService(chainId, ctx, addressProvider, ctx.partnerId) : undefined
    };
  };

  _proto._initAdapters = function _initAdapters(chainId) {
    return {
      vaults: {
        v2: new RegistryV2Adapter(chainId, this.context, this.addressProvider)
      },
      ironBank: new IronBankAdapter(chainId, this.context, this.addressProvider)
    };
  };

  return Yearn;
}();

exports.AssetService = AssetService;
exports.Context = Context;
exports.CustomError = CustomError;
exports.EarningsInterface = EarningsInterface;
exports.EthersError = EthersError;
exports.FeesInterface = FeesInterface;
exports.IronBankAdapter = IronBankAdapter;
exports.IronBankInterface = IronBankInterface;
exports.LensService = LensService;
exports.OracleService = OracleService;
exports.PriceFetchingError = PriceFetchingError;
exports.RegistryV2Adapter = RegistryV2Adapter;
exports.SdkError = SdkError;
exports.SimulationError = SimulationError;
exports.SimulationInterface = SimulationInterface;
exports.StrategyInterface = StrategyInterface;
exports.SubgraphService = SubgraphService;
exports.TelegramService = TelegramService;
exports.TenderlyError = TenderlyError;
exports.TokenInterface = TokenInterface;
exports.VaultInterface = VaultInterface;
exports.VisionService = VisionService;
exports.Yearn = Yearn;
exports.ZapperError = ZapperError;
exports.ZapperService = ZapperService;
exports.getZapInDetails = getZapInDetails;
exports.getZapOutDetails = getZapOutDetails;
//# sourceMappingURL=sdk.cjs.development.js.map