• Duel jest otwarty na Robinhood Chain
  • Uruchom pojedynek dwa tokeny, trzy pule, jedna transakcja
  • Runda zamyka się za --:--:--
  • Czterogodzinne rundy odkup zwycięzcy ma limit ceny
  • Płynność zablokowana na zawsze, bez tokenów zespołu

Bezpieczeństwo

Co ma wartość

  • ETH i tokeny w pulach, w pozycjach, których nikt nie może wycofać. ETH strony opuszcza jej pulę tylko wtedy, gdy ta strona jest do niej sprzedawana: przez tradera albo przez wyrównanie hooka po tym, jak transakcja rozsunęła trzy ceny.
  • Pule nagród, opłaty twórców i opłaty protokołu, przechowywane przez hook jako należności w ETH w PoolManagerze Uniswap V4, rozliczane osobno dla każdego pojedynku.

Co je chroni

  • Zablokowana płynność. Tylko fabryka może otwierać zarejestrowane pule lub dodawać ich płynność startową; wypłata i darowizna są cofane.
  • Ograniczeni odbiorcy. Pula nagród kupuje tylko zwycięzcę własnego pojedynku; opłaty twórcy trafiają tylko do twórcy pojedynku: portfela, który go uruchomił, albo adresu, któremu przekazał rolę i który ją przyjął. Opłaty protokołu trafiają do bieżącego skarbca, który właściciel fabryki może zmienić po 48 godzinach, także dla już zgromadzonych opłat protokołu.
  • Ograniczone uprawnienia fabryki. Tokeny nie mają właściciela ani funkcji mintowania, a hooka nie można zaktualizować ani wstrzymać. Właściciel fabryki może wstrzymać nowe uruchomienia, zaproponować ograniczone warunki dla przyszłych pojedynków lub zmienić skarbiec po upływie terminu. Może też od razu obniżyć udział protokołu w opłacie za swap we wszystkich pojedynkach, aż do zera, albo podnieść go z powrotem, nigdy ponad warunki pojedynku: to, czego protokół nie bierze, trafia do pul nagród. Właściciel może zrzec się roli na stałe (renounceOwnership): warunki, skarbiec, stawka protokołu i wstrzymanie zostają wtedy bez zmian, poza już zaproponowaną zmianą, którą każdy może jeszcze zastosować po upływie terminu.
  • Rozliczenie przed swapem. Pierwszy swap po zamknięciu rozlicza zakończoną średnią przed handlem. Pułap odkupu leży około 10% powyżej wartości odniesienia przechowywanej z dokładnością do ułamków ticka: 30-minutowej średniej wykładniczej ticków puli ETH, ograniczonej z góry do bieżącego ticka, tak by od razu podążała za ceną w dół.
  • Rundy tylko w ETH. Podział i średnia rundy korzystają z dwóch pul ETH. Zmiana strony przez A/B, która nie rusza żadnej ceny w ETH, nie zmienia ani sygnału, ani aktywności rundy, która inaczej byłaby spokojna.
  • Opłaty tylko przy pełnym wykonaniu. Swapy obciążane z góry są cofane, jeśli nie mogą w pełni wykonać żądanej kwoty. Gas sieci jest osobno.
  • Odizolowane wyrównanie. Zachowywane są tylko zyskowne pętle, ograniczone przez ETH sprzedającej puli. Nieudana próba jest cofana i pomijana; przy braku gazu cofany jest swap (ArbitrageStarved), aby wywołujący nie mógł pominąć wyrównania, wstrzymując gaz. Nie gwarantuje to zgodności cen ani ochrony przed wszystkimi stratami w handlu.
  • Te same zasady na każdej trasie. Hook pobiera opłaty, podatki i spalenia niezależnie od tego, czy router należy do Duel, czy jest innym routerem V4.

Fabryka rozpoczyna działanie ze wstrzymanym uruchamianiem pojedynków. Dopóki paused() ma wartość true, tylko owner() może uruchomić pojedynek; wywołania innych osób są wycofywane z błędem CreationPaused. Właściciel otwiera uruchamianie przez setPaused(false). Handel istniejącymi pojedynkami trwa nadal.

Co pokazuje strona

  • Obrazy tylko ze strony. Strony pokazują obrazy pojedynku wyłącznie z własnego adresu Duel i tylko obrazy przetworzone przez stronę: JPEG, PNG lub WebP odczytany najpierw z nagłówka (najwyżej 1536 × 1536 pikseli i 5 MB), zdekodowany w WebAssembly, dopasowany do 1024 pikseli i zakodowany ponownie jako WebP, bez metadanych. Polityka bezpieczeństwa stron nie pozwala im ładować obrazów skądkolwiek indziej.
  • Odizolowane kodeki. Obrazy są dekodowane we własnym Workerze, do którego dociera tylko strona i który niczego nie przechowuje: żadnego klucza, żadnej pamięci. Błąd w kodeku dotknąłby tylko obrazu, który odczytuje. Strona sprawdza odpowiedź tego Workera (statyczny WebP o oczekiwanym rozmiarze), zanim ją zachowa, a dekodery w C startują od nowa dla każdego obrazu.
  • Pojedynki uruchomione bezpośrednio z kontraktu. Ich dane mogą wskazywać dowolny adres. Strona nie pokazuje obrazów https; obraz z IPFS pobiera jeden raz przez publiczną bramkę (najwyżej 5 MB i 10 sekund), przetwarza go jak przesłany plik i pokazuje własną kopię albo inicjały strony pojedynku.
  • Przesyłanie w granicach. Strona przyjmuje obrazy tylko ze swoich stron: dziesięć na minutę z jednego adresu i ograniczoną liczbę dziennie. Obraz, którego nie wskazuje żaden pojedynek, jest usuwany po dobie.

Jak to sprawdzono

  • Testy automatyczne obejmują zachowanie kontraktów, aplikację webową i bota powiadomień. Pokrycie to miara testów, a nie dowód, że każde możliwe zachowanie jest bezpieczne.
  • Testy na forku sprawdzają integrację z kontraktami Uniswap V4 wdrożonymi w Robinhood Chain, w tym z Universal Routerem, Permit2 i V4 Quoterem.
  • Testy regresji zachowują przypadki znalezione podczas wewnętrznego przeglądu, w tym rozliczanie opłat, przypadki brzegowe startu, rozliczanie rund i wyczerpane pule.
  • Testy niezmienników sprawdzają księgowość w losowych sekwencjach transakcji, rozliczeń i odbiorów: należności w ETH muszą zgadzać się z kwotami należnymi, a w hooku, fabryce ani routerze nie mogą zostawać tokeny pośrednie. Zaliczenie skonfigurowanych przebiegów nie dowodzi bezpieczeństwa dla każdej możliwej sekwencji.

Wewnętrzny przegląd znalazł i naprawił trasę z dokładnym wyjściem omijającą podatek antysnajperski, podział, który nie podążał za stroną kupioną samodzielnie, wyczerpane pule źle odczytywane przez cenę odniesienia odkupu oraz niebezpieczne linki w metadanych pojedynku.

Zgłaszanie podatności

Jeśli uważasz, że znalazłeś podatność, dziękujemy, że poświęcasz czas na jej zgłoszenie. Napisz do nas prywatnie na Telegramie, na @chatwithdivine, co znalazłeś i, jeśli możesz, jak to odtworzyć, i daj nam czas na sprawdzenie, zanim cokolwiek upublicznisz. Odpowiemy szybko i będziemy cię informować.

Nigdy nie piszemy pierwsi: ufaj tylko @chatwithdivine.