GMX Synthetics 계약.
이 섹션에서는 시스템 작동 방식에 대한 일반적인 개요를 제공합니다.
기술 개요는 아래 섹션을 참조하세요.
시장은 현물 거래와 무기한 거래를 모두 지원하며 긴 담보 토큰, 짧은 담보 토큰 및 인덱스 토큰을 지정하여 생성됩니다.
예:
유동성 공급자는 긴 담보 토큰이나 짧은 담보 토큰 중 하나를 예치하거나 둘 다 유동성 토큰을 발행할 수 있습니다.
긴 담보 토큰은 긴 포지션을 뒷받침하는 데 사용되고, 짧은 담보 토큰은 짧은 포지션을 뒷받침하는 데 사용됩니다.
유동성 공급자는 유동성을 제공하는 시장에서 거래자의 이익과 손실을 떠맡습니다.
별도의 시장을 가짐으로써 위험 격리가 가능하며, 유동성 공급자는 자신이 예치한 시장에만 노출되므로 잠재적으로 무허가 상장이 가능해집니다.
거래자는 롱 토큰이나 숏 토큰을 시장의 담보로 사용할 수 있습니다.
계약은 다음과 같은 주요 기능을 지원합니다.
전면 실행 문제를 방지하려면 대부분의 작업을 실행하는 데 두 단계가 필요합니다.
가격은 가격이 쿼리된 시간을 기준으로 지속적으로 가격에 서명하는 오프체인 오라클 시스템에 의해 제공됩니다.
최소 가격과 최대 가격이 모두 서명되어 있으므로 입찰-매도 스프레드에 대한 정보가 포함될 수 있습니다.
Oracle 계약 내에 저장된 가격은 소수점 이하 30자리의 값을 사용하여 토큰 한 단위의 가격을 나타냅니다.
이러한 방식으로 가격을 표시하면 토큰 금액과 명목화폐 가치 간의 변환을 단순화할 수 있습니다. 예를 들어 주어진 토큰 수의 명목화폐 가치를 계산하려면 다음과 같이 계산하면 됩니다. 토큰 금액 * 오라클 가격, 특정 토큰 금액을 계산하는 경우 법정화폐 가치는 법정화폐 가치 / 오라클 가격이 됩니다.
펀딩 수수료와 가격 영향은 가격 조작 위험을 줄이면서 매수/매도 균형을 유지합니다.
시스템에는 몇 가지 키퍼와 노드가 있습니다:
몇 가지 주요 계약 유형이 있습니다.
계약은 점진적인 업그레이드가 가능하도록 이러한 유형으로 구분됩니다.
대부분의 데이터는 DataStore 계약을 사용하여 저장됩니다.
*storeUtils 계약은 DataStore를 사용하여 구조체 데이터를 저장하므로 구조체에 새 키를 추가할 수 있습니다.
EnumberableSets는 인터페이스나 키퍼가 주문 목록과 위치 목록을 쉽게 쿼리할 수 있도록 하는 데 사용되며, 인덱서가 최신 블록을 동기화하는 데 지연이 있을 수 있으므로 이는 인덱서에 사용됩니다. 목록을 계약서에 직접 저장하면 필요할 때 정확한 데이터를 검색하고 확인할 수 있습니다.
*eventUtils 계약은 이벤트 이미터를 사용하여 이벤트를 생성하며, 이벤트는 ABI 업데이트 없이도 새로운 키-값을 이벤트에 추가할 수 있도록 일반화됩니다.
GMX Liquidity Vault의 약자: 동일한 롱 토큰과 숏 토큰을 사용하는 여러 시장의 래퍼입니다. 유동성은 시장 활용도에 따라 기본 시장 간에 자동으로 재조정됩니다.
이 섹션에서는 계약에 대한 기술적 설명을 제공합니다.
Market은 MarketFactory.createMarket
사용하여 생성되며, 이는 MarketToken을 생성하고 MarketStore에 Market.Props 구조체를 저장합니다.
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 한 단위의 가격은 5000 / (10 ^ 18), 5 * (10 ^ -15)
입니다.
소수를 처리하려면 값에 (10 ^ 30)
을 곱합니다.
가격은 5000 / (10 ^ 18) * (10 ^ 30) => 5000 * (10 ^ 12)
으로 저장됩니다.
가스 최적화를 위해 이러한 가격은 uint8 소수점 승수 값과 uint32 가격 값의 형태로 오라클에 전송됩니다.
10진수 승수 값이 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 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 한 단위의 가격은 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%
이 됩니다. (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 > ThresholdForStableFunding이므로 saveFundingFactorPerSecond는 0.0001% * 6% * 600 = 0.0036%
증가해야 합니다.
매수자가 이미 매도자에게 지불하고 있기 때문에 스큐는 동일하며 longShortImbalance < ThresholdForStableFunding,SavedFundingFactorPerSecond는 변경되어서는 안 됩니다.
longShortImbalance < ThresholdForDecreaseFunding 이므로,SavedFundingFactorPerSecond 는 0.000002% * 600 = 0.0012%
감소해야 합니다.
왜곡이 다른 방향이기 때문에 saveFundingFactorPerSecond는 0.0001% * 1% * 600 = 0.0006%
만큼 감소해야 합니다.
펀딩 수수료를 조작할 수 있는 방법이 있다는 점에 유의하세요. 이러한 가능성을 최소화하도록 펀딩 요소를 조정해야 합니다.
longOpenInterest > shortOpenInterest 및 longShortImbalance가 ThresholdForStableFunding 내에 있는 경우, 숏 포지션을 보유한 사용자는 롱 포지션을 오픈하여 longShortImbalance를 높이고 펀딩 수수료를 높이려고 시도할 수 있습니다. 활성 시장에서는 이 게임을 어렵게 만드는 증가된 펀딩 수수료를 얻기 위해 다른 사람이 언제 반대 숏 포지션을 오픈할지 예측하기 어렵습니다. 또한 이 게임의 이점을 최소화하도록 펀딩 요소를 조정할 수도 있습니다. .
longOpenInterest > shortOpenInterest 및 longShortImbalance > ThresholdForStableFunding인 경우, 매수 포지션을 보유한 트레이더는 전체 기간 동안 더 큰 값이 사용되는 대신 자금 요소가 지속적으로 업데이트되도록 이 시간 동안 여러 개의 소규모 거래를 할 수 있습니다. 롱 포지션에 대한 펀딩 수수료는 예상되지만 펀딩 수수료가 예상 요율 이하로 낮아져서는 안 됩니다.
유동성 공급자에게 지불되는 차용 수수료가 있습니다. 이는 사용자가 수수료를 지불하지 않고 풀 용량을 차지하기 위해 롱 포지션과 숏 포지션을 모두 개설하는 것을 방지하는 데 도움이 됩니다.
차용 수수료는 곡선 모델 또는 꼬임 모델을 사용할 수 있습니다.
곡선 모델을 사용하기 위해 구성할 키는 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 플래그를 설정하는 옵션도 있습니다. 이렇게 하면 작은 쪽의 차용 수수료가 0으로 설정됩니다. 예를 들어, 공매도보다 공매도가 많고 SkipBorrowingFeeForSmallerSide가 true인 경우 공매도에 대한 차입 수수료는 0이 됩니다.
가격 영향에 대한 코드는 /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에 제한이 있을 수 있으며, 시장 토큰 가격을 계산하는 데 사용되는 요소는 활동에 따라 다를 수 있습니다.
Keys.MAX_PNL_FACTOR_FOR_DEPOSITS: 예금에 대한 시장 토큰 가격을 계산할 때 손익 계수 한도입니다.
Keys.MAX_PNL_FACTOR_FOR_WITHDRAWALS: 인출에 대한 시장 토큰 가격을 계산할 때 PnL 계수 한도입니다.
Keys.MAX_PNL_FACTOR_FOR_TRADERS: 포지션 마감을 위한 시장 토큰 가격을 계산할 때 PnL 계수 한도입니다.
이러한 다양한 요소는 유동성 공급자가 위험을 관리하고 필요할 때 예금에 대한 인센티브를 제공하도록 구성할 수 있습니다. 예를 들어 거래자 손익 한도 설정은 거래자 손익으로 인해 시장 토큰 가격이 감소할 수 있는 금액을 제한하는 데 도움이 되며 예금 및 인출에 대한 손익 한도 설정은 이로 인해 발생할 수 있습니다. PnL이 높을 때 예금에 대한 인센티브를 제공할 수 있는 인출에 비해 예금에 대한 시장 토큰 가격이 더 낮습니다.
minColtralFactor: (포지션 담보) / (포지션 크기)의 최소 허용 비율을 결정합니다.
maxPoolAmount: 시장에 예치할 수 있는 최대 토큰 양
maxOpenInterest: 시장에 개설할 수 있는 최대 미결제약정
ReserveFactor: (포지션에 예약된 토큰의 가치) / (풀의 토큰)의 최대 허용 비율을 결정합니다.
maxPnlFactor: (PnL / 풀의 토큰 가치)의 최대 비율
positionFeeFactor: 포지션 증가/감소 조치에 대해 공제되는 수수료 금액을 결정합니다. 수수료 금액은 포지션 크기 변경에 따라 결정됩니다.
positionImpactFactor: "가격 영향" 섹션에 설명된 포지션에 대한 "가격 영향 요소"입니다.
maxPositionImpactFactor: "가격 영향" 섹션에 설명된 포지션에 대한 "최대 가격 영향"입니다.
positionImpactExComponentFactor: "가격 영향" 섹션에 설명된 포지션 액션에 대한 "가격 영향 지수" 값입니다.
swapFeeFactor: 스왑에 대해 공제될 수수료 비율을 결정합니다. 수수료 금액은 스왑 금액을 기준으로 합니다.
swapImpactFactor: "가격 영향" 섹션에 설명된 "가격 영향 요소"입니다.
swapImpactExComponentFactor: 위의 "가격 영향" 섹션에 설명된 예금 및 스왑에 대한 "가격 영향 지수" 값입니다.
fundFactor: "펀딩 수수료" 섹션에 설명된 "초당 펀딩 요소" 값입니다.
BorrowingFactorForLongs: "차용 수수료" 섹션에 설명된 매수 포지션에 대한 "차용 요소"입니다.
BorrowingFactorForShorts: "차용 수수료" 섹션에 설명된 숏 포지션에 대한 "차용 요소"입니다.
BorrowingExComponentFactorForLongs: "차용 수수료" 섹션에 설명된 매수 포지션에 대한 "차용 지수 인자"입니다.
BorrowingExComponentFactorForShorts: "차용 수수료" 섹션에 설명된 매수 포지션에 대한 "차입 지수 인자"입니다.
역할은 RoleStore에서 관리되며 RoleAdmin은 모든 역할을 부여하고 취소할 수 있는 액세스 권한을 갖습니다.
처음에는 RoleAdmin이 배포자가 되지만 역할이 설정된 후에는 이를 제거해야 합니다.
초기 설정 후:
Timelock 계약에만 RoleAdmin 역할이 있어야 합니다.
Timelock 관리자는 시간 지연을 통해 새로운 역할을 부여할 수 있습니다.
시스템 값은 구성 계약을 통해서만 설정해야 합니다.
EOA에는 컨트롤러 역할이 있어서는 안 됩니다.
구성 관리자 및 시간 잠금 관리자는 기능 비활성화, 잘못된 값 설정, 악성 토큰 허용 목록, 긍정적인 가격 영향 값 남용 등을 통해 잠재적으로 일반 작업을 방해할 수 있습니다.
타임록 다중서명은 악의적이거나 손상된 계정의 권한을 취소해야 할 것으로 예상됩니다.
주문 보관인과 동결 주문 보관인은 거래 주문, 지연된 거래 실행, ADL 실행 등을 통해 잠재적으로 가치를 추출할 수 있습니다. 이는 키퍼 네트워크를 통해 부분적으로 완화될 것입니다.
Oracle 서명자는 토큰 가격을 정확하게 보고해야 합니다.
담보 토큰은 구성된 TOKEN_TRANSFER_GAS_LIMIT로 화이트리스트에 추가되어야 합니다.
리베이스 토큰, 전송 시 잔액을 변경하는 토큰, 토큰 소각, 콜백이 포함된 토큰(예: ERC-777 토큰 등)은 시스템과 호환되지 않으며 화이트리스트에 추가해서는 안 됩니다.
주문 보관인은 스왑이 포함된 지정가 주문에 대해 서로 다른 타임스탬프의 가격을 사용할 수 있으며 이로 인해 생산량이 달라질 수 있습니다.
주문 보관인은 가스 낭비를 최소화하기 위해 거래를 보내기 전에 거래가 되돌릴지 여부를 검증해야 합니다.
주문 키퍼는 가스가 부족한 상태에서 요청을 실행함으로써 요청을 실행하는 대신 취소할 수 있습니다.
실행 트랜잭션에 최대 블록 가스 한도에 가까운 많은 양의 가스가 필요한 경우 해당 트랜잭션이 블록에 포함되지 않도록 블록을 채우는 것이 가능할 수 있습니다.
특정 블록체인에서는 키퍼가 트랜잭션을 실행하는 데 사용되는 tx.gasprice를 제어할 수 있으며 이는 키퍼에게 지불되는 실행 수수료에 영향을 미칩니다.
의도적으로 시장의 불균형을 초래하여 악의적인 사용자가 주문을 실행하지 못하게 하여 가격에 큰 영향을 미칠 수 있습니다. 이는 비용이 많이 들고 이익을 얻기 어렵습니다.
포지션과 스왑을 사용하고 시장, 체인, 포크, 기타 프로토콜 전반에 걸쳐 거래함으로써 가격 영향을 줄일 수 있습니다. 이는 가상 재고 추적을 통해 부분적으로 완화됩니다.
사용자는 높은 레버리지 포지션을 사용하여 가격 영향을 줄일 수 있습니다. 이는 MIN_COLLATERAL_FACTOR_FOR_OPEN_INTEREST_MULTIPLIER 값으로 부분적으로 완화됩니다.
가격 영향 가치 계산에는 수수료와 가격 영향 자체로 인한 효과가 고려되지 않습니다. 대부분의 경우 가격 영향 계산에 미치는 영향은 작아야 합니다.
드물지만 수영장 가치가 부정적인 것은 가능합니다. 이는 ImpactPoolamount 및 보류중인 PNL이 수영장의 토큰의 가치에서 빼기 때문에 발생할 수 있습니다.
긍정적 인 위치 가격 및 부정적인 위치 가격 영향의 차이로 인해 시장 토큰의 가격에 영향을 미치는 위치 영향 풀에 가상 토큰 금액이 구축 될 수 있습니다. 필요한 경우 위치 영향 풀을 점차 배포해야합니다.
가상 인벤토리는 수영장의 토큰 양을 추적합니다. 각 그룹의 토큰이 동일한 유형이며 동일한 소수증을 가져야합니다. 즉, 그룹의 수영장을 가로 지르는 긴 토큰은 동일한 소마 장애가 있어야합니다. USDC가 6 개의 소수증을 가지고 있고 DAI가 18 개의 소수증을 가지고 있다고 가정 할 때 그룹에서 동일한 소수성을 가져야합니다.
시장 창출 / 토큰 화이트리스트 전에 가상 ID를 설정해야합니다. 토큰 / 시장 거래 후 설정된 경우 추적이 정확하지 않으며 조정해야 할 수도 있습니다.
시퀀서가있는 L2S의 경우 L2 시퀀서가 활성화되어 있는지 확인하기위한 계약 검증이 없으며, 시퀀서가 정기적으로 작동하는 경우 블록이 생성되지 않으면 Oracle Keepers는 가격 서명을 중지해야합니다. Oracle Keepers는 최신 가격을 사용한 최신 블록
L2 시퀀서가 다운 된 경우 청산을 방지하기 위해 위치로의 예금을 방지 할 수 있습니다.
온쇄 가격 사료를 사용하여 전적으로 실행할 수있는 거래의 경우 가격 대기 시간 또는 체인이 줄어드는 이유를 활용할 수 있습니다. 온쇄 가격 사료의 사용은 일시적이어야하며 낮은 대기 시간 피드 여야합니다. 대신 모든 토큰이 지원되면 대신 사용됩니다
Block Reorgs는 사용자가 사용자가 호의적으로 이동하지 않은 경우 사용자가 주문을 소급 적으로 취소 할 수 있습니다.
주문 실행을 방지하기 위해 주문의 업데이트 및 취소가 진행될 수 있습니다. 성공적인 프론트 실행 가능성이 50%보다 적거나 50%보다 적은 경우 문제가되지 않아야합니다. 전략이 순 수익성이 없는지 확인하기 위해 가격 영향을 조정해야합니다.
블록 체인 또는 Oracle의 다운 타임의 경우 주문이 상당히 다른 가격으로 실행되거나 주문의 수용 가능한 가격을 충족 할 수없는 경우 실행되지 않을 수 있습니다.
블록 체인 노드가 타임 스탬프를 제어하는 블록 체인의 경우 Oracle 가격 이이 값에 대해 검증되기 때문에 블록 타임 스탬프의 정확도에 대한 의존성이 있습니다. 타임 스탬프 수익성이 없습니다
GLV 시프트 기능은 일반적으로 활용도가 낮은 시장에서의 활용을 일시적으로 증가시킴으로써 악용 될 수 있습니다. 골키퍼가 교대를 실행하면 공격자는 활용을 정상 수준으로 다시 낮출 수 있습니다. 포지션 수수료 및 가격 영향은이 공격이 GLV 손실을 충당 할 정도로 비용이 많이 드는 방식으로 구성되어야합니다.
GLV에는 최대 pnltopoolfactorfortraders 이상인 GM 시장이있을 수 있습니다. 이 GM 시장의 MaxpnlfactorfordePosits가 Maxpnlfactorfortraders보다 높으면, 거래가 캡핑 된 이익을 실현 한 후에는 예금 중에 GM 시장이 더 낮게 가치가 있습니다. 악의적 인 사용자는 그러한 조건에서 GM 시장을 관찰하고 곧 뒤 따르는 ADL로부터 얻기 위해 포함 된 GLV에 입금 할 수 있습니다. 이 maxpnlfactorfordeposits를 피하려면 maxpnlfactorfortraders보다 작거나 같아야합니다.
시장 가치가 부정적인 것이 기술적으로 가능합니다. 이 경우 시장 가치가 양수가 될 때까지 GLV는 사용할 수 없습니다.
GM 토큰은 높은 PNL 계수 또는 높은 예약 USD로 인해 비유동이 될 수 있습니다. 사용자는 비유동 GM 토큰을 GVL에 입금하고 다른 시장에서 유동성을 철회하여 GLV에 비유동 토큰을 남길 수 있습니다. GLVMAXMARKETTOKENBALANCEUSD 및 GLVMAXMARKETTOKENBALANCEAMONT 매개 변수는 위험한 시장에서 너무 많은 GM 토큰을 피하기 위해 시장의 위험성을 설명해야합니다.
scripts/verifyFallback.ts
계약을 확인하는 데 사용할 수 있습니다npx hardhat verify
해야합니다. 그 후 모든 MarketToken 계약은 소스 코드가 동일하므로 확인해야합니다. 예를 들어 이전 계약과 신규 계약 간의 시장 토큰과 같은 가격 차이로 이어질 수있는 신규 계약이 추가되면 새 계약이 활성화되기 전에 기존 계약을 비활성화하기 위해주의해야합니다.
독자 계약 또는 잠재적으로 구식 계산을 사용하는 외부 프로토콜은 최신 계약 및 계산을 사용하여 GM 토큰의 체인 링크 가격 피드를 사용하도록 상기시켜야합니다.
통합이 알아야 할 중요한 변경 사항을 문서화하는 최선의 노력을 게시하는 것이 좋습니다.
계약이 주식 합성 시장을 지원하는 데 사용되는 경우 주식 분할 및 유사한 변경 사항을 처리 할 수 있도록주의를 기울여야합니다.
"컨트롤러"역할과의 계약은 데이터 저장소 값 설정과 같은 중요한 기능에 액세스 할 수 있습니다. 이로 인해 그러한 계약에 중요한 가치를 변경하는 데 사용할 수있는 일반적인 기능이나 기능이 없도록주의해야합니다.
다양한 시장 유형에 대한 테스트를 추가해야합니다. 예 : 단일 시장, 단일 토큰 시장
콜백 계약이 고정 인덱스로 값을 참조 할 수 있으므로 콜백에 대한 eventData의 값 순서는 엄격하게 필요하지 않으면 수정해서는 안됩니다.
콜백으로 전달 된 구조물이 변경되면 예 : 예금, 인출, 주문 스트러크가 변경되면 이전 구조가 작동을 중단 할 것으로 예상되는 콜백 계약의 기능이 발생합니다.
추천 시스템을 사용하는 경우 주문 핸들러는 거래자의 추천 코드를 업데이트하기 위해 액세스해야합니다.
요청에 지정된 요구 사항을 이행 할 수없는 경우 예금, 인출 및 주문이 취소 될 수 있습니다. 기금 및 가스 환불이 취소 시점에 전송 될 위치를 확인하여 기대치와 일치하는지 확인하십시오.
위치 주문 감소는 단일 토큰 대신 2 개의 토큰을 출력 할 수 있습니다. 포지션 스왑 감소가 실패하는 경우 출력 금액과 담보가 수수료를 충당하기에 충분하지 않아 주문을 실행하지 않을 수도 있습니다.
스프레드가 큰 경우, 포지션을 개설 / 폐쇄하면 시장 토큰의 최소 및 최대 가격을 크게 변경할 수 있습니다. 이는 수익성있는 방식으로 조작 할 수 없어야합니다.
Funding_Factor, STABLE_FUNDING_FACTOR, BORPING_FACTOR, SKIP_BORSING_FEE_FOR_SISSID, BORPING_FEE_RECEIVER_FACTOR와 같은 구성 값의 변경 사항은 사용자에게 추가 비용이 발생할 수 있습니다.
MAX_PNL_FACTOR_FOR_TRADERS로 인해 Trader PNL이 제한되는 경우, 상한선이 풀의 현재 상태에 따라 CAP가 다시 계산 된 후 위치가 감소 / 폐쇄 된 시점의 순서에 따라 트레이더에게 지불 된 이익의 비율이 다를 수 있습니다.
이벤트 데이터는 콜백 계약으로 전달 될 수 있고, 이벤트 데이터의 매개 변수 순서는 변하지 않으려 고 시도되므로 인덱스별로 매개 변수에 액세스 할 수 있습니다. 예상 값
Order.sizeelta 및 Order.InitialCollateralDeltaamount와 같은 일부 매개 변수는 실행 중에 업데이트 될 수 있으며, 업데이트 된 값은 콜백 계약으로 전달되지 않을 수 있습니다.
콜백 계약을 체결 할 때 콜백 계약은 퇴적물 밴들러, OrderHandler 또는 DisplopalHandler의 화이트리스트를 사용해야 할 수도 있습니다. 새 버전의 새 버전은 새 코드가 핸들러에 추가 될 때 배포 될 수 있습니다. 예를 들어 OrderHandler (1), OrderHandler (2), 예를 들어 일시적으로 존재합니다. 이로 인해 콜백 계약은 화이트리스트를 만들고 동시에 여러 번의 콜백을 수락 할 수 있어야합니다. 예금자, 주문 핸들러 및 철수 핸들러
콜백 계약의 경우 퇴적물 밴더, 주문 핸들러, 철수에 대한 별도의 화이트리스트를 유지하는 대신 콜백 계약의 경우, 가능한 솔루션은 롤 RoleStore.hasRole(msg.sender, Role.CONTROLLER)
로에서 MSG.Sender의 역할을 검증하는 것입니다. MSG.Sender가 유효한 처리기인지 확인하십시오
ExchangerOuter, Oracle 또는 Reader와 같은 계약을 사용하는 경우 새 논리가 추가됨에 따라 주소가 변경됩니다.
ExchangerOuter, Oracle 또는 Reader와 같은 계약이 업데이트 된 경우 기능 매개 변수를 동일하게 유지하려는 노력이 이루어져야합니다. 예를 들어 새 주문 속성을 지원하려면 항상 가능하지는 않습니다. 변경해야합니다
배포를위한 롤레스테로와 데이터 저장소는 이전 계약에서 새 계약으로 자금 마이그레이션이 변경되면 변경되지 않아야합니다.
이 코드는 읽기 전용 재생의 위험을 최소화하기 위해 구성되었지만 이러한 가능성을 방지하기 위해주의를 기울여야합니다.
토큰 에어 드롭은 GM 토큰 보유자의 계정에 발생할 수 있으며, GM 토큰을 보유한 계약을 통합하면 이러한 토큰을 청구 할 수 있어야합니다. 그렇지 않으면 토큰이 잠긴 경우, 이에 대한 정확한 구현은 통합 계약에 따라 다릅니다. 시장 토큰이 아닌 토큰의 경우 Keys.MARKET_LIST
값을 사용하여 확인할 수 있습니다.
ETH 전송은 가스 한계에 대해 aviL_Token_transfer_GAS_LIMIT와 함께 전송됩니다. 가스가 충분하지 않거나 기타 오류로 인해 전송이 실패하면 ETH는 대신 weth로 전송됩니다.
계정은 ADL / 청산에 대한 ETH를받을 수 있습니다. 계정이 ETH를받을 수 없다면 Weth는 대신 전송됩니다.
긍정적 인 가격 영향은 충격 풀의 토큰 양과 구성 값을 기준으로 캡핑됩니다.
부정적인 가격 영향은 구성된 값에 의해 제한 될 수 있습니다
부정적인 가격 영향이 제한되면 추가 금액은 청구 가능한 담보 풀에 보관됩니다. 이는 ExchangerOurter.clecollateral function을 사용하여 수동으로 청구해야합니다.
긍정적 인 자금 수수료는 exchangerouter.claimfundingfees 기능을 사용하여 수동으로 청구해야합니다.
exchangerouter.claimaffiliaterewards 기능을 사용하여 수동으로 청구해야합니다.
시장이나 기능이 비활성화 될 수 있습니다
콜백이 되돌아도 여전히 실행이 계속됩니다
콜백에 충분한 가스가 있는지 확인하십시오
Subaccounts는 계정 주문을 작성, 업데이트 및 취소 할 수 있습니다.
하위 계정은 계정에서 wnt와 담보를 소비 할 수 있습니다
UI 수수료를 변경할 수 있습니다
추천 할인을 변경할 수 있습니다
블랙리스트 주소에 대한 자금은 프로토콜 내에 보관됩니다.
인덱스 토큰이 항상 긴 토큰임을 보장하는 것은 아닙니다.
긍정적인지 부정적인 영향이 있는지 여부에 따라 수수료 금리 변경
GM 가격을 추정 할 때 PNL 팩터를 고려하십시오
입금 취소를 처리합니다
컨트롤러 역할을 가진 핸들러 만 AfterDepositeXecution 및 AfterDepositCancellation 콜백 함수를 호출 할 수 있습니다.
올바른 입금 실행 만 콜백 함수를 호출 할 수 있는지 확인하십시오.
길고 짧은 토큰을 가진 시장을 고려하면 스왑은 이러한 시장에 지원되지 않습니다.
긍정적 및 부정적인 가격 영향을 고려하십시오
입금 요청을 취소 할 수없는 구성 지연에 대한 요청 취소 기간이 있습니다.
생산량은 가격 영향 및 수수료의 적용을받습니다
예금은 max_pnl_factor_for_deposits 위에 허용되지 않습니다
모든 시장의 첫 입금은 수신기 _for_first_deposit로 이동해야합니다.
인출에는 두 개의 최소 출력을 사용해야합니다
철수 취소를 처리합니다
컨트롤러 역할을 가진 핸들러 만 이후에 DrawalExecution을 호출 할 수 있으며 DrawAlcancellation 콜백 함수를 호출 할 수 있습니다.
올바른 인출 실행 만 콜백 함수를 호출 할 수 있는지 확인하십시오.
길고 짧은 토큰을 가진 시장을 고려하면 스왑은 이러한 시장에 지원되지 않습니다.
긍정적 및 부정적인 가격 영향을 고려하십시오
인출 요청을 취소 할 수없는 구성 지연에 대한 요청 취소 기간이 있습니다.
생산량은 가격 영향 및 수수료의 적용을받습니다
인출은 max_pnl_factor_for_withdrawals 위에 허용되지 않습니다
주문 취소 처리
청산 및 ADL은 저장된 콜백 계약을 유발할 수 있습니다
주문이 얼어 붙을 수 있습니다
컨트롤러 역할을 가진 핸들러 만 이후에 AfterOdereXecution, AfterOrderCancellation 및 AfterOrderFrozen Callback 함수를 호출 할 수 있습니다.
올바른 순서 실행 만 콜백 함수를 호출 할 수 있는지 확인하십시오.
길고 짧은 토큰을 가진 시장을 고려하면 스왑은 이러한 시장에 지원되지 않습니다.
긍정적 및 부정적인 가격 영향을 고려하십시오
저장된 콜백 계약을 변경할 수 있습니다
주문 요청을 취소 할 수없는 구성 지연에 대한 요청 취소 기간이 있습니다.
생산량은 가격 영향 및 수수료의 적용을받습니다
포지션 영향 풀은 시간이 지남에 따라 유동성 제공 업체에 분배됩니다.
가격 영향 계산을 시도하는 경우 가상 인벤토리를 참조해야합니다.
Trader PNL은 max_pnl_factor_for_traders 위에 캡핑됩니다
부정적인 가격 영향은 위치 감소에 막을 수 있습니다
주문 크기 셀타 감소 및 Clateraldelta는 위치가 처리 할 수있는 것보다 더 큰 경우 자동 업데이트됩니다.
WillPositionCillestalervesolofifively Validation을 고려하십시오
감소에 대한 수용소를 고려하십시오
최소 담보 금액을 고려하십시오
청산 중에는 여전히 추천이 지불됩니다
직책에 담보가 없을 수 있습니다
크기가 0 인 위치는 존재할 수 없습니다
계약을 수집하려면 :
npx hardhat compile
모든 테스트를 실행하려면 다음 안내를 따르세요.
npx hardhat test
export NODE_OPTIONS=--max_old_space_size=4096
테스트를 실행하려면 필요할 수 있습니다.
코드 메트릭 인쇄 :
npx ts-node metrics.ts
테스트 범위를 인쇄하려면 :
npx hardhat coverage