setApprovalForAll — це функція ERC-721 / ERC-1155, що видає контракту або адресі blanket дозвіл передавати кожен NFT або токен певної колекції, що належить вашій адресі — теперішні і майбутні. Один підпис, невизначений scope, без ліміту на токен. Патерн OpenSea "approve один раз, торгуй багато разів" залежить від цього; кити Inferno Drainer і Pink Drainer експлуатують це. У доларових термінах це один з найдорожчих викликів функцій в історії Ethereum.

Навіщо існує setApprovalForAll

NFT-маркетплейсам потрібна можливість передавати NFT від імені продавців без вимоги окремої approve-транзакції для кожного listing. OpenSea, LooksRare, X2Y2, Blur — всі використовують setApprovalForAll, щоб видавати своєму маркетплейс-контракту дозвіл переміщувати NFT, коли продажі виконуються.

Це зручно для легітимного використання. Це також one-signature катастрофа, якщо схвалений контракт виявляється шкідливим. На відміну від ERC-20 approval (що мають ліміт суми на токен), setApprovalForAll бінарний: так чи ні, все чи нічого.

Механіка drainer

Фейкова сторінка mint → користувач підключає гаманець → кнопка mint запитує setApprovalForAll на найбільш цінний NFT-контракт у гаманці користувача → користувач підписує без читання → зловмисник тепер має права передачі для кожного NFT у тій колекції за тією адресою.

Зловмисник зазвичай затримує drain. Іноді вони чекають до того, як користувач додав більше NFT у гаманець (більша здобич). Іноді вони чекають до ринкової події, що знижує пильність користувача. За бухгалтерією Chainalysis, один Inferno Drainer ексфільтрував приблизно $80 мільйонів у 2023, передусім через підписи setApprovalForAll на Discord-розповсюджуваних фейкових сторінках mint.

Як UI гаманця представляє setApprovalForAll

Транзакція читається як "setApprovalForAll" у полі функції, з двома параметрами: адреса "operator" (контракт, що отримує approval) і булева (true для grant, false для revoke). Сучасні гаманці на кшталт Rabby і пост-2024 MetaMask відображають це чітко, часто з попередженням, якщо адреса operator невідома.

Старіша прошивка апаратного гаманця показує raw-транзакцію з hex-encoded даними. Прошивка Ledger Nano S Plus до 2024 року не парсила setApprovalForAll осмислено; Trezor Safe 3 і Safe 5 роблять. Якщо ваш апаратний гаманець відображає raw hex для незнайомого виклику, ставтесь до цього як до red flag — відмовтесь підписувати, оновіть прошивку, спробуйте знову.

Що захищає

Три правила, що працюють на практиці:

Перше, схвалюйте лише маркетплейси, які ви активно використовуєте. Якщо ви мінтите виключно на OpenSea, не схвалюйте контракт LooksRare. Кожен невикористаний approval — це майбутня поверхня атаки.

Друге, відкличте після першого використання незнайомих контрактів. Якщо ви підключаєтесь до нового dApp один раз для airdrop claim, одразу після відвідайте revoke.cash і видаліть approval.

Третє, розділяйте гаманці "trading" і "vault". Тримайте цінні NFT за адресою, у якої немає approval до будь-чого. Коли хочете листингувати один, переведіть на trading-адресу, зробіть listing, потім переведіть залишки назад. Це додає тертя, але повністю усуває клас катастрофи setApprovalForAll.

Подальше читання: EIP-2612 Permit, revoke.cash, Фішинг.