Контракты на GMX Synthetics.
В этом разделе представлен общий обзор того, как работает система.
Технический обзор см. в разделе ниже.
Рынки поддерживают как спотовую, так и индивидуальную торговлю. Они создаются путем указания длинного токена обеспечения, короткого токена обеспечения и индексного токена.
Примеры:
Поставщики ликвидности могут депонировать либо длинный, либо короткий залоговый токен, либо оба, для выпуска токенов ликвидности.
Длинный токен обеспечения используется для поддержки длинных позиций, а короткий токен обеспечения используется для поддержки коротких позиций.
Поставщики ликвидности берут на себя прибыли и убытки трейдеров на рынке, для которого они предоставляют ликвидность.
Наличие отдельных рынков позволяет изолировать риски, поставщики ликвидности имеют доступ только к рынкам, на которых они вносят депозиты, что потенциально допускает несанкционированный листинг.
Трейдеры могут использовать длинные или короткие токены в качестве обеспечения рынка.
Контракты поддерживают следующие основные функции:
Чтобы избежать проблем с опережением, большинство действий требуют выполнения двух шагов:
Цены предоставляются автономной системой оракула, которая постоянно подписывает цены в зависимости от времени запроса цен.
Подписывается как минимальная, так и максимальная цена, что позволяет включать информацию о спредах спроса и предложения.
Цены, хранящиеся в контракте Oracle, представляют собой цену одной единицы токена с точностью до 30 десятичных знаков.
Представление цен таким образом позволяет упростить преобразование между суммами токенов и бумажными значениями, например, для расчета бумажной стоимости заданного количества токенов расчет будет просто: количество токена * цена оракула, чтобы вычислить количество токенов для Фиатная стоимость это будет: фиатная стоимость / цена оракула.
Комиссия за финансирование и влияние на цену поддерживают баланс между длинными и короткими позициями, одновременно снижая риск манипулирования ценами.
В системе есть несколько хранителей и узлов:
Существует несколько основных типов договоров:
Контракты разделены на эти типы, чтобы обеспечить возможность постепенного обновления.
Большая часть данных хранится с использованием контракта DataStore.
Контракты *storeUtils хранят данные структуры с помощью DataStore, что позволяет добавлять в структуры новые ключи.
EnumberableSets используются для того, чтобы интерфейсы или хранители могли легко запрашивать списки заказов и списки позиций. Это используется для индексаторов, поскольку индексаторы могут иметь задержку при синхронизации последнего блока. Хранение списков непосредственно в контракте также помогает гарантировать возможность получения и проверки точных данных при необходимости.
Контракты *eventUtils излучают события с использованием генератора событий. События обобщаются, что позволяет добавлять к событиям новые пары «ключ-значение», не требуя обновления ABI.
Сокращение от GMX Liquidity Vault: оболочка нескольких рынков с одинаковыми длинными и короткими токенами. Ликвидность автоматически перебалансируется между базовыми рынками в зависимости от их использования.
В этом разделе представлено техническое описание контрактов.
Рынки создаются с помощью MarketFactory.createMarket
, при этом создается MarketToken и сохраняется структура Market.Props в MarketStore.
MarketToken используется для отслеживания доли поставщиков ликвидности в рыночном пуле и для хранения токенов для каждого рынка.
В любой момент времени цена MarketToken равна (worth of market pool) / MarketToken.totalSupply()
, для получения этого значения можно использовать функцию MarketUtils.getMarketTokenPrice
.
Стоимость рыночного пула равна сумме
Депозиты добавляют длинные/короткие токены в рыночный пул и отправляют вкладчику MarketTokens.
Запросы на депозиты создаются путем вызова ExchangeRouter.createDeposit с указанием:
Запросы на депозит выполняются с использованием DepositHandler.executeDeposit. Если депозит был создан в момент времени n
, он должен быть выполнен с ценами оракула после временной метки n
.
Количество выпущенных MarketToken без учета комиссий и влияния на цену рассчитывается как (worth of tokens deposited) / (worth of market pool) * MarketToken.totalSupply()
.
При снятии средств маркеры MarketToken сжигаются в обмен на длинные/короткие токены рыночного пула.
Запросы на вывод средств создаются путем вызова ExchangeRouter.createWithdrawal с указанием:
Запросы на вывод средств выполняются с помощью WithdrawalHandler.executeWithdrawal. Если вывод был создан в момент времени n
, он должен быть выполнен с ценами оракула после отметки времени n
.
Сумма длинных или коротких токенов, подлежащих погашению, без учета комиссий и влияния на цену, рассчитывается как (worth of market tokens) / (long / short token price)
.
Длинные и короткие токены рынка можно обменивать друг на друга.
Например, если на рынке ETH/USD есть WETH в качестве длинного токена и USDC в качестве короткого токена, WETH можно отправить на рынок для обмена на USDC, а USDC можно отправить на рынок для обмена на WETH.
Запросы своп-ордеров создаются путем вызова ExchangeRouter.createOrder с указанием:
Сумма вывода свопа без учета комиссий и влияния на цену (amount of tokens in) * (token in price) / (token out price)
.
Запросы ордеров на рыночный своп выполняются с использованием OrderHandler.executeOrder. Если ордер был создан во временную метку n
, он должен быть выполнен с ценами оракула после временной метки n
.
Пассивные своп-ордера, которые должны выполняться, когда сумма вывода соответствует минимальной сумме вывода, указанной пользователем.
Запросы лимитных своп-ордеров выполняются с использованием OrderHandler.executeOrder. Если ордер был создан во временную метку n
, он должен быть выполнен с ценами оракула после временной метки n
.
Откройте или увеличьте длинную/короткую позицию.
Запросы ордеров на увеличение рынка создаются путем вызова ExchangeRouter.createOrder с указанием:
Запросы ордеров на увеличение рынка выполняются с использованием OrderHandler.executeOrder. Если ордер был создан во временную метку n
, он должен быть выполнен с ценами оракула после временной метки n
.
Пассивные ордера на увеличение позиции, которые должны выполняться, когда цена индексного токена соответствует приемлемой цене, указанной пользователем.
Пример длинной позиции: если текущая цена индексного токена составляет 5000 долларов США, можно создать ордер на увеличение лимита с приемлемой ценой в 4990 долларов США, ордер может быть исполнен, когда цена индексного токена <= 4990 долларов США.
Пример короткой позиции: если текущая цена индексного токена составляет 5000 долларов США, ордер на увеличение лимита может быть создан с приемлемой ценой в 5010 долларов США, ордер может быть исполнен, когда цена индексного токена >= 5010 долларов США.
Запросы ордеров на увеличение лимита выполняются с помощью OrderHandler.executeOrder. Если ордер был создан в момент времени n
, он должен быть исполнен с ценами оракула после временной метки n
.
Закройте или уменьшите длинную/короткую позицию.
Запросы ордеров на снижение рынка создаются путем вызова ExchangeRouter.createOrder с указанием:
Запросы ордеров на понижение рынка выполняются с помощью OrderHandler.executeOrder. Если ордер был создан в момент времени n
, он должен быть выполнен с ценами оракула после временной метки n
.
Ордера на пассивное уменьшение позиции, которые должны выполняться, когда цена индексного токена соответствует приемлемой цене, указанной пользователем.
Пример длинной позиции: если текущая цена индексного токена составляет 5000 долларов США, можно создать ордер на уменьшение лимита с приемлемой ценой в 5010 долларов США, ордер может быть исполнен, когда цена индексного токена >= 5010 долларов США.
Пример короткой позиции: если текущая цена индексного токена составляет 5000 долларов США, можно создать ордер на уменьшение лимита с приемлемой ценой в 4990 долларов США, ордер может быть исполнен, когда цена индексного токена <= 4990 долларов США.
Запросы ордеров на уменьшение лимита выполняются с помощью OrderHandler.executeOrder. Если ордер был создан во временную метку n
, он должен быть исполнен с ценами оракула после временной метки n
.
Ордера на пассивное уменьшение позиции, которые должны выполняться, когда цена индексного токена пересекает приемлемую цену, указанную пользователем.
Пример длинной позиции: если текущая цена индексного токена составляет 5000 долларов США, можно создать ордер на уменьшение стоп-лосса с приемлемой ценой в 4990 долларов США, ордер можно исполнить, когда цена индексного токена составит <= 4990 долларов США.
Пример короткой позиции: если текущая цена индексного токена составляет 5000 долларов США, можно создать ордер на уменьшение стоп-лосса с приемлемой ценой в 5010 долларов США, ордер может быть исполнен, когда цена индексного токена >= 5010 долларов США.
Запросы ордеров на уменьшение стоп-лосса выполняются с помощью OrderHandler.executeOrder. Если ордер был создан в момент времени n
, он должен быть исполнен с ценами оракула после временной метки n
.
Цена ETH составляет 5000, а ETH имеет 18 знаков после запятой.
Цена одной единицы ETH составляет 5000 / (10 ^ 18), 5 * (10 ^ -15)
.
Чтобы обработать десятичные дроби, умножьте значение на (10 ^ 30)
.
Цена будет храниться как 5000 / (10 ^ 18) * (10 ^ 30) => 5000 * (10 ^ 12)
.
Для оптимизации газа эти цены отправляются оракулу в виде значения десятичного множителя uint8 и значения цены uint32.
Если значение десятичного множителя установлено равным 8, значение uint32 будет 5000 * (10 ^ 12) / (10 ^ 8) => 5000 * (10 ^ 4)
.
С этой конфигурацией цены ETH могут иметь максимальное значение (2 ^ 32) / (10 ^ 4) => 4,294,967,296 / (10 ^ 4) => 429,496.7296
с точностью до 4 десятичных знаков.
Цена BTC составляет 60 000, а BTC имеет 8 знаков после запятой.
Цена одной единицы BTC равна 60,000 / (10 ^ 8), 6 * (10 ^ -4)
.
Цена будет храниться как 60,000 / (10 ^ 8) * (10 ^ 30) => 6 * (10 ^ 26) => 60,000 * (10 ^ 22)
.
Максимальное значение цены BTC: (2 ^ 64) / (10 ^ 2) => 4,294,967,296 / (10 ^ 2) => 42,949,672.96
.
Десятичные знаки точности: 2.
Цена USDC равна 1, а USDC имеет 6 десятичных знаков.
Цена одной единицы USDC равна 1 / (10 ^ 6), 1 * (10 ^ -6)
.
Цена будет храниться как 1 / (10 ^ 6) * (10 ^ 30) => 1 * (10 ^ 24)
.
Максимальное значение цены USDC: (2 ^ 64) / (10 ^ 6) => 4,294,967,296 / (10 ^ 6) => 4294.967296
.
Десятичные знаки точности: 6.
Цена DG равна 0,00000001, а DG имеет 18 десятичных знаков.
Цена одной единицы ДГ равна 0.00000001 / (10 ^ 18), 1 * (10 ^ -26)
.
Цена будет храниться как 1 * (10 ^ -26) * (10 ^ 30) => 1 * (10 ^ 3)
.
Максимальное значение цены DG: (2 ^ 64) / (10 ^ 11) => 4,294,967,296 / (10 ^ 11) => 0.04294967296
.
Десятичные знаки точности: 11.
Формула для расчета значения десятичного множителя:
Десятичные знаки: 30 – (десятичные знаки) – (количество десятичных знаков, требуемое для точности)
Пример расчета WNT:
dataStreamPrice / (10 ^ 8) / (10 ^ 18) * (10 ^ 30)
(5000 * (10 ^ 8)) / (10 ^ 8) / (10 ^ 18) * (10 ^ 30) = 5000 * (10 ^ 12)
dataStreamPrice * multiplier / (10 ^ 30)
(5000 * (10 ^ 8)) * (10 ^ 34) / (10 ^ 30) = 5000 * (10 ^ 12)
Пример расчета для WBTC:
dataStreamPrice / (10 ^ 8) / (10 ^ 8) * (10 ^ 30)
(50,000 * (10 ^ 8)) / (10 ^ 8) / (10 ^ 8) * (10 ^ 30) = 50,000 * (10 ^ 22)
dataStreamPrice * multiplier / (10 ^ 30)
(50,000 * (10 ^ 8)) * (10 ^ 44) / (10 ^ 30) = 50,000 * (10 ^ 22)
Формула множителя: 10 ^ (60 - dataStreamDecimals - tokenDecimals)
Комиссия за финансирование стимулирует балансировку длинных и коротких позиций: сторона с большим открытым интересом платит комиссию за финансирование стороне с меньшим открытым интересом.
Плата за финансирование для большей стороны рассчитывается как (funding factor per second) * (open interest imbalance) ^ (funding exponent factor) / (total open interest)
.
Например, если коэффициент финансирования в секунду равен 1/50 000, а коэффициент экспоненты финансирования равен 1, открытый интерес по длинной позиции составляет 150 000 долларов США, а открытый интерес по короткой позиции составляет 50 000 долларов США, то плата за финансирование в секунду для длинных позиций будет равна (1 / 50,000) * 100,000 / 200,000 => 0.00001 => 0.001%
.
Плата за финансирование в секунду для коротких позиций составит -0.00001 * 150,000 / 50,000 => 0.00003 => -0.003%
.
Также можно установить значениеfundingIncreaseFactorPerSecond, это приведет к следующей логике финансирования:
longShortImbalance
рассчитывается как [abs(longOpenInterest - shortOpenInterest) / totalOpenInterest] ^ fundingExponentFactor
longShortImbalance
больше thresholdForStableFunding
, то ставка финансирования увеличится на longShortImbalance * fundingIncreaseFactorPerSecond
longShortImbalance
больше порога thresholdForDecreaseFunding
и меньше порога thresholdForStableFunding
и перекос находится в том же направлении, что и финансирование, то ставка финансирования не изменится.longShortImbalance
меньше thresholdForDecreaseFunding
и перекос находится в том же направлении, что и финансирование, то ставка финансирования уменьшится на fundingDecreaseFactorPerSecond
Поскольку longShortImbalance > пороговое значениеForStableFunding, saveFundingFactorPerSecond должно увеличиться на 0.0001% * 6% * 600 = 0.0036%
Поскольку длинные позиции уже оплачивают короткие позиции, перекос тот же, и longShortImbalance < порогForStableFunding, saveFundingFactorPerSecond не должен меняться.
Поскольку longShortImbalance < пороговое значениеForDecreaseFunding, saveFundingFactorPerSecond должно уменьшиться на 0.000002% * 600 = 0.0012%
Поскольку перекос в другом направлении, saveFundingFactorPerSecond должен уменьшиться на 0.0001% * 1% * 600 = 0.0006%
Обратите внимание, что существуют возможные способы обмана комиссии за финансирование, поэтому факторы финансирования должны быть скорректированы, чтобы свести к минимуму эту возможность:
Если longOpenInterest > shortOpenInterest и longShortImbalance находятся в пределах порога ForStableFunding, пользователь, занимающий короткую позицию, может открыть длинную позицию, чтобы увеличить longShortImbalance и попытаться вызвать увеличение комиссии за финансирование. На активном рынке должно быть трудно предсказать, когда противоположная короткая позиция будет открыта кем-то другим, чтобы заработать повышенную комиссию за финансирование, что должно затруднить эту игру. Факторы финансирования также могут быть скорректированы, чтобы помочь минимизировать выгоду от этой игры. .
Если longOpenInterest > shortOpenInterest и longShortImbalance > пороговое значениеForStableFunding, трейдер, удерживающий длинную позицию, может совершить несколько мелких сделок в течение этого времени, чтобы гарантировать, что фактор финансирования постоянно обновляется вместо того, чтобы использовать большее значение в течение всего периода времени, это должно свести к минимуму комиссию за финансирование для длинных позиций, но не должна снижать комиссию за финансирование ниже ожидаемых ставок.
Поставщикам ликвидности выплачивается комиссия за заимствование, что помогает пользователям не открывать как длинные, так и короткие позиции для использования емкости пула без уплаты каких-либо комиссий.
Плата за заимствование может использовать кривую модель или модель излома.
Чтобы использовать кривую модель, ключами для настройки будут BORROWING_FACTOR
и BORROWING_EXPONENT_FACTOR
, коэффициент заимствования в секунду будет рассчитываться как:
// reservedUsd is the total USD value reserved for positions
reservedUsd = MarketUtils.getReservedUsd(...)
// poolUsd is the USD value of the pool excluding pending trader PnL
poolUsd = MarketUtils.getPoolUsdWithoutPnl(...)
// reservedUsdAfterExponent is the reservedUsd after applying the borrowingExponentFactor for the market
reservedUsdAfterExponent = applyExponentFactor(reservedUsd, borrowingExponentFactor)
borrowingFactorPerSecond = borrowingFactor * reservedUsdAfterExponent / poolUsd
Чтобы использовать модель излома, ключами для настройки будут OPTIMAL_USAGE_FACTOR
, BASE_BORROWING_FACTOR
и ABOVE_OPTIMAL_USAGE_BORROWING_FACTOR
, коэффициент заимствования в секунду будет рассчитываться как:
// usageFactor is the ratio of value reserved for positions to available value that can be reserved
usageFactor = MarketUtils.getUsageFactor(...)
borrowingFactorPerSecond = baseBorrowingFactor * usageFactor
if (usageFactor > optimalUsageFactor) {
diff = usageFactor - optimalUsageFactor
additionalBorrowingFactorPerSecond = aboveOptimalUsageBorrowingFactor - baseBorrowingFactor
borrowingFactorPerSecond += additionalBorrowingFactorPerSecond * diff / (Precision.FLOAT_PRECISION - optimalUsageFactor)
}
Существует также возможность установить флаг SkipBorrowingFeeForSmallerSide, это приведет к тому, что комиссия за заимствование для меньшей стороны будет установлена на ноль. Например, если длинных позиций больше, чем коротких, и параметр SkipBorrowingFeeForSmallerSide имеет значение true, то комиссия за заимствование для коротких позиций будет равна нулю.
Код влияния на цену можно найти в контрактах /pricing
.
Влияние на цену рассчитывается как:
(initial USD difference) ^ (price impact exponent) * (price impact factor) - (next USD difference) ^ (price impact exponent) * (price impact factor)
Для свопов дисбаланс рассчитывается как разница в стоимости длинных и коротких токенов.
Например:
price impact exponent
установлена на 2, а price impact factor
— на 0.01 / 50,000
0 ^ 2 * (0.01 / 50,000) - 50,000 ^ 2 * (0.01 / 50,000) => -$500
50,000 ^ 2 * (0.01 / 50,000) - 25,000 ^ 2 * (0.01 / 50,000) => $375
Для позиционных действий (увеличение/уменьшение позиции) дисбаланс рассчитывается как разница в длинном и коротком открытом интересе.
price impact exponents
и price impact factors
настраиваются для каждого рынка и могут различаться для спотовых и позиционных действий.
Обратите внимание, что этот расчет отражает влияние цены на сделку пользователя, а не на цену пула. Например, сделка пользователя может иметь влияние на цену 0,25%, следующая сделка на очень небольшую сумму может иметь влияние на цену 0,5%.
Целью ценового воздействия является:
Поскольку в контрактах используется цена оракула, которая будет средней или медианной ценой нескольких ссылочных бирж. Без влияния на цену может быть выгодно манипулировать ценами на справочных биржах при исполнении заказов по контрактам.
Этот риск также будет присутствовать, если значения положительного и отрицательного воздействия на цену аналогичны, поэтому положительное влияние на цену должно быть установлено на низкое значение во времена волатильности или нерегулярных движений цен.
Что касается влияния цены на позицию, увеличивается/уменьшается, если отрицательное влияние цены вычитается в качестве обеспечения из позиции, это может привести к тому, что позиция будет иметь кредитное плечо, отличное от того, которое предполагал пользователь, поэтому вместо вычета обеспечения цена входа/выхода позиции будет равна скорректировано с учетом влияния на цену.
Например:
Если индексный токен отличается как от длинного, так и от короткого токена рынка, то возможно, что на стоимость пула существенно повлияет пул влияния позиции, если пул влияния позиции очень велик, а индексный токен имеет большую цену. увеличивать. Если это станет проблемой, может быть добавлена возможность постепенного уменьшения размера пула влияния позиции.
Влияние на цену также отслеживается с использованием стоимости виртуальных запасов для позиций и свопов. Это отслеживает дисбаланс токенов на аналогичных рынках, например ETH/USDC, ETH/USDT.
В случае большого движения цены возможно, что большое количество позиций будет уменьшено или ликвидировано с одной стороны, что приведет к значительному дисбалансу между длинными и короткими открытыми интересами, что может привести к очень высоким значениям воздействия на цену. Чтобы смягчить это, можно настроить максимальное значение импакт-фактора позиции. Если текущее влияние на цену превышает максимальное отрицательное влияние на цену, то любое избыточное обеспечение, вычтенное сверх максимального отрицательного влияния на цену, будет удерживаться в рамках контракта. Если не было обнаружено манипуляций с ценами, это обеспечение может быть передано пользователю. Когда отрицательное влияние на цену ограничено, может быть выгодно открывать и немедленно закрывать позиции, поскольку положительное влияние на цену теперь может быть больше, чем ограниченное отрицательное влияние на цену. Чтобы избежать этого, максимальное положительное влияние на цену должно быть настроено так, чтобы оно было ниже максимального отрицательного влияния на цену.
Существуют настраиваемые комиссии за своп и комиссию за позицию в зависимости от рынка.
Комиссия за исполнение также оценивается и учитывается при создании депозита, вывода средств и запросов ордеров, чтобы хранители могли выполнять транзакции с чистой нулевой стоимостью, близкой к чистой.
Если на рынке есть стейблкоины в качестве короткого залогового токена, он должен иметь возможность полностью выплачивать короткую прибыль, если максимальный открытый интерес к коротким позициям не превышает количество стейблкоинов в пуле.
Если на рынке есть длинный залоговый токен, который отличается от индексного токена, длинные прибыли могут быть не выплачены полностью, если рост цены индексного токена превышает рост цены длинного залогового токена.
Рынки имеют резервный фактор, который позволяет ограничить открытый интерес процентом от размера пула. Это снижает влияние прибыли коротких позиций и снижает риск того, что длинные позиции не могут быть полностью погашены.
Цена рыночного токена зависит от стоимости активов в пуле и чистого ожидающего PnL открытых позиций трейдеров.
Ожидаемый PnL может быть ограничен, факторы, используемые для расчета рыночной цены токена, могут различаться в зависимости от активности:
Keys.MAX_PNL_FACTOR_FOR_DEPOSITS: это факторный предел PnL при расчете рыночной цены токена для депозитов.
Keys.MAX_PNL_FACTOR_FOR_WITHDRAWALS: это ограничение фактора PnL при расчете рыночной цены токена для вывода средств.
Keys.MAX_PNL_FACTOR_FOR_TRADERS: это ограничение фактора PnL при расчете рыночной цены токена для закрытия позиции.
Эти различные факторы можно настроить, чтобы помочь поставщикам ликвидности управлять рисками и стимулировать депозиты, когда это необходимо. к более низкой рыночной цене токена для депозитов по сравнению со снятием средств, что может стимулировать депозиты, когда ожидающий PnL высок.
minCollateFactor: определяет минимально допустимое соотношение (обеспечение позиции) / (размер позиции).
maxPoolAmount: максимальное количество токенов, которое можно разместить на рынке.
maxOpenInterest: Максимальный открытый интерес, который может быть открыт для рынка.
ReserveFactor: определяет максимально допустимое соотношение (стоимость токенов, зарезервированных для позиций) / (токены в пуле)
maxPnlFactor: максимальное соотношение (PnL / стоимость токенов в пуле)
PositionFeeFactor: определяет процентную сумму комиссий, которая будет вычтена за действия по увеличению/уменьшению позиции. Сумма комиссии зависит от изменения размера позиции.
PositionImpactFactor: это «фактор влияния на цену» для позиций, описанных в разделе «Влияние на цену».
maxPositionImpactFactor: это «максимальное влияние на цену» для позиций, описанных в разделе «Влияние на цену».
PositionImpactExComponentFactor: это значение «экспоненты влияния на цену» для действий позиции, описанных в разделе «Влияние на цену».
swapFeeFactor: определяет процентную сумму комиссий, вычитаемых за свопы. Размер комиссии зависит от суммы свопа.
swapImpactFactor: это «фактор влияния на цену», описанный в разделе «Влияние на цену».
swapImpactExComponentFactor: это значение «показателя влияния на цену» для депозитов и свопов, описанное в разделе «Влияние на цену» выше.
fundFactor: это значение «коэффициента финансирования в секунду», описанное в разделе «Комиссия за финансирование».
заимствованиеFactorForLongs: это «коэффициент заимствования» для длинных позиций, описанный в разделе «Комиссия за заимствование».
заимствованиеFactorForShorts: это «коэффициент заимствования» для коротких позиций, описанный в разделе «Комиссия за заимствование».
заимствованиеЭкспонентФакторФорЛонгс: это «коэффициент экспоненты заимствования» для длинных позиций, описанный в разделе «Комиссия за заимствование».
заимствованиеЭкспонентФакторФорШортс: это «коэффициент экспоненты заимствования» для длинных позиций, описанный в разделе «Комиссия за заимствование».
Роли управляются в RoleStore, администратор ролей имеет доступ для предоставления и отзыва любой роли.
Изначально RoleAdmin будет развертывателем, но его следует удалить после настройки ролей.
После первоначальной настройки:
Только контракт Timelock должен иметь роль RoleAdmin.
Новые роли могут быть предоставлены администраторами временной блокировки с задержкой по времени.
Системные значения следует устанавливать только с помощью контракта Config.
Ни один EOA не должен иметь роль контролера.
Хранители конфигураций и администраторы временной блокировки потенциально могут нарушить регулярную работу из-за отключения функций, неправильной установки значений, внесения в белый список вредоносных токенов, злоупотребления положительным значением влияния на цену и т. д.
Ожидается, что мультиподпись временной блокировки должна отзывать разрешения вредоносных или скомпрометированных учетных записей.
Хранители ордеров и хранители замороженных ордеров потенциально могут извлечь выгоду за счет упорядочивания транзакций, отложенного выполнения транзакций, выполнения ADL и т. д. Это будет частично смягчено с помощью сети хранителей.
Ожидается, что подписанты Oracle будут точно сообщать цену токенов.
Залоговые токены должны быть внесены в белый список с настроенным TOKEN_TRANSFER_GAS_LIMIT.
Перебазирование токенов, токены, которые меняют баланс при переводе, с сжиганием токенов, токены с обратными вызовами, например токены ERC-777 и т. д., несовместимы с системой и не должны быть внесены в белый список.
Держатели ордеров могут использовать цены из разных временных меток для лимитных ордеров со свопом, что приведет к разным объемам вывода.
Ожидается, что хранители заказов проверят, будет ли транзакция отменена, прежде чем отправлять транзакцию, чтобы минимизировать потери газа.
Хранители заказов могут вызывать отмену запросов вместо их выполнения, выполняя запрос с недостаточным количеством газа.
Если транзакция выполнения требует большого количества газа, близкого к максимальному пределу газа в блоке, можно заполнить блоки, чтобы транзакция не была включена в блоки.
В некоторых блокчейнах хранитель может контролировать цену tx.gasprice, используемую для выполнения транзакции, что повлияет на комиссию за исполнение, выплачиваемую хранителю.
Злоумышленник может помешать исполнению ордеров, намеренно вызывая дисбаланс рынка, что приведет к сильному влиянию на цену; это должно быть дорогостоящим и трудно получить от этого выгоду.
Влияние на цену можно уменьшить за счет использования позиций и свопов, а также торговли между рынками, цепочками, форками и другими протоколами. Это частично смягчается с помощью виртуального отслеживания запасов.
Пользователь может снизить влияние на цену, используя позиции с высоким кредитным плечом, это частично смягчается значением MIN_COLLATERAL_FACTOR_FOR_OPEN_INTEREST_MULTIPLIER.
Расчет значений воздействия на цену не учитывает сборы и последствия, возникающие в результате самого воздействия на цену, для большинства случаев влияние на расчет воздействия на цену должно быть небольшим
Это редко, но для того, чтобы ценность пула стала отрицательной, это может произойти, поскольку ImpactPoolMound и ожидающий PNL вычитаются из ценности токенов в бассейне
Из -за разницы в положительном и негативном воздействии цен на позицию может быть нарастание виртуальных токенов в пуле воздействия, что может повлиять на ценообразование токенов рынка, пул воздействия должно быть постепенно распределен, если это
Виртуальный инвентарь отслеживает количество токенов в бассейнах, должно быть обеспечено, что токены в каждой группировке будут одинаковыми и имеют одинаковые десятичные десятики, то есть длинные токены между бассейнами в группе должны иметь одинаковые десятичные десятичные. В группе должны быть те же десятичные десятичные знаки, предполагая, что USDC имеет 6 десятиков, а у DAI есть 18 десятичных десятиц, такие рынки, как Eth-USDC, Eth-Dai не должно быть сгруппировано
Виртуальные идентификаторы должны быть установлены до создания рынка / токенового белого списки
Для L2 с секвенсорами не существует проверки контракта, чтобы проверить, активен ли секвенсор L2, Oracle Keepers прекратить подписывать цены, если блоки не создаются секвенсором, если секвенсер возобновит регулярную работу, хранители Oracle должны подписывать цены на цены на Последние блоки с использованием последних полученных цен
В случае снижения секвенсора L2, он может предотвратить отложения в положения для предотвращения ликвидации
Для транзакций, которые могут быть выполнены полностью с использованием каналов цен на цепь, может быть возможно воспользоваться несвежими ценообразой из-за задержки цены или снижения цепочки, использование каналов цены должно быть временными, и должны быть каналы с низкой задержкой. используется вместо этого, как только все токены поддерживаются
Блок Reorgs может позволить пользователю задним числом отменять заказ после его выполнения, если цена не перемещается благоприятно для пользователя, необходимо соблюдать осторожность для обработки этого случая при использовании контрактов на цепях, где возможны длинные переосмысления
Обновление и отмена заказов может быть передовым, чтобы предотвратить выполнение порядка, это не должно быть проблемой, если вероятность успешного фронта меньше или равна 50%, если вероятность превышает 50%, сборы и Воздействие на цену должно быть скорректировано, чтобы гарантировать, что стратегия не является чистой прибыльной, корректировка платы за пользовательский интерфейс или скидка на реферал можно также использовать для выздоровления отмены заказа
В случае простоя блокчейна или Oracle, заказы могут быть выполнены по значительно другим ценам или не могут выполняться, если приемлемая цена заказа не может быть выполнена
Существует зависимость от точности блокировки временной метки, поскольку цены оракула подтверждены от этого значения, для блокчейнов, где узлы блокчейна имеют некоторый контроль над временной меткой, необходимо соблюдать осторожно временная метка убыточно
Функция сдвига GLV может быть использована путем временного увеличения использования на рынке, который обычно имеет низкое использование. Как только хранитель выполняет сдвиг, злоумышленник может снизить использование обратно до своих нормальных уровней. Плата за позицию и воздействие на цену должны быть настроены таким образом, чтобы сделать эту атаку достаточно дорогой, чтобы покрыть потерю GLV.
В GLV могут быть GM -рынки, которые выше их максимального pnltopoolfactortraders. Если MaxPnlFactorfordEposits этого GM рынка выше, чем MaxPnlFactorTraders, то рынок GM оценивается ниже во время депозитов, чем когда -то трейдеры реализуют свою ограниченную прибыль. Злоусовеченный пользователь может наблюдать за рынком GM в таком состоянии и депозит в GLV, содержащий его, чтобы получить от ADL, которые скоро будут следовать. Чтобы избежать этого maxpnlfactorfordeposits, должно быть меньше или равно maxpnlfactortraders.
Технически для рыночной стоимости становится негативной. В этом случае GLV будет непригодным для использования до тех пор, пока рыночная стоимость не станет положительной.
Токены GM могут стать неликвидными из -за высокого коэффициента PNL или высокого зарезервированного доллара США. Пользователи могут вносить неликвидные токены GM в GVL и извлекать ликвидность с другого рынка, оставляя GLV с неликвидными токенами. Параметры Glvmaxmarketketkenbalanceusd и Glvmaxmarketketkenbalanceamount должны учитывать рискованность рынка, чтобы избежать слишком большого количества токенов GM с рискованного рынка.
scripts/verifyFallback.ts
можно использовать для проверки контрактовnpx hardhat verify
, после этого все контракты на рынке должны быть проверены, поскольку исходный код будет одинаковым Если добавлены новые контракты, которые могут привести к разнице в ценах, например, токенах рынка между старыми и новыми контрактами, то необходимо соблюдать осторожность, чтобы отключить старые контракты до включения новых контрактов
Любые внешние протоколы, которые используют договор считывателя или потенциально устаревшие расчеты для цены, следует напомнить, чтобы использовать последние контракты и расчеты, например, ленты цен на цепь
Рекомендуется опубликовать наилучшие усилия ChangeLog, документирующие важные изменения, о которых следует знать интеграции, например, если поле добавляется в структуру, которая передается в функцию обратного вызова, это изменение может быть не очевидным для интеграций
Если контракты используются для поддержки синтетических рынков акционерного капитала, необходимо соблюдать осторожно
Контракты с роли «контроллера» имеют доступ к важным функциям, таким как настройка значений хранилища данных, из -за этого необходимо обеспечить осторожность, чтобы убедиться, что такие контракты не имеют общих функций или функций, которые можно использовать для изменения важных значений
Тесты должны быть добавлены для различных типов рынка, например, на рынках, рынках одиночных токенов.
Заказ значений в EventData для обратных вызовов не должно быть изменено, если это строго необходимо, поскольку контракты на вызов могут ссылаться на значения с помощью фиксированного индекса
Обратите внимание, что если структура, которая передается в обратные вызовы, изменяется, например, депозит, снятие средств, порядок строк, это приведет к тому, что функции контрактов обратного вызовов ожидают, что предыдущая структура прекратит работу, из -за этого, изменения в структурах должны быть выделены на интеграции
Если используется реферальная система, orderhandler должен быть предоставлен доступ для обновления реферального кода для трейдеров
Депозиты, снятие средств и заказы могут быть отменены, если требования, указанные в запросе, не могут быть выполнены, например, сумма. Проверьте, где будут отправлены средства и возмещение газа при отмене, чтобы убедиться, что они соответствуют ожиданиям.
Уменьшение порядка положения может вывести два токена вместо одного токена, в случае сбоя свопа с уменьшением позиции, также возможно, что выходная сумма и залога могут быть недостаточно для покрытия платежей, что приведет к выполнению заказа
Если есть большой спред, возможно, что открытие / закрытие позиции может значительно изменить минимальную и максимальную цену токена рынка, это не должно быть манипуляционным
Изменения в значениях конфигурации, таких как funding_factor, stable_funding_factor, bourning_factor, skip_borwing_fee_for_smaller_side, bourning_fee_receiver_factor, могут привести к дополнительным сбору для пользователей, это также может привести к изменению цены рынка Tokens
Если трейдер PNL ограничен из-за max_pnl_factor_for_traders, процент прибыли, выплачиваемой трейдерам, может отличаться в зависимости от упорядочения, когда позиции уменьшаются / закрыты, поскольку ограничение перечисляется на основе текущего состояния пула
Данные о события могут быть переданы в контракты обратного вызова, упорядочение параметров в EventData будет предпринята попытка быть неизменным, поэтому параметра может быть доступен по индексу, для безопасности. Ключ параметра все еще должен быть подтвержден перед использованием, чтобы проверить, соответствует ли он соответствующим ожидаемое значение
Некоторые параметры, такие как order.siedelta и order.initialcollateraldeltaamount, могут быть обновлены во время выполнения, обновленные значения не могут быть переданы в контракт на вызов
При создании договора обратного вызова, договору обратного вызова может потребоваться белоснуть в белом списке депонизировки, заказывания или скидки Временно существует в то же время, например, OrderHandler (1), OrderHandler (2), Из -за этого, договор обратного вызовов должен быть в состоянии белого списка и одновременно принимать обратные вызовы от множества Депонируемые, заказывающие и снявшись
Для контрактов обратного вызовов вместо того, чтобы поддерживать отдельный белый список для депонирующих, заказов, снятых мандерлеров, возможным решением было бы подтвердить роль MSG.Sender в Rolestore, например, RoleStore.hasRole(msg.sender, Role.CONTROLLER)
, это было бы Убедитесь, что msg.sender является действительным обработчиком
При использовании контрактов, таких как обменник, Oracle или Reader. Обратите внимание, что их адреса изменятся при добавлении новой логики
Если такие контракты, как обменник, Oracle или Reader, обновляются, необходимо приложить усилия, чтобы сохранить параметры функции одинаковыми, однако это не всегда возможно, например, если следует поддерживать новое свойство заказа, то Обменник. должен быть изменен
Rolestore и Datastore для развертываний не должны меняться, если они изменяются
Хотя кодекс был структурирован для минимизации риска повторной работы только для чтения, необходимо соблюдать осторожность, чтобы защитить эту возможность
Токеновые воздушные кадры могут возникнуть на счетах держателей токенов GM, интеграция контрактов, содержащих токены GM, должны быть в состоянии претендовать на эти токены, в противном случае токены будут заблокированы, точная реализация для этого будет варьироваться в зависимости от контракта на интегрирование, одна из возможностей заключается в токенов, которые не являются токенами рынка, это можно проверить с помощью значения Keys.MARKET_LIST
Передаты ETH отправляются с Native_token_transfer_gas_limit для лимита газа, если передача не удастся из -за недостаточного газа или других ошибок, ETH отправляется как Weth вместо этого
Учетные записи могут получить ETH для ADL / ликвидации, если учетная запись не может получить ETH, то Weth будет отправлено вместо этого
Положительное воздействие на цену ограничено количеством токенов в пулах ударов и на основе настроенных значений
Негативное воздействие в цену может быть ограничено настроенными значениями
Если негативное воздействие на цену ограничено, дополнительная сумма будет храниться в претензии по обеспечению, это необходимо вручную заявить об использовании обменения. Клаймколлатеральная функция
Позитивные платы за финансирование должны быть заявлены вручную с использованием функции Craisgerouter.claimfundingFees
Партнерские вознаграждения должны быть заявлены вручную с использованием функции обменника.
Рынки или функции могут быть отключены
Исполнение все равно будет продолжаться, даже если обратный вызов вернется
Убедиться, что обратные вызовы имеют достаточное газ
Subaccounts может создавать, обновлять и отменить любой заказ на учетную запись
Subaccounts может тратить Wnt и залог с учетной записи
Пользовательские сборы могут быть изменены
Реферальные скидки могут быть изменены
Средства для адресов в черном списке будут храниться в рамках протокола
Индексный токен не всегда гарантированно будет длинным токеном
Ставки на платы изменяются в зависимости от того, есть ли положительное или отрицательное влияние
Рассмотрим фактор PNL при оценке цены GM
Обрабатывать отмену депозита
Убедитесь, что только обработчики с роли контроллера могут вызвать функции обратного вызовов после следов и послепозитоцитуальной обратной связи
Убедитесь, что только правильное выполнение депозита может вызвать функции обратного вызова
Рассмотрим рынки с тем же длинным и коротким токеном, свопы не поддерживаются для этих рынков
Рассмотрим положительное и отрицательное воздействие цены
Существует период отмены запроса для настроенной задержки, когда запросы на депозит не могут быть отменены
Выходные суммы подвержены воздействию цен и сборов
Депозиты не допускаются выше MAX_PNL_FACTOR_FOR_DEPOSITS
Первый депозит на любом рынке должен перейти к receiver_for_first_deposit
Два минимальных выхода должны использоваться для снятия средств
Обработка отмены отмены
Убедитесь, что только обработчики с роли контроллера могут вызвать функции обратного вызова после
Убедитесь, что только правильное выполнение снятия может вызвать функции обратного вызова
Рассмотрим рынки с тем же длинным и коротким токеном, свопы не поддерживаются для этих рынков
Рассмотрим положительное и отрицательное воздействие цены
Существует период отмены запроса для настроенной задержки, когда запросы на снятие средств не могут быть отменены
Выходные суммы подвержены воздействию цен и сборов
Снятие не допускается выше max_pnl_factor_for_withdrawals
Обрабатывать отмену заказа
Ликвидация и ADL могут вызвать сохраненный контракт на вызов
Заказы могут заморозить
Убедитесь, что только обработчики с роли контроллера могут вызвать послеоперационное обеспечение, послеподобия и функции обратного вызова после
Убедитесь, что только правильное выполнение заказа может вызвать функции обратного вызова
Рассмотрим рынки с тем же длинным и коротким токеном, свопы не поддерживаются для этих рынков
Рассмотрим положительное и отрицательное воздействие цены
Сохраненные контракты на вызов можно изменить
Существует период отмены запроса для настроенной задержки, когда запросы на заказ не могут быть отменены
Выходные суммы подвержены воздействию цен и сборов
Пул воздействия позиции распределен поставщикам ликвидности с течением времени
При попытке вычислять влияние на цену, виртуальные запасы следует проконсультироваться
Trader PNL ограничен выше max_pnl_factor_for_traders
Негативное воздействие на цену может быть ограничено на уменьшение положения
Уменьшение порядка SizeLta и ColaterAldelta будут автоматическими, если они больше, чем положение, может справиться с положением
Рассмотрим WillPositionCollateralBesureAl Validation
Рассмотрим снижение сжимания
Рассмотрим минимальную сумму залога
Рефералы все еще выплачиваются во время ликвидации
Позиции могут иметь нулевой залог
Позиции с нулевым размером не могут существовать
Для составления контрактов:
npx hardhat compile
Чтобы запустить все тесты:
npx hardhat test
export NODE_OPTIONS=--max_old_space_size=4096
может потребоваться для запуска тестов.
Для печати метрик кода:
npx ts-node metrics.ts
Для печати тестового покрытия:
npx hardhat coverage