가격 영향과 샌드위치 공격
모든 거래는 자기가 체결되는 가격을 움직이고, 다른 사람은 그 움직임으로 이익을 보려 할 수 있습니다. 이 글에서는 가격 영향과 샌드위치 공격이 무엇인지, GIWA와 GAMA의 주문서가 무엇을 막아 주는지, 그리고 유동성이 얇은 시장의 큰 주문에 남는 위험 하나를 설명합니다.
가격 영향
가격 영향은 내 거래가 가격을 얼마나 움직이는지를 말합니다. 매수는 체결되면서 가격을 밀어 올리므로, 큰 매수의 마지막 부분은 처음보다 비쌉니다. 시장이 작을수록 더 크게 움직입니다. 커브 초반의 출시 토큰이나 유동성이 적은 풀은 깊은 풀보다 훨씬 크게 움직입니다.
- 스왑하기 전에 앱이 수수료를 포함한 가격 영향을 보여 줍니다.
- DCA 주문은 매수 한 번이 가격을 얼마나 움직이는지 알려 줍니다. "매수할 때마다 가격이 약 X% 움직입니다."
- 슬리피지가 최소 수령량을 정합니다. 거래가 처리되기 전에 가격이 그보다 더 움직이면 더 나쁜 가격에 체결되는 대신 거래가 실패합니다.
앱은 기본적으로 슬리피지를 자동으로 정합니다. 커브는 3%, 풀은 0.5%이며, 거래 자체가 가격을 크게 움직이면 조금 더 늘립니다. 5%보다 높게 정하면 "슬리피지가 높으면 거래가 훨씬 불리한 가격에 체결될 수 있습니다."라고 경고합니다. 슬리피지와 가격 영향을 참고하세요.
샌드위치 공격이란
샌드위치 공격은 내 거래를 앞뒤로 감싸는 거래입니다. 누군가 내 매수 직전에 사서 내가 더 높은 가격을 내게 만들고, 내 매수가 끌어올린 가격에서 직후에 팝니다. 그 사람의 이익이 곧 내 손실입니다.
거래 대기 공간이 공개된 체인에서는 공격자가 대기 중인 스왑을 지켜보다가 그 앞뒤로 거래를 넣습니다. GIWA에는 공개 멤풀이 없습니다. 거래는 곧바로 GIWA의 시퀀서로 가고, 시퀀서가 우선순위 수수료가 높은 것부터 순서를 정합니다. 내 스왑이 블록에 들어가기 전에는 다른 사용자가 볼 수 없으므로 그것을 겨냥해 거래할 수 없습니다.
그렇다고 가격이 고정되지는 않습니다. 견적을 받은 뒤 내 거래가 처리되기 전에 다른 거래가 먼저 들어올 수 있고, 누구나 내 거래 직후에 거래할 수 있습니다. 내 가격이 얼마나 나빠질 수 있는지를 제한하는 것은 슬리피지 한도입니다.
시장가 주문을 지키는 장치
DCA 주문은 누구나 읽을 수 있는 일정에 따라 매수하므로, GAMA의 주문서에는 별도의 보호 장치가 있습니다. 이전 주문서에 대한 보안 검토에서는 이 장치가 없으면 시장가 주문이 매수 한 번의 절반 넘게 샌드위치 공격으로 잃을 수 있다는 것이 확인되었습니다. 현재 배포는 주문을 다음과 같이 체결합니다.
- 키퍼와 나만. GAMA의 키퍼와 주문의 소유자만 주문을 체결할 수 있습니다. 다른 사람은 내 주문의 체결 시점을 정할 수 없습니다.
- 무작위 시점. 키퍼는 각 간격의 매수를 그 간격 안의 무작위 시점에 체결합니다.
- 한 블록으로는 움직일 수 없는 가격. 모든 커브와 공식 풀은 각 블록의 첫 거래만 갱신하는 3분 가격 평균을 유지합니다. 가격이 이 평균에서 3% 넘게 벗어나 있으면 체결이 거부되고, 가격이 안정될 때까지 기다립니다. 이 범위를 가격 밴드라고 합니다.
- 하한. 각 체결은 현재 가격과 평균 중 나에게 더 불리한 쪽으로 계산한 뒤 내 슬리피지를 적용합니다.
- 내 가격 영향의 상한. 체결 한 번은 가격을 최대 약 1%까지만 움직일 수 있습니다. 더 큰 매수는 간격 안에서 분할 체결됩니다.
- 일괄 체결은 한 가격. 같은 경로의 주문은 한 번의 거래로 함께, 같은 가격에 체결됩니다. 이것이 일괄 체결입니다.
키퍼 키가 도난당하더라도 체결 한 번에서 가져갈 수 있는 것은 가격 밴드, 내 슬리피지, 1% 가격 영향 한도를 합친 것보다 많을 수 없습니다. 주문이 체결되는 방식을 참고하세요.
막힌 공격 사례
10월 3일 실제 테스트에서 새 지갑이 DCA 주문이 기다리는 동안 새 출시 토큰의 얇은 커브에서 0.055 테스트 ETH어치를 사서 가격을 3.6% 올렸습니다. 이 지갑이 직접 주문을 체결하려는 시도는 키퍼가 아니라서 거부되었습니다. 끌어올린 가격에서 키퍼가 체결하려는 시도도 가격 밴드 밖이라서 거부되었습니다. 실제 키퍼는 가격이 평균의 3% 안으로 돌아올 때까지 기다렸다가 69초 뒤에 주문을 체결했습니다.
막지 못하는 것
공개된 큰 주문을 앞질러 사기. 내 주문의 크기와 간격은 공개되어 있습니다. 유동성이 얇은 시장의 큰 DCA 주문은 체결 하나하나가 가격 밴드와 가격 영향 한도 안에 있더라도 매수할 때마다 가격을 계속 올립니다. 그보다 먼저 사서 내 주문이 사는 동안 들고 있던 사람은 나중에 더 높은 가격에 팔 수 있습니다.
같은 테스트에서 그 지갑은 주문이 매수하는 동안 토큰을 들고 있다가 약 3분 30초 뒤에 팔아 0.05609 테스트 ETH를 받았습니다. 0.00109, 약 2%의 이익입니다. 이 이익은 조작된 체결이 아니라 주문 자체의 매수에서 나왔습니다. GAMA는 이것을 얇은 시장에서 큰 주문이 만드는 일반적인 시장 영향으로 봅니다. 주문은 계속 공개되며 이 때문에 바뀌지 않습니다.
그 밖의 한계도 있습니다.
- 가격 평균이 없는 풀. 일반 풀을 거치는 경로에는 확인할 가격 평균이 없습니다. 이때 앱은 직접 가격 한도를 정하라고 요청합니다. "가격 한도를 설정하세요. 이 경로는 GAMA 가격 평균이 없는 풀을 거칩니다."
- 추세가 체결을 멈춥니다. 가격이 평균에서 3% 넘게 벗어난 채로 있으면 체결이 기다립니다. 체결되지 못한 채 간격이 끝난 매수는 건너뛰며 나중에 다시 시도하지 않습니다.
- 이전 버전. 이전 버전의 GAMA에서는 누구나 원하는 시점에 시장가 주문을 체결할 수 있습니다. 앱은 그런 주문에 경고를 표시하고 취소를 권합니다.
나를 지키는 방법
- 스왑하기 전에 매번 수수료를 포함한 가격 영향을 확인하세요. 높으면 금액을 줄이세요.
- 슬리피지는 낮게 두고, 5%를 넘는 값은 조심하세요.
- DCA 매수 한 번의 크기를 시장에 맞추세요. 얇은 커브에서는 매수 횟수를 늘려 한 번의 금액을 줄이거나 간격을 늘려, 매수 한 번이 가격을 조금만 움직이게 하세요.
- DCA 주문을 넣기 전에 표시된 슬리피지를 읽으세요. "각 매수는 시장 가격으로 체결되며 슬리피지는 최대 X%입니다." 풀을 거치는 경로에서는 자동이 매수 한 번의 가격 영향에 따라 커지므로, 얇은 풀의 큰 매수는 5%보다 훨씬 큰 슬리피지를 허용할 수 있습니다.
- 일정 가격 이상으로 사고 싶지 않다면 DCA 주문에 가격 한도를 정하세요.
- 큰 주문은 진행되는 동안 모두에게 보인다는 점을 기억하세요.
