GMX Synthetics との契約。
このセクションでは、システムの仕組みの概要を説明します。
技術的な概要については、以下のセクションを参照してください。
マーケットはスポット取引とパープ取引の両方をサポートしており、ロング担保トークン、ショート担保トークン、インデックス トークンを指定することによって作成されます。
例:
流動性プロバイダーは、流動性トークンを鋳造するために、ロング担保トークンまたはショート担保トークンのいずれか、あるいはその両方を預けることができます。
ロング担保トークンはロングポジションを裏付けるために使用され、ショート担保トークンはショートポジションを裏付けるために使用されます。
流動性プロバイダーは、流動性を提供する市場のトレーダーの利益と損失を引き受けます。
個別の市場を持つことでリスクの隔離が可能になり、流動性プロバイダーは入金先の市場にのみ公開されるため、許可のない上場が可能になる可能性があります。
トレーダーはロングトークンまたはショートトークンを市場の担保として使用できます。
契約は次の主な機能をサポートします。
進行中の問題を回避するには、ほとんどのアクションを実行するために次の 2 つの手順を実行する必要があります。
価格はオフチェーンのオラクル システムによって提供され、価格が照会された時間に基づいて継続的に価格に署名します。
最低価格と最高価格の両方が署名されるため、買値と売値のスプレッドに関する情報を含めることができます。
Oracle コントラクト内に保存されている価格は、小数点以下 30 桁の精度の値を使用してトークン 1 単位の価格を表します。
この方法で価格を表すと、トークンの量と法定価格の間の変換が簡素化されます。たとえば、特定の数のトークンの法定価格を計算する場合、計算は次のようになります: トークンの量 * オラクル価格、トークンの量を計算する場合法定価格は次のようになります: 法定価格 / オラクル価格。
資金調達手数料と価格への影響により、価格操作のリスクを軽減しながらロングとショートのバランスが保たれます。
システムにはいくつかのキーパーとノードがあります。
契約には主に次のような種類があります。
契約はこれらのタイプに分割されており、段階的なアップグレードが可能です。
データの大部分は、DataStore コントラクトを使用して保存されます。
*storeUtils コントラクトは、DataStore を使用して構造体データを保存します。これにより、新しいキーを構造体に追加できます。
EnumberableSet は、インターフェイスまたはキーパーによって順序リストと位置リストを簡単にクエリできるようにするために使用されます。これは、インデクサーが最新のブロックを同期するまでにラグが生じる可能性があるため、インデクサーよりも使用されます。リストをコントラクトに直接保存すると、必要なときに正確なデータを取得して検証できるようになります。
*eventUtils コントラクトは、イベント エミッターを使用してイベントを発行します。イベントは一般化されており、ABI の更新を必要とせずに新しいキーと値をイベントに追加できるようになります。
GMX Liquidity Vault の略: 同じロングおよびショート トークンを持つ複数の市場のラッパー。流動性は、市場の利用状況に基づいて、原市場間で自動的にリバランスされます。
このセクションでは、契約の技術的な説明を提供します。
マーケットはMarketFactory.createMarket
を使用して作成されます。これにより、MarketToken が作成され、Market.Props 構造体が MarketStore に保存されます。
MarketToken は、市場プールにおける流動性プロバイダーのシェアを追跡し、各市場のトークンを保管するために使用されます。
任意の時点で、MarketToken の価格は(worth of market pool) / MarketToken.totalSupply()
あり、関数MarketUtils.getMarketTokenPrice
を使用してこの値を取得できます。
市場プールの価値は次の合計です。
入金により、ロング/ショート トークンが市場のプールに追加され、MarketToken が入金者に発行されます。
デポジットのリクエストは、以下を指定して 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 1 単位の価格は5000 / (10 ^ 18), 5 * (10 ^ -15)
です。
小数を処理するには、値に(10 ^ 30)
を掛けます。
価格は5000 / (10 ^ 18) * (10 ^ 30) => 5000 * (10 ^ 12)
として保存されます。
ガスの最適化のために、これらの価格は uint8 10 進数の乗数値と uint32 価格値の形式でオラクルに送信されます。
10 進数の乗数値が 8 に設定されている場合、uint32 値は5000 * (10 ^ 12) / (10 ^ 8) => 5000 * (10 ^ 4)
になります。
この設定では、ETH 価格は小数点以下 4 桁の精度で(2 ^ 32) / (10 ^ 4) => 4,294,967,296 / (10 ^ 4) => 429,496.7296
の最大値を持つことができます。
BTC の価格は 60,000 で、BTC には小数点以下 8 桁があります。
BTC の 1 単位の価格は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 単位の価格は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 桁があります。
DG の 1 単位の価格は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。
10 進数の乗数値を計算する式は次のとおりです。
小数点: 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 秒あたりの資金調達係数が 1/50,000、資金調達指数係数が 1、ロング建玉が 150,000 ドル、ショート建玉が 50,000 ドルの場合、ロングの 1 秒あたりの資金調達手数料は(1 / 50,000) * 100,000 / 200,000 => 0.00001 => 0.001%
なります。 (1 / 50,000) * 100,000 / 200,000 => 0.00001 => 0.001%
。
ショートの 1 秒あたりの資金調達手数料は-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 > ThresholdForStableFunding であるため、savedFundingFactorPerSecond は0.0001% * 6% * 600 = 0.0036%
増加する必要があります。
ロングがすでにショートに支払っているため、スキューは同じであり、longShortImbalance <thresholdForStableFunding、savedFundingFactorPerSecond は変化しないはずです。
longShortImbalance <thresholdForDecreaseFunding であるため、savedFundingFactorPerSecond は0.000002% * 600 = 0.0012%
減少するはずです。
スキューが反対方向にあるため、savedFundingFactorPerSecond は0.0001% * 1% * 600 = 0.0006%
減少するはずです。
資金調達手数料を騙す方法が考えられるため、この可能性を最小限に抑えるために資金調達係数を調整する必要があることに注意してください。
longOpenInterest > shortOpenInterest かつlongShortImbalanceがthresholdForStableFunding以内の場合、ショートポジションを保有しているユーザーはロングポジションをオープンしてlongShortImbalanceを増加させ、ファンディング手数料を増加させようとする可能性があります。活発な市場では、増額された資金調達手数料を得るために、いつ他の人が反対側のショートポジションをオープンするかを予測するのは難しいはずです。これにより、このゲームが困難になります。また、このゲームの利益を最小限に抑えるために資金調達要素を調整することもできます。 。
longOpenInterest > shortOpenInterest および longShortImbalance >thresholdForStableFunding の場合、ロング ポジションを保持しているトレーダーは、期間全体でより大きな値が使用されるのではなく、ファンディング ファクターが継続的に更新されることを保証するために、この期間中に複数の小さな取引を行うことができます。これにより、ロングポジションの資金調達手数料は、予想レートを下回ってはいけません。
流動性プロバイダーに支払われる借入手数料があり、これにより、ユーザーが手数料を支払わずにプール容量を占有するためにロングポジションとショートポジションの両方をオープンするのを防ぐことができます。
借入手数料には、カーブ モデルまたはキンク モデルを使用できます。
曲線モデルを使用するには、構成するキーはBORROWING_FACTOR
およびBORROWING_EXPONENT_FACTOR
となり、1 秒あたりの借入係数は次のように計算されます。
// 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
となり、1 秒あたりの借用係数は次のように計算されます。
// 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 などの同様の市場にわたるトークンの不均衡が追跡されます。
大きな価格変動の場合、一方の側で大量のポジションが減少または清算され、長建建玉と短期建玉の間で大きな不均衡が生じる可能性があり、これにより価格への影響値が非常に高くなる可能性があります。これを軽減するために、最大位置影響係数値を設定できます。現在の価格への影響が最大マイナス価格影響を超えた場合、最大マイナス価格影響を超えて差し引かれた超過担保は契約内で保持され、価格操作が検出されなかった場合、この担保はユーザーに解放されます。マイナスの価格への影響が制限されている場合、プラスの価格への影響が制限付きのマイナスの価格への影響よりも大きい可能性があるため、ポジションをオープンしてすぐに決済することが有益である可能性があります。これを回避するには、最大のプラスの価格影響が最大のマイナスの価格影響を下回るように構成する必要があります。
設定可能なスワップ手数料とポジション手数料が市場ごとにあります。
執行手数料も、入金、出金、注文リクエストの作成時に見積もられて計上されるため、キーパーは純ゼロに近いコストで取引を実行できます。
市場がショート担保トークンとしてステーブルコインを持っている場合、最大ショート建玉がプール内のステーブルコインの量を超えなければ、ショート利益を全額支払うことができるはずです。
市場にインデックス トークンとは異なるロング担保トークンがある場合、インデックス トークンの価格上昇がロング担保トークンの価格上昇を超えると、ロング利益が完全に支払われない可能性があります。
市場には、建玉をプールサイズの一定割合に制限できる準備率があり、これによりショートポジションの利益の影響が軽減され、ロングポジションが全額支払われないリスクが軽減されます。
マーケットトークンの価格は、プール内の資産の価値と、トレーダーのオープンポジションの純損益によって異なります。
保留中の損益に上限が設定される可能性があり、市場トークン価格の計算に使用される要素はアクティビティに応じて異なる場合があります。
Keys.MAX_PNL_FACTOR_FOR_DEPOSITS: これは、預金の市場トークン価格を計算するときの損益係数の上限です。
Keys.MAX_PNL_FACTOR_FOR_WITHDRAWALS: これは、引き出しの市場トークン価格を計算するときの損益係数の上限です。
Keys.MAX_PNL_FACTOR_FOR_TRADERS: これは、ポジションを決済するための市場トークン価格を計算する際の損益係数の上限です。
これらのさまざまな要素は、流動性プロバイダーがリスクを管理し、必要に応じて入金を奨励するのに役立つように構成できます。たとえば、トレーダーの損益の上限は、トレーダーの損益によって市場トークン価格が減少する量を制限するのに役立ち、入出金の損益の上限は、出金と比較して預金の市場トークン価格が低くなり、保留中の損益が大きい場合に預金を奨励することができます。
minColternateFactor: (ポジション担保) / (ポジションサイズ) の最小許容比率を決定します。
maxPoolAmount: マーケットに入金できるトークンの最大量
maxOpenInterest: 市場に対してオープンできる最大建玉
reserveFactor: (ポジション用に予約されたトークンの価値) / (プール内のトークン) の最大許容比率を決定します。
maxPnlFactor: (PnL / プール内のトークンの価値) の最大比率
PositionFeeFactor: これは、ポジションの増加/減少アクションに対して差し引かれる手数料の割合を決定します。手数料の金額はポジションサイズの変化に基づきます。
PositionImpactFactor: これは、「価格影響」セクションで説明されているポジションの「価格影響係数」です。
maxPositionImpactFactor: これは、「価格への影響」セクションで説明されているポジションの「最大価格への影響」です。
PositionImpactExponentFactor: これは、「価格への影響」セクションで説明されている、ポジション アクションの「価格影響指数」値です。
swapFeeFactor: スワップに対して差し引かれる手数料の割合を決定します。手数料の金額はスワップの金額に基づきます。
swapImpactFactor: これは、「価格への影響」セクションで説明されている「価格影響係数」です。
swapImpactExponentFactor: これは、上記の「価格への影響」セクションで説明した、預金とスワップの「価格影響指数」の値です。
FundingFactor: これは、「資金調達手数料」セクションで説明されている「1 秒あたりの資金調達係数」の値です。
borringFactorForLongs: これは、「借入手数料」セクションで説明されているロングポジションの「借入係数」です。
boringFactorForShorts: これは、「借入手数料」セクションで説明されているショートポジションの「借入係数」です。
borringExponentFactorForLongs: これは、「借入手数料」セクションで説明されているロングポジションの「借入指数係数」です。
borringExponentFactorForShorts: これは、「借入手数料」セクションで説明されているロングポジションの「借入指数係数」です。
ロールはRoleStoreで管理され、RoleAdminは任意のロールを付与および取り消すためのアクセス権を持ちます。
最初は、RoleAdmin がデプロイヤになりますが、これはロールのセットアップ後に削除する必要があります。
初期設定後:
Timelock コントラクトのみが、RoleAdmin ロールを持つ必要があります。
タイムロック管理者は時間遅延を設けて新しいロールを付与できます
システム値は、Config コントラクトを使用してのみ設定する必要があります。
EOA にコントローラーの役割を持たせることはできません
構成管理者とタイムロック管理者は、機能の無効化、値の誤った設定、悪意のあるトークンのホワイトリストへの登録、プラスの価格影響値の悪用などにより、通常の運用を妨害する可能性があります。
タイムロック マルチシグは、悪意のあるアカウントまたは侵害されたアカウントのアクセス許可を取り消すことが期待されます。
オーダー キーパーと凍結されたオーダー キーパーは、トランザクションの順序付け、遅延したトランザクション実行、ADL 実行などを通じて価値を引き出す可能性があります。これはキーパー ネットワークによって部分的に軽減されます。
オラクルの署名者はトークンの価格を正確に報告することが期待されています
担保トークンは、TOKEN_TRANSFER_GAS_LIMIT を設定してホワイトリストに登録する必要があります
リベーストークン、転送時に残高を変更するトークン、トークンバーンを伴うトークン、コールバックを伴うトークン(ERC-777 トークンなど)は、システムと互換性がないため、ホワイトリストに登録すべきではありません。
オーダーキーパーは、スワップを伴う指値注文に異なるタイムスタンプの価格を使用できます。これにより、異なる出力金額が得られます。
注文管理者は、ガスの無駄を最小限に抑えるために、トランザクションを送信する前にトランザクションが元に戻るかどうかを検証することが期待されます。
オーダーキーパーは、ガスが不十分な状態でリクエストを実行することにより、リクエストが実行されずにキャンセルされる可能性があります。
実行トランザクションが最大ブロック ガス制限に近い大量のガスを必要とする場合、トランザクションがブロックに含まれないようにブロックを詰め込むことができる場合があります。
特定のブロックチェーンでは、キーパーがトランザクションの実行に使用される tx.gasprice を制御でき、キーパーに支払われる実行手数料に影響を与える可能性があります。
悪意のあるユーザーが意図的に市場のバランスを崩して注文の執行を妨げられる可能性があり、その結果、価格に大きな影響を与える可能性がありますが、これにはコストがかかり、恩恵を受けるのは困難です。
価格への影響は、ポジションとスワップを使用し、市場、チェーン、フォーク、その他のプロトコル間で取引することで軽減できます。これは仮想在庫追跡で部分的に軽減されます。
ユーザーは、高レバレッジのポジションを使用することで価格への影響を軽減できます。これは、MIN_COLLATERAL_FACTOR_FOR_OPEN_INTEREST_MULTIPLIER 値で部分的に軽減されます。
価格影響値の計算では、手数料や価格影響自体から生じる影響は考慮されていません。ほとんどの場合、価格影響計算への影響は小さいはずです。
まれですが、プールの値がネガティブになる可能性があります。これは、ImpactPoolamountと保留中のPNLがプール内のトークンの価値から差し引かれるために発生する可能性があります。
プラスとマイナスの位置価格の影響の違いにより、市場トークンの価格設定に影響を与えるポジションインパクトプールに仮想トークン量が増加する可能性があります。
仮想在庫はプールのトークンの量を追跡します。各グループのトークンが同じタイプで同じ小数であることを保証する必要があります。グループでは、USDCには6つの小数があり、Daiには18小数があると仮定して、Eth-USDCのような市場があると仮定して、同じ小数を持つ必要があります。 Eth-Daiをグループ化しないでください
仮想IDは、市場作成 /トークンホワイトリストの前に設定する必要があります。トークン /市場の取引が完了した後に設定されている場合、追跡は正確ではなく、調整する必要がある場合があります
シーケンサーを備えたL2Sの場合、L2シーケンサーがアクティブであるかどうかを確認する契約検証はありません。Sequencerがブロックが作成されていない場合、Sequencerが定期的な操作を再開する場合、Oracle KeepersがOracle Keepersが価格に署名する場合、Oracle Keepersは価格に署名を停止する必要があります。最新のフェッチング価格を使用した最新のブロック
L2シーケンサーがダウンしている場合、清算を防ぐために堆積物を維持しない可能性があります
オンチェーン価格フィードを完全に実行できるトランザクションの場合、価格の遅延やチェーンがダウンしているため、古い価格設定を利用することが可能な場合があります。代わりに、すべてのトークンがサポートされたら使用します
Block Reorgsは、ユーザーがユーザーにとって好意的に移動しなかった場合にユーザーが実行された後、注文を遡及的にキャンセルできるようにすることができます。長いReorgsが可能なチェーン上の契約を使用している場合は、このケースを処理するように注意する必要があります。
注文の更新とキャンセルは、注文の実行を防ぐために最前か実行される可能性があります。これは、成功したフロントランニングの確率が50%以下である場合、確率が50%を超え、料金と料金が高い場合、これは問題になりません。価格への影響は、戦略が純利益を上げないように調整する必要があります。UI料金または紹介割引の調整も同様に、注文のキャンセルを引き起こすために使用できます
ブロックチェーンまたはオラクルのダウンタイムの場合、注文は大幅に異なる価格で実行されるか、注文の許容価格が履行できない場合に実行できない場合があります
ブロックチェーンノードがタイムスタンプをある程度制御するブロックチェーンについては、オラクルの価格がこの値に対して検証されているため、ブロックタイムスタンプの精度に依存します。タイムスタンプは不採算
GLVシフト機能は、通常、使用率が低い市場での使用率を一時的に増やすことで活用できます。キーパーがシフトを実行すると、攻撃者は使用率を通常のレベルに引き下げることができます。ポジション料金と価格への影響は、GLVの損失をカバーするのに十分な高価になるように構成する必要があります。
GLVには、最大のpnltopoolfactorfortradersを超えるGM市場がある場合があります。このGM市場のmaxpnlfactorfordepositsがmaxpnlfactorfortradersよりも高い場合、預金中は、トレーダーが上限利益を実現したよりも低く評価されます。悪意のあるユーザーは、このような状態でGM市場を観察し、GLVを含むGLVに預け入れて、すぐに続くADLSから得ることができます。このmaxpnlfactorfordepositsを回避するには、maxpnlfactorfortradersと等しくなければなりません。
技術的には、市場価値がマイナスになる可能性があります。この場合、市場価値がプラスになるまでGLVは使用できません。
GMトークンは、PNL因子が高いか、予約されたUSDが高いため、非流動性になる可能性があります。ユーザーは、非流動性GMトークンをGVLに預け、異なる市場から流動性を撤回し、GLVに非流動性トークンを残すことができます。 glvmaxmarkettedokenbalanceusdおよびglvmaxmarkettedokenbalanceamountパラメーターは、リスクの高い市場からのGMトークンが多すぎないようにするための市場のリスクを説明する必要があります。
scripts/verifyFallback.ts
使用して契約を確認できますnpx hardhat verify
使用して1つのマーケットトークン契約を検証する必要があります。その後、ソースコードが同じであるため、すべてのマーケットトークン契約を検証する必要があります古い契約と新しい契約の間の市場トークンなどの価格設定の違いにつながる可能性のある新しい契約が追加された場合、新しい契約が有効になる前に古い契約を無効にするように注意する必要があります
読者契約または価格設定のために潜在的に時代遅れの計算を使用する外部プロトコルは、最新の契約と計算を使用するように思い出させる必要があります。
統合が認識すべき重要な変更を文書化する最善の努力を公開することをお勧めします。
契約が株式合成市場をサポートするために使用される場合、株式の分割や同様の変更を処理できるように注意する必要があります
「コントローラー」の役割との契約は、データストア値の設定などの重要な機能にアクセスできます。これにより、そのような契約には重要な値を変更するために使用できる汎用関数または機能がないことを確認するように注意する必要があります。
さまざまな市場タイプ、例:スポットのみの市場、単一のトークン市場についてテストを追加する必要があります
コールバック契約は固定インデックスで値を参照する可能性があるため、厳密に必要な場合を除き、コールバックのイベントDataの値の順序付けは変更されるべきではありません
コールバックに渡された構造体が変更された場合、預金、引き出し、順序構造体など、これにより、以前の構造体が動作を停止することを期待するコールバック契約の関数が原因であることに注意してください。
紹介システムが使用されている場合、オーダーハンドラーには、トレーダーの紹介コードを更新するためにアクセスできる必要があります
リクエストで指定された要件が満たされない場合、預金、引き出し、注文はキャンセルされる場合があります。資金とガスの払い戻しがキャンセルに送られる場所を確認して、それが期待に合っていることを確認してください。
ポジショニングオーダーの減少は、単一のトークンの代わりに2つのトークンを出力する可能性があります。ポジションスワップの減少が失敗した場合、出力量と担保が料金をカバーするのに十分ではない可能性があり、注文は実行されません。
大きなスプレッドがある場合、ポジションを開設 /閉じることで、マーケットトークンの最小価格と最大価格を大幅に変更できる可能性があります。
Funding_Factor、stable_funding_factor、borrowing_factor、skip_borrowing_fee_for_smaller_side、borrowing_fee_receiver_factorなどの構成値の変更は、ユーザーの追加料金につながる可能性があります。
トレーダーPNLがMAX_PNL_FACTOR_FOR_TRADERSのためにキャップされている場合、トレーダーに支払われる利益の割合は、プールの現在の状態に基づいてCAPが再計算されるため、ポジションが減少 /閉じられる場合の注文 /閉鎖の順序によって異なる場合があります
イベントデータはコールバック契約に渡される場合があります。イベントDataのパラメーションの順序は変更されないように試みます。そのため、パラメーションにはインデックスでアクセスできます。期待値
Order.SizedeltaやOrder.InitialCollarteraldeltaamountなどのいくつかのパラメーターは、実行中に更新される場合があります。
コールバック契約を作成する場合、コールバック契約はdeposithandler、Orderhandler、またはextreatalhandlerをホワイトリストに登録する必要がある場合があります。これらのハンドラーの新しいバージョンがハンドラーに追加されると展開される可能性があることに注意する必要があります。一時的に同時に存在します。たとえば、OrderHandler(1)、OrderHandler(2)、このため、コールバック契約は複数からのコールバックをホワイトリストに登録し、同時に受け入れることができるはずですDeposithandlers、OrderHandlers、および撤退ハンドラー
デポシタンドラー、オーダーハンドラー、引き出しハンドラーのRoleStore.hasRole(msg.sender, Role.CONTROLLER)
の個別のホワイトリストを維持する代わりにコールバック契約の場合、可能な解決策は、ロールストアのMSG.senderの役割を検証することです。 msg.senderが有効なハンドラーであることを確認してください
交換器、Oracle、または読者などの契約を使用する場合、新しいロジックが追加されるとアドレスが変更されることに注意してください
交換器、Oracle、または読者などの契約が更新されている場合、関数パラメーターを同じに保つ努力をする必要がありますが、これは常に可能であるとは限りません。変更する必要があります
展開用のロールストアとデータストアは変更されないはずです。以前の契約から新しい契約への資金の移行が変更された場合、おそらく必要になる可能性があります
コードは、読み取り専用の再発のリスクを最小限に抑えるために構成されていますが、この可能性を防ぐために注意する必要があります
トークンエアドロップはGMトークンホルダーのアカウントに発生する可能性があり、GMトークンを保持する契約の統合がこれらのトークンを請求することができなければなりません。そうしないと、トークンがロックされます。これの正確な実装は統合契約によって異なります。マーケットトークンではないトークンの場合、これはKeys.MARKET_LIST
値を使用してチェックできます
ETH転送は、ガス制限のためにnative_token_transfer_gas_limitを使用して送信されます。ガスやその他のエラーが不十分であるため転送が故障した場合、ETHは代わりにwethとして送信されます
アカウントはADL /清算のETHを受け取る場合があります。アカウントがETHを受け取ることができない場合、代わりにWETHが送信されます
プラスの価格の影響は、衝撃プールのトークンの量によってキャップされ、構成された値に基づいています
負の価格の影響は、構成された値によってキャップされる場合があります
マイナスの価格の影響がキャップされている場合、追加の金額は請求可能な担保プールに保持されます。
exchangerouter.claimfundingfees関数を使用して手動で請求する必要があります
Affiliateの報酬は、curchangerouter.claimaffiliaterewards関数を使用して手動で請求する必要があります
市場または機能が無効になる場合があります
コールバックが戻っていても、実行は引き続き継続されます
コールバックに十分なガスがあることを確認してください
サブアカウントは、アカウントの任意の注文を作成、更新、キャンセルできます
サブアカウントは、アカウントからWntと担保を費やすことができます
UI料金を変更できます
紹介割引を変更できます
ブラックリストに登録された住所の資金は、プロトコル内に保持されます
インデックストークンは常に長いトークンであることが保証されているとは限りません
プラスの影響があるか悪影響があるかに応じて、料金金利は変化します
GM価格を推定するときは、PNL因子を検討してください
デポジットキャンセルを処理します
コントローラーの役割を持つハンドラーのみが、afterdepositexecutionおよびafterdepositcancellationコールバック関数を呼び出すことができることを確認してください
正しいデポジットの実行のみがコールバック関数を呼び出すことができることを確認してください
同じ長いトークンと短いトークンを持つ市場を考慮して、これらの市場ではスワップがサポートされていません
プラスとマイナスの価格への影響を検討してください
デポジットリクエストをキャンセルできない場合、構成された遅延の要求キャンセル期間があります
出力額は、価格の影響と料金の対象となります
堆積物はMAX_PNL_FACTOR_FOR_DEPOSITSの上に許可されていません
あらゆる市場での最初のデポジットは、receiver_for_first_depositに送信する必要があります
撤退には2つの最小出力を使用する必要があります
引き出しキャンセルを処理します
コントローラーの役割を持つハンドラーのみが、afthdrawalexecutionおよびafthddrawalcellationコールバック関数を呼び出すことができることを確認してください
正しい引き出し実行のみがコールバック関数を呼び出すことができることを確認します
同じ長いトークンと短いトークンを持つ市場を考慮して、これらの市場ではスワップがサポートされていません
プラスとマイナスの価格への影響を検討してください
引き出しリクエストをキャンセルできない構成された遅延の要求キャンセル期間があります
出力額は、価格の影響と料金の対象となります
MAX_PNL_FACTOR_FOR_WITHDRAWALSよりも引き出しは許可されていません
注文キャンセルを処理します
清算とADLは、保存されたコールバック契約をトリガーできます
注文は凍結される可能性があります
コントローラーの役割を持つハンドラーのみが、OrderCancellationおよびAfter OrderFrozenコールバック関数を呼び出すことができることを確認してください
正しい注文実行のみがコールバック関数を呼び出すことができることを確認します
同じ長いトークンと短いトークンを持つ市場を考慮して、これらの市場ではスワップがサポートされていません
プラスとマイナスの価格への影響を検討してください
保存されたコールバック契約は変更できます
注文要求がキャンセルできない構成された遅延の要求キャンセル期間があります
出力額は、価格の影響と料金の対象となります
ポジションインパクトプールは、時間の経過とともに流動性プロバイダーに配布されます
価格の影響を計算しようとする場合、仮想在庫に相談する必要があります
トレーダーPNLは、max_pnl_factor_for_tradersの上にキャップされています
マイナスの価格への影響は、位置の減少に上限している可能性があります
注文sizedeltaを減少させ、副次的なものは、位置が処理できるよりも大きい場合に自動更新されます
willpositionCollateralBeSufficive Validationを検討してください
DecraseSpositionSwapTypesを検討してください
最小担保額を考慮してください
紹介はまだ清算中に支払われます
ポジションが担保をゼロにする可能性があります
サイズがゼロの位置は存在できません
契約を編集するには:
npx hardhat compile
すべてのテストを実行するには:
npx hardhat test
export NODE_OPTIONS=--max_old_space_size=4096
テストを実行するには必要になる場合があります。
コードメトリックを印刷するには:
npx ts-node metrics.ts
テストカバレッジを印刷するには:
npx hardhat coverage