Как Cook Finance отдал злоумышленнику чужие токены  на сумму $50 тыс.
29.06.2026 | CoinKyt Company

27 июня 2026 года злоумышленники нашли способ получить токены из хранилища Cook Finance, просто передав в контракт неверные числа. Контракт принял их без проверки — и честно «вернул» то, чего атакующие никогда не вносили.

 


Введение


Cook Finance — протокол на BNB Smart Chain, который позволяет создавать CKToken — своеобразные токен-корзины, аналог индексного фонда в традиционных финансах. Внутри одного CKToken объединены несколько токенов в определённых пропорциях — они называются компонентами. Купить CKToken — значит получить долю сразу в нескольких активах одновременно.


Для выпуска CKToken можно было внести один токен, а контракт сам распределял его между нужными компонентами. Именно в этой функции и скрывалась уязвимость.

 


Ход инцидента


1️⃣ Вызов функции выпуска с пользовательскими весами. Атакующие обратились к функции issueWithSingleToken2() в модуле IssuanceModuleV2. Особенность этой функции в том, что веса компонентов — то есть пропорции, по которым внесённый токен распределяется между активами в корзине, — передавал сам вызывающий. Иными словами, пользователь сам говорил контракту: «распредели мой вклад в таких-то долях».


2️⃣ Завышенные веса при минимальном депозите. Злоумышленники внесли очень маленькое количество токена, но указали искусственно завышенные веса. Из-за этого контракт «думал», что для покрытия одного из компонентов корзины требуется намного большая сумма, чем реально была внесена.


3️⃣ Выпуск CKToken и ошибочный возврат остатка. После выпуска небольшого количества CKToken срабатывал механизм возврата остатков: если внесено больше, чем нужно для выпуска, контракт возвращает разницу. Но из-за завышенного расчёта контракт считал, что «пришло» значительно больше токенов, чем на самом деле. Разница между этой завышенной суммой и реально нужным количеством возвращалась атакующему — только брал контракт эту разницу не из депозита злоумышленника, а из уже существующих запасов хранилища.


4️⃣ Обмен в BNB. Полученные таким образом токены конвертировались обратно в BNB. Атака повторялась несколько раз.

 


Почему это стало возможным


Функция issueWithSingleToken2() принимала веса компонентов напрямую от пользователя и сразу использовала их в расчётах. Контракт не проверял, находятся ли эти веса в разумных пределах, и не сверял, реально ли поступило то количество токена, которое следует из переданных весов.


Особенно опасной оказалась ситуация, когда внесённый токен сам являлся компонентом CKToken. В этом случае контракт пропускал шаг обмена и просто «засчитывал» нужное количество компонента как уже полученное — без реальной проверки поступления. Дальше механизм возврата остатков делал своё дело: сравнивал завышенную расчётную сумму с реально нужной и возвращал разницу из резервов хранилища.


Дополнительно злоумышленники использовали тонкие пулы на PancakeSwap — биржевые пулы с малым объёмом ликвидности, курс в которых легко сдвинуть небольшими сделками. Это помогало провести обмен полученных токенов на выгодных условиях, но главной причиной успеха атаки был именно неправильный расчёт выпуска и возврата остатков в самом контракте.

 


Детали расследования: движение средств


Атака проводилась с двух адресов.


Адрес 0xEe18c4c2E123402731f43d680e75ca2809c30f8b
— на момент расследования остаётся неактивным, средства находятся на балансе адреса без движения.


Адрес 0x516144DE29Fb9d797666744C8ABffae07f974278
— после получения средств в сети BNB Smart Chain они были переброшены в сеть Ethereum через Relay.Link — сервис для перевода активов между разными блокчейнами. Там средства были обменяны на DAI (стейблкоин, привязанный к доллару), смешаны с другими средствами на балансе адреса и переведены дальше. Затем конвертированы обратно в ETH и отправлены в Tornado Cash для анонимизации.


Пример транзакции атаки: 0x51e46828b7aabfa810910b3f8ca535053716e6bcb8b7f94a4ff59757d71a1bca

 


Заключение


Атака на Cook Finance — пример того, как одна доверенная пользователю переменная может разрушить всю логику расчётов. Контракт добросовестно выполнял то, что ему сказали: распределял вклад по переданным весам и возвращал «остаток». Просто веса были ложными, а «остаток» брался из чужих средств.


Подобные ошибки особенно опасны в протоколах с составными токенами и многоступенчатой логикой выпуска: чем сложнее расчёт, тем больше мест, где неверные входные данные могут привести к непредсказуемому результату.


Часть средств уже выведена через Tornado Cash, другая часть остаётся на адресе злоумышленника без движения. Команда «КоинКит» продолжает отслеживать ситуацию.