0.0.1 • Published 1 year ago

@overnight-contracts/blp-rebalancer v0.0.1

Weekly downloads
-
License
-
Repository
-
Last release
1 year ago

RebalancerAave

Взят по адресу: https://etherscan.io/address/0x1ed9c8bd3dccb85f704a5287444b552f9d5e1a26#code

Используется для примера построения своего ребалансера.

RebalancerPlus

Осуществляет ребалансировку основного токена в линейном (LinearPool) пуле по аналогии с RebalancerAave. В пуле планируется работать с парой USDC-USD+, где USDC будет основным (mainToken), а USD+ врапированным статик токеном StaticUsdPlus (wrapped). UsdPlus и StaticUsdPlus конвертируются через deposit/redeem на контракте StaticUsdPlus.

Для получения flash займов используется пул UniswapV3 USDC-USDT:

UniswapV3 pool USDC-USDT на polygonscan: https://polygonscan.com//address/0x3f5228d0e7d75467366be7de2c31d0d098ba2c23

Balancer Vault на polygonscan: https://polygonscan.com/address/0xba12222222228d8ba445958a75a0704d566bf2c8

Принцип работы

Параметрами вызова метода rebalance являются:

  • id балансируемого пула с Balancer
  • желаемый объем основного токена, к которому надо привести текущее значение
  • флаг использования flash займов

Если желаемый объем не указан, то вместо него будет использовано ближайшая граница коридора допустимого значения основного токена.

Если не указано использовать флеш займ, то будет произведена попытка произвести своп с использованием средств вызвавшего контракт пользователя, поэтому необходимо будет разрешить (approve) движение средств, на необходимый объем для соответствующего токена. Объем для аппрува необходимо будет узнать через вызов approveAmountRequirement.

Основного токена меньше желаемого объема

Для случая когда основного токена меньше желаемого объема, то необходимо сделать обмен (swap) на этом пуле основного токена на врапировнный (USDC -> USD+). При этом указываемый для обмена объем соответствует объему основного токена и нет необходимости в доп расчетах.

Для определения объема займа дополнительно ничего делать не нужно, т.к. займ будет в USDC и объем для свопа и займа совпадают.

Основного токена больше желаемого объема

В обратном случае необходимо произвести обмен врапированного токена на основной (USD+ -> USDC). На волте можно указать для операции свопа, что мы знаем объем выводимого токена, поэтому для формирования запроса больше ничего не требуется.

Но для подсчета объема для займа необходимо получить необходимый объем врапированного токена, который надо будет передать во время обмена в пул. Этот объем вычисляется так же, как это будет происходить внутри пула в момент обмена, поэтому из линейного пула берется функция из линейного пула (getWrappedInForMainOut).
Дальше этот объем врапированного токена для обмена пересчитывается в объем USDC, который потребуется для займа - для этого используется staticToDynamicAmount функция из врапированного токена (StaticUsdPlus)

Flash

Для движения средств в обоих случаях требуется обернуть какое-то количество USDC, которые берутся из пула юнисвопа USDC-USDT по механизму flash-loans. Для этого на предыдущем этапе был подсчитан объем USDC, который будет взят в займы. Принцип работы флешей подразумевает, что контракт должен реализовать функцию-колбек (uniswapV3FlashCallback), которую вызовет пул после перечисления средств на контракт ребалансера. По окончанию работы этой функции на адрес пула (он вызывает, msg.sender) необходимо перечислить взятые ранее взаймы средства и доплатить процент. Процент определяется на пуле и соответствует проценту при свопах.

Запрос на флеш должен содержать в себе объем займа и данные, которые будут переданы в функцию колбека.

uniswapV3FlashCallback

На момент вызова этой функции текущий контракт получает заказанный объем основного токена (USDC) и далее производит следующие действия:

  • проверка, что вызов был из нужного пула, а не стороннего пользователя или контракта
  • проверка, что действительно был получен займ
  • выполнение обмена (вызов doSwap)
  • оценка необходимости в доп ликвидности и запрос ее
  • передача средств займа с процентами в пул

Дополнительная ликвидность может потребоваться для оплаты процентов, например из-за некорректно указанных комиссий. В таком случае будет произведена попытка запросить у вызвавшего метод rebalance необходимого для покрытия объема USDC. В случае невозможности произойдет откат.

Если после обмена останется прибыль в виде неизрасходованных USDC,

doSwap

Осуществляет сами обмены.

USD+ -> USDC

Если осуществляется обмен USD+ -> USDC для увеличения объема USDC, то перед обменом производится перевод заемных средств (USDC) в StaticUsdPlus в два этапа: 1. На Exchange через метод buy обмениваются Usdc на UsdPlus 2. Полученные UsdPlus переводятся в StaticUsdPlus в StaticUsdPlus.deposit

После чего осуществляется обмен (swap) на волте балансера. Комиссия 0.04% на эксчендже на buy, которая будет компенсирована на пейауте, можно считать, что эти выплаты пойду уже на пул, но при вычислениях это образует нехватку.

USDC -> USD+

Если осуществляется обмен USDC -> USD+ для уменьшения объема USDC, то сначала производится обмен на волте. После обмена полученные StaticUsdPlus токены обмениваются на USDC в два этапа: 1. StaticUsdPlus переводятся в UsdPlus в StaticUsdPlus.redeem 2. Полученные UsdPlus на Exchange через метод redeem обмениваются на Usdc

Комиссия 0.04% на эксчендже на redeem, невозвратные.

estimateDeficitRequirement

При работе с флеш займом возможна ситуация, когда недостаточно средств для выплаты комиссии, поэтому данный метод дает оценку дефицита, который должен быть покрыт вызывающим ребансировку. Вызывающий должен иметь необходимый объем основного токена и выдать разрешение (approve) на перевод от имени контракта этого объема.

approveAmountRequirement

Высчитывает объем основного токена, который будет запрошен у вызывающего ребалансировку, если не будет использоваться флеш займ. На этот объем необходимо выдать approve на контракт ребалансера.

Запуск тестов в IDEA

Для запуска тестов mocha из-под IDEA необходимо указать в Node options:

-r ts-node/register

И в Environment variables:

TS_NODE_FILES=true