InVM - изнутри о Web3
406 subscribers
46 photos
5 files
74 links
Про тонкости работы Defi в EVM-блокчейнах глазами solidity разработчика.

Админ @zerofuz
Download Telegram
InVM - изнутри о Web3
#EVM Не так давно нужны были недели, чтобы обработать вручную тысячи токенов, читать их код на bscscan, искать скрытые комиссии, это работа обезьянки, а не разработчика)) Встретил проект TokenChecks и понял, что именно это я давно искал)) Опубликовал свое…
Обновление:
- Поддерживается больше блокчейнов и dex’ов.
- Добавлен новый способ проверки токенов, что можно купить и продать без затрат на оплату траназкции. Раньше eth_call + перезапись состояния (контракт его нужно виртуально задеплоить и потом к нему обратиться в пределах одного eth_call). Теперь достаточно только eth_call. Вот место в контракте. Это позволяет покрыть больше блокчейнов, в том числе avax-c.
С помощью https://dune.com можно взаимодействовать с eth/bsc/matic/optimism блокчейнами через sql запросы и упаковывать в инфографики, например «прирост деплоев смарт-контрактов по месяцам».

Мне сильно пригодился для того, чтобы выгрузить все адреса еth контрактов, за 15млн блоков и пару часов)) Вышел файл на 2ГБ и 50млн адресов. Не без ухищрений конечно для ускорения сбора, но это все равно в десятки раз быстрее, чем собирать данные через провайдера типа infura/ankr и читать транзакции каждого блока, где есть создание нового контракта.

Вот кто-то заморочился и сделал дашборд про нфт https://dune.com/impossiblefinance/nft-lending-aggregated-dash , да, оказывается есть landing для nft.

Интересно, какие такие ухищрения для ускорения сбора? Ставьте 🔥

Что почитать, чтобы лучше разбираться в сортах NFT, как не попасть на скам минт?
InVM - изнутри о Web3
С помощью https://dune.com можно взаимодействовать с eth/bsc/matic/optimism блокчейнами через sql запросы и упаковывать в инфографики, например «прирост деплоев смарт-контрактов по месяцам». Мне сильно пригодился для того, чтобы выгрузить все адреса еth…
Перед тем, как расскажу про «ухищрения» введу в курс дела.
На dune.com создал запрос на извлечение всех созданных адресов из eth. Вот сам SQL-запрос:

SELECT address
from ethereum.traces
where
block_number>={{tillBlock}}-{{step}}
and block_number<={{tillBlock}}
and success=true
and type='create'

Переменные внутри {{}} подставляются снаружи.
Есть кнопка RUN, которая создает задачу и ждет ее завершения.
Но сканировать все 15млн блоков руками неблагодарное дело, в том числе из-за того, что когда адресов в ответе больше 1млн, это дико лагает. И нельзя извлечь все адреса простым копированием, нет такой кнопки.

А теперь про то, как это ускорить:

Если открыть инспектор браузера(f12->network) и посмотреть, что творится при клике на RUN, увидим, что создается task через http.post.graphql запрос, и раз в несколько секунд проверяется статус task’а. Когда статус меняется, результат работы выгружается отдельным graphql запросом.

Заголовки (Authorization,X-Dune-Access-Token
) истекают очень быстро, поэтому нужно часто выполнять http.post./session с куками авторизованного юзера, чтобы обновить их.

Итого, общая структура (nodejs,typescript,got) скрипта такая:
⁃ Обновляем токены сессии перед каждым graphql запросам
⁃ Создаем task, передаем tillBlock, step
⁃ Ждем окончания выполнения задачи
⁃ Запрашиваем результаты выполнения и выделяем адреса
⁃ Сохраняем в файл (fs.appendFileSync) одна строка = 1 адрес.

Скрипт однопоточный, чтобы не перегрузить dune, который бесплатно дает извлекать такие данные.
InVM - изнутри о Web3
#DEFI Как создать особенный адрес кошелька в EVM-сети Существует утилита Profanity (остерегайтесь форков), которая написана в далеком 2019 году. Она ищет такой privateKey, что address совпадает с искомым паттерном. Например 10 ноликов вначале адреса, или…
#HACK
Profanity уязвим, найден вектор атаки когда становится возможным восстановить приватный ключ зная публичный ключ из транзакции и некоторого брутфорса, подробнее в блоге 1inch . Адреса кошельков и контрактов, созданных с помощью profanity в опасности
InVM - изнутри о Web3
9-21 июля, BR ⁃ Сменил вектор анализа с «одна транзакция пользователя в вакууме» на анализ «сколько выгоды можно извлечь из целого сманеного блока». Потому что шансов быть следующим после целевой транзакции очень мало. ⁃ Заметил, что из avalanchego+coreth…
#FR_BR
Каков функционал бота сейчас:
- Код бота встроен в avax state-sync ноду, а точнее в плагин coreth. Это позволяет исключить задержки на транспортировку данных от ноды до бота по rpc/ws/... о состоянии резервов пар прямо после блока.
- Так как state-sync нода в основном получает только блоки, а не pendingTransactions как bsc, то поиск арбитража сводится к поиску недоизъятого арбитража среди пар по итогу блока. Тоесть backrun бот ищет, какие еще резервы univ2 пар не сбаланисораны между собой по итогу блока, а не каждой транзакции, как возможно сделать имея fullnode валидатора.
- Попадать в тот же блок, что и потенциальная целевая транзакция невозможно с помощью state-sync ноды. Для этого нужно быть валидатором и оповещать о своем видении порядка блоков сильнее, чем это делают другие валидаторы в момент распространения блоков (если 700/1000 валидаторов за Х вариант блока, то скорее всего его и примут, где может быть нужный нам порядок транзакций)
- Транзакция бота попадает во 2-3 блок после целевой транзакции. Никак ускорить не вышло. Пробовал 2-6 разных локаций одновременно, не помогло.
- Бот жертвует 50-60% чистой прибыли на более высокую комиссию транзакции, чтобы быть раньше в блоке
- Chi токен в avax-c не котируется, не реализован частичный манибек за удаление контракта.

Финансовые показатели бота:
- Условно 10$ ушло на транзакции, 5$ заработано. ROI -50% в среднем, поднять не получилось
- Сервер aws не окупается, spot.c5.large обходится примерно в 1.2$/d

Как сэкономить на стоимости содержания state-sync ноды avalanche:
- Взять spot instance у aws и поставить в настройках "любая цена бида" и "спящий режим при нехватке ресурсов". Это снижает ежедневные затраты в 2-4 раза
- Поселить avalanchego в systemctl демона, чтобы он сам стартовал при перезапуске инстанса

Опыт получен интересный, но бота следует остановить. В нынешней реализации он не показывает признаков окупаемости.

На примере с bsc, нода может 2 месяца работать в минус но потом пара транзакций покроют большоую часть затрат. К сожалению в сети avax так не вышло.

В avax-c существуют активные backrun боты, которые попадают в тот же блок что и целевая транзакция, они извлекают 80% прибыли. А остатки извлекают боты из блоков.
InVM - изнутри о Web3
С помощью https://dune.com можно взаимодействовать с eth/bsc/matic/optimism блокчейнами через sql запросы и упаковывать в инфографики, например «прирост деплоев смарт-контрактов по месяцам». Мне сильно пригодился для того, чтобы выгрузить все адреса еth…
#EVM #DEFI
11кк abi собрано, если обогащать базу сигнатур функций, то тут на 10% больше, чем в 4byte.directory

Большинство контрактов на solidity, попадаются vyper.

Чаще всего попадаются такие опкоды для идентификации сигнатур в байткоде:
// aa bb cc dd = сигнатура
// 63 = PUSH4 означает что длина сигнатуры 4 байта (минимум 1 байт, поэтому 1+3)функции
80 63 aa bb cc dd …

или
80 62 aa bb cc …. // 62 = PUSH3
80 61 aa bb ….
80 60 aa ….

Живой пример weth (байткод внизу)
06fdde03 = name()
095ea7b3 = approve(address,uint256)
#EVM
После компиляции .sol в bytecode внутренняя структура начинается с выбора корректной функции для старта.

что-то вроде «если сигнатура X, то JUMP на Y позицию»

Следовательно, возможно обращаться к контрактам, у которых нет объявленного abi, зная их внутренние функции.

Если умеем выделять сигнатуры в коде, то можно попытаться подобрать аргументы вызова функции в слепую, наиболее распространенные transfer(address,uint256) и тд
#EVM #DEFI
Rpc запросы к evm провайдерам можно делать пачками, не один eth_call а сразу тысяча в одном запросе.

Пример curl
curl --request GET \
--url https://eth-mainnet.public.blastapi.io/ \
--header 'Content-Type: application/json' \
--data '[{"jsonrpc":"2.0","id":0,"method":"eth_blockNumber","params":[]},{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]},{"jsonrpc":"2.0","id":2,"method":"eth_blockNumber","params":[]}]'


- Важно менять ‘id’
- Максимум 1000 элементов, зависит от провайдера
- Если внутри заменить eth_blockNumber на etc_call + свой контракт, то можно повысить емкость одного запроса еще в 10-100 раз
- На один eth_call ограничение в несколько млн газа
- Гуглить список rpc api так «eth eth_call»
Celsius требовал KYC
Celsius обанкротился
Celsius опубликовал 14к данных пользователей (имя, дата, сделка) по решению суда

https://twitter.com/0xfoobar/status/1578168737529794561

Правда ли KYC так необходим повсюду?

Upd:
«требовал» и «опубликовал» связаны
«требовал» и «обранкротился» не связано, просто хронология))
Вчера вышел 8й пакет санкций ЕС, если коротко, то все биржи, которые ввели 10к евро лимит, теперь понижают этот лимит до 0

Будьте осторожны
В момент перехода eth на PoS в середине сентября, появился минимум один форк: ETHW.

Часть майнеров отказалась принимать большое обновление и их цепочка блоков отделилась от оригинального еth. Тоесть все транзакции до блока Х связаны с eth сетью, но после блока X баланс пользователей раздвоился. Если у пользователя было 1eth,100dai, то такой баланс будет в сетях ETH,ETHW.

И в первые часы существовало много арбитражных возможностей в форкнутой сети.

Например, оракл chainlink, который раз в несколько минут обновляет рыночную цену eth(нативного токена) перестал обновляться в сети ethw. Следовательно, aave и другие landing протоколы не могут корретно соотносить ценность займа и залога.

Более практичный пример, правда когда его проверял, вся ликвидность на aave уже выжата:
1. 1ethw в «реальном» мире стоил 14$, у CEX такой курс был.
2. Цена нативного токена в сети ethw от chainlink 1300$(1ethw)
3. В uniswap 1ethw=36k$

Стратегия:
1000$CEX меняем на ethw
71ethw (1000$CEX)
71*36000=2 556 000$ (ethw меняем на $ в сети ethw через uniswap)
Вносим обеспечение 2.5kk$ в aave (в сети ethw)
Так как у aave старые цены оракла, то он считает что 1ethw стоит 1300$, значит при нашем залоге в 2.5kk$ выдаст 1572ethw при 80% обеспечения.
Выводим 1572ethw на биржу, продаем по 14$, получаем 22008$CEX

Другое направление в том, чтобы нормализовать курсы обмена пар в пределах dex’ов, вероятно там есть пары, которые еще не уравновешены между собой. Задача для BR бота, с последующим выходом в ethw.

Через несколько часов после форка все токены кроме ethw стали фантиками без привязки к реальным ценам. Субъективное ощущение, что все, что позволяет получать ethw уже выжато.

Специфика подобного поиска еще в том, что никакого интерфейса нет, нужно обращаться на прямую к смарт-контрактам, а это значительно сужает порог входа.

Вероятно инициаторы форка неплохо заработали, так как хорошо понимали подобные направления.
#GETH
EstimageGas метод использует тот же инструментарий что и во время создания блоков. Только применятся меньше правил.

Общие моменты:
- берут состояние state на запрошенный блок Х
- подготавливают EVM контекст для исполнения транзакций

Разные моменты:
- EstimateGas ограничивается исполнением транзакции и взятием только GasUsed (/internal/ethapi/api.go:1056 DoEstimateGas)
- Во время создания блока исполняются все транзакции и формируется их receipt с сохранением нового состояния state. (Копать от core/state_processor.go:95 applyTransaction)

В теории возможно производить симуляцию своих транзакций *без signTransaction* и получать tx.Logs и прочие детали будто транзакция смайнена.
Давно научился ускорять процесс обработки однотипных строк процесс с помощью sublime text 3.

Основная идея в том, что вместо одного мигающего веделения, так называемой вертикальной палочки, можно сделать их несколько и писать с помощью этого в нескольких местах одну команду

Например, есть список
ip1:port1
ip2:port2
...


Нужно добавить в начало строки 'http://'
// cmd(mac) = ctrl(windows)
1. Выделить :
2.a Eсли строк несколько десятков: cmd+D столько раз, сколько : подряд нужно выделить.
2.b Если строк много, то cmd+C (скопировать ':'), cmd+F, cmd+V, ’Find all’. Выделятся все ':'
3. cmd+Home, чтобы перейти всеми выделениями максимально влево строки. Тут нужно поиграться с тем, как передвигать выделения в начало/конец строки, влево/вправо на слово. cmd,option,ctrl,alt,стрелочки,pgUp,pgDown,end.
4. Написать 'http://'

Схожим образом можно заменить . на , чтобы правильно импортировались числа в таблицу.

Cделать все в одну строку:
1. cmd+F, \n
2. Убедиться что включен поиск по regexpr (слева от окна поиска кнопка ‘.*’)
3. Find All
4. del, пробел

Для более сложных паттернов есть с регулярные выражения (regexpr).
Головоломка, почему адрес неконтракта принимает usdt, когда to=0xdAC17F958D2ee523a2206206994597C13D831ec7 (не контракт в сети bsc)

https://bscscan.com/tx/0x3ace52daa2e58ac03d45443cd593b9343b55473410e06d28e9685bcfed007223
#FULLNODE
Для запуска eth full node нужно минимум 650гб nvme

+14gb в неделю на хранение блоков/транзакций и тд, всего, что можно удалить через prune-state

По этому гайду все запустилось меньше чем за 24 часа.

Правда есть особенность, prysm’y нужно дать доверенный источник, чтобы быстрее пошла синхронизация. Без = 20 блоков в секунду. С = 50+ блоков в секунду.

Пример запуска prysm+geth

Для ускорения синхронизации:
./prysm/prysm.sh beacon-chain --execution-endpoint=$HOME/.ethereum/geth.ipc --block-batch-limit 1024 --checkpoint-block 15815920 --checkpoint-sync-url https://beaconstate.ethstaker.cc

Выбрать ссылку отсюда
#FULLNODE
Существует способ запустить bsc full node и занять от 350гб (сам state) с помощью снапшота от bnb48

официальный снапшот

bnb48 снапшот (Скорость скачивания получалась 400Мб/с), на весь запуск потребовалась пара часов

В общих чертах нужно:
- Запустить скачивание и разархивирование снапшота одной командой
- Скачать/скомпилировать geth и его mainnet.toml
- На основе команды запуска geth от bnb48, обновить datadir и запустить.
#DEFI
Как мы все знаем, в bsc минимальный gasPrice = 5gwei.

Но отдельный валидатор, если захочет, может принимать транзакции с 1gwei.

Идея в том, что пользователю нужно купить токен 1KOGE=11$.
1KOGE = 240000 gasLimit максимум.
Рост gasLimit от количества koge нелинейный, детали в офф чате.

Имея 1koge и установив их rpc link можно отправлять сколько угодно транзакций с 1gwei и до 240000gasLimit.

Пост-релиз в офф чате
InVM - изнутри о Web3
#GETH EstimageGas метод использует тот же инструментарий что и во время создания блоков. Только применятся меньше правил. Общие моменты: - берут состояние state на запрошенный блок Х - подготавливают EVM контекст для исполнения транзакций Разные моменты:…
#GETH #FLASHBOTS
Перед отправкой бандла в flashbots, нужно произвести симуляцию бандла и убедиться что все транзакции будут исполнены без ошибок. Пример

Внутри это устроено так, что запущен форк geth под названием mev-geth внутри которого есть среди прочего метод симуляции бандла eth_callBundle, который последовательно виртуально исполняет транзакции, давая максимально реалистичный ответ, если бы тоже самое выполнить в mainnet без конкуренции.

Что нужно сделать, чтобы получить аналогичный метод симуляции в собстенной ноде geth?
- Простой ответ: запустить mev-geth и подружить с консенсус-клиентом
- Сложный ответ: нужно зарегистрировать кастомный namespace и дополнить внутренние методы.
По шагам:
1. В GetAPIs нужно передавать два аргумента, и тут
2. Регистрируем свой api-namespace с префиксом eth_ и добавляем прием двух аргументов
3. Определяем апи метод CallBundle
4. Дополнить внутренние методы исполнения транзакций, чтобы получать еще и receipt. Раз, Два

Думаю, что blocknative взял за основу callBundle и предлагает 300 симуляций (Simulations, Simulation Bundle Size) за всего-лишь 100$/mo
InVM - изнутри о Web3
#HACK Вероятный вектор обхода блокировки на продажу до роста цены: Контекст: 1. Так как пара токена добавлена в исключения, она всегда отправляет мгновенно, потому что все пользователи могут покупать много раз (пара отправляет токены к пользователю) 2. Как…
Сейчас идет спам-рассылка что нужно срочно покупать sui(bsc) убийца aptos’a в первые часы иксы все дела.

Но продать никто кроме админов не сможет.

И находятся люди, кто покупает: https://dexscreener.com/bsc/0xa71832bc3743e7453317a714ddfcfb0383e5f688 , не ловите FOMO)

На втором фото, if _to == unknown… это проверка на то, чтобы не позволять указать получателя pancakeswap.pair с ликвидностью sui*-busd. Покупать можно без проблем этот скам, но продать нельзя