Вопросы на собеседовании: Блокчейн-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Middle.
Смотреть пример резюме: Блокчейн-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
При reentrancy внутри одной функции повторно вызывается та же точка входа, а при reentrancy между функциями вызывается другая функция, зависящая от того же незавершенного состояния.
- В первом случае callback повторно вызывает, например, withdraw до завершения обновления баланса.
- Во втором случае callback входит в другую точку, например transfer или borrow, которая читает тот же баланс или лимит.
- Блокировка только withdraw не защищает transfer, если обе функции зависят от инварианта, который первый вызов еще не восстановил.
- Границей анализа безопасности служит общий инвариант всех внешних точек входа, а не тело одной функции отдельно.
Зачем это спрашивают: Интервьюер проверяет, умеет ли кандидат рассуждать об общем состоянии за пределами классического примера с рекурсивным выводом средств.
При cross-contract reentrancy callback переходит в другой контракт, а при read-only reentrancy наружу попадает временное значение без прямой записи в уязвимое состояние.
- В cross-contract пути контракт A вызывает внешний контракт, тот вызывает контракт B, а B читает или меняет состояние, связанное с A.
- Мьютекс в A не защищает B автоматически, потому что у контрактов разное хранилище и общий инвариант может контролироваться по-разному.
- При read-only reentrancy callback запрашивает view-функцию вроде getPrice, когда одно поле учета уже обновлено, а другое еще содержит старое значение.
- Модификатор view запрещает записи в состояние через эту функцию, но не гарантирует, что возвращаемое значение соответствует согласованному моменту транзакции.
Зачем это спрашивают: Интервьюер хочет увидеть, понимает ли кандидат, что reentrancy может пересекать границы контрактов и искажать не только записи, но и наблюдаемые значения.
Checks-effects-interactions сокращает окно для callback, а ReentrancyGuard блокирует повторный вход в защищенные пути, но ни один из механизмов не доказывает безопасность целиком.
- CEI сначала проверяет входные данные, затем фиксирует все связанные изменения учета и только после восстановления инварианта делает внешние вызовы.
- ReentrancyGuard использует мьютекс в хранилище и отклоняет второй вход в функцию с тем же guard во время первого вызова.
- CEI применен не полностью, если одно поле обновлено, а связанные поля или состояние другого контракта перед взаимодействием остаются несогласованными.
- Guard не покрывает незащищенные точки входа, хранилище другого контракта или несогласованные значения, доступные через view-функции.
Зачем это спрашивают: Интервьюер оценивает, воспринимает ли кандидат распространенные средства защиты как механизмы с ограниченной областью действия, а не универсальные исправления reentrancy.
Перевод ERC-777 может выполнить код хука отправителя или получателя, поэтому операция с токеном также передает управление наружу.
- Хук tokensToSend запускается до изменения токен-балансов, а tokensReceived после него, поэтому хуки получают разные точки для callback.
- Хук получателя может снова вызвать интегрирующий протокол до завершения его собственного учета депозита, вывода или награды.
- Контракт, принимающий произвольные ERC-20-совместимые активы, не может считать, что transfer или transferFrom никогда не вызывает callback.
- SafeERC20 обрабатывает совместимость вызовов и возвращаемых значений, но не блокирует хуки, поэтому по-прежнему нужны CEI и подходящие по области действия reentrancy guards.
Зачем это спрашивают: Интервьюер проверяет, распознает ли кандидат переводы токенов как потенциально враждебные внешние вызовы, а не простые обновления баланса.
Спотовая цена DEX отражает текущие резервы пула, которые атакующий может временно исказить ликвидностью, занятой на одну транзакцию.
- Флеш-займ дает достаточно капитала для крупной сделки с пулом без необходимости заранее владеть этим капиталом.
- Если протокол считывает измененное соотношение резервов до обратной сделки атакующего, он может неверно оценить залог, доли или обмен.
- Атакующий может закрыть позицию и вернуть заем в той же транзакции, поэтому прибыль должна лишь превысить влияние на цену, комиссии пула, газ и комиссию флеш-займа.
- Поэтому один мгновенный quote из одного пула слабее средневзвешенного по времени или независимого агрегата с проверками ликвидности и отклонения.
Зачем это спрашивают: Интервьюер проверяет, связывает ли кандидат атомарную ликвидность, изменяемые резервы AMM и небезопасное использование оракула.
TWAP усредняет цены за временное окно, заставляя атакующего поддерживать искажение дольше ценой более медленной реакции на реальные движения рынка.
- Манипуляция несколькими наблюдениями или блоками обычно требует больше капитала и подвергает атакующего риску арбитража между блоками.
- Более длинное окно повышает эту нагрузку, но заставляет оракул запаздывать при настоящих резких изменениях цены.
- Стоимость атаки также зависит от глубины пула, частоты наблюдений и возможности влиять на последовательные блоки, а не только от длины окна.
- Источник с низкой ликвидностью или активностью все равно может быть дешевым для манипуляции, потому что усреднение слабых наблюдений не создает ликвидность.
Зачем это спрашивают: Интервьюер хочет услышать и об экономической защите временного усреднения, и о ее ограничениях по задержке и ликвидности.
При sandwich-атаке атакующий торгует до и после ожидающего swap, чтобы забрать движение цены, разрешенное жертвой через допустимое проскальзывание.
- Атакующий видит swap жертвы в публичном mempool и отправляет перед ним сделку в том же направлении, чтобы сдвинуть цену пула.
- Затем сделка жертвы исполняется по худшей цене, пока результат удовлетворяет minAmountOut или maxAmountIn.
- После жертвы атакующий совершает обратную сделку и оставляет себе разницу цен за вычетом комиссий пула и стоимости транзакций.
- Более свободный slippage дает больше пространства для извлечения, строгие лимиты могут вызвать revert, а приватная отправка скрывает транзакцию от публичных поисковиков.
Зачем это спрашивают: Интервьюер проверяет понимание порядка транзакций, влияния сделок на цену AMM и проскальзывания как ограничения для атакующего.
Администратор роли может выдавать и отзывать эту роль, поэтому контроль над ролью администратора может быть сильнее прямого членства в управляемой роли.
- В OpenZeppelin AccessControl роль DEFAULT_ADMIN_ROLE по умолчанию администрирует все роли и сама является своим администратором.
- Поэтому компрометация одного ключа default admin позволяет выдать роли для минта, апгрейда, паузы или управления казначейством, даже если соответствующие рабочие ключи не пострадали.
- Самоуправляемые роли, циклы администрирования и отсутствие пути отзыва могут неожиданно усложнить удаление привилегий или восстановление доступа.
- Отделение рабочих ролей от администратора под multisig или timelock и двухэтапная передача администрирования снижают риск эскалации через один ключ.
Зачем это спрашивают: Интервьюер оценивает, прослеживает ли кандидат полный граф привилегий, а не только модификаторы бизнес-функций.
delegatecall исполняет байткод другого контракта с адресом, балансом и хранилищем вызывающего контракта, сохраняя его текущие msg.sender и msg.value.
- Чтение и запись хранилища идут по сырым слотам вызывающего контракта, поэтому layout прокси и имплементации должен оставаться совместимым.
- address(this) указывает на вызывающий контракт, а внешние вызовы из делегированного кода исходят от него с его полномочиями и активами.
- Недоверенный или некорректно обновленный код может перезаписать слоты владельца или имплементации, изменить произвольное состояние или перевести активы вызывающего контракта.
- delegatecall дает переиспользование кода, а не изоляцию, поэтому проверка имплементации и защита инициализации и апгрейдов входят в его границу безопасности.
Зачем это спрашивают: Интервьюер проверяет, понимает ли кандидат, почему прокси на основе delegatecall наследуют риски layout хранилища и доверия к имплементации.
Подпись можно использовать повторно, если контракт проверяет подписанные данные, но не привязывает их к одному использованию и одному домену исполнения.
- Replay в том же контракте возникает, когда принятые данные можно отправлять многократно из-за отсутствия nonce или проверки уже использованного digest.
- Cross-chain replay возникает, когда та же подпись действительна в другом деплое, потому что подписанный домен не содержит идентификатор сети.
- Контракт должен проверить и использовать signer-specific nonce или digest до внешних вызовов, а для ограниченного по времени разрешения также проверять deadline.
- Домен EIP-712 с chainId и verifyingContract разделяет сети и контракты, а подписанная структура привязывает разрешение к конкретному действию, получателю и сумме.
Зачем это спрашивают: Интервьюер проверяет, знает ли кандидат, что валидность подписи сама по себе не обеспечивает уникальность или разделение доменов.
Прокси перенаправляет вызов через delegatecall, поэтому код реализации работает с состоянием прокси.
- Fallback-функция прокси передаёт исходный calldata по адресу реализации и не делает обычный внешний вызов.
- Во время выполнения address(this), хранилище и баланс ETH принадлежат прокси, поэтому запись состояния меняет слоты прокси.
- delegatecall сохраняет исходные msg.sender и msg.value, поэтому контроль доступа в реализации видит настоящего вызывающего.
- Прокси возвращает returndata реализации или передаёт вызывающему данные её revert без изменений.
Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы, что реализация предоставляет код, а прокси предоставляет адрес, хранилище, баланс и контекст вызова.
EIP-1967 задаёт для метаданных прокси стандартные слоты хранения, которые почти не могут пересечься с переменными реализации.
- Слот реализации вычисляется как bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1), и OpenZeppelin использует именно эту константу.
- Стандарт аналогично задаёт отдельные слоты для администратора прокси и beacon, хотя конкретный паттерн может использовать не все три.
- Блокчейн-обозреватели и клиенты могут читать известные слоты через eth_getStorageAt без getter-функции прокси.
Зачем это спрашивают: Сильный ответ связывает детерминированные слоты с предотвращением коллизий, совместимостью и инспекцией, а не принимает EIP-1967 за алгоритм обновления.
Transparent-прокси выбирает между обработкой обновления и fallback-вызовом реализации по адресу вызывающего.
- Любой вызов не от администратора делегируется реализации, даже если его селектор совпадает с upgradeToAndCall.
- Администратор может вызвать только upgradeToAndCall; любой другой его вызов завершается ошибкой ProxyDeniedAdminAccess и не доходит до реализации.
- В OpenZeppelin 5.x каждый прокси разворачивает отдельный ProxyAdmin, начальный владелец которого передаётся в конструктор прокси.
Зачем это спрашивают: Интервьюер проверяет знание правила прозрачности по адресу отправителя и актуальной схемы ProxyAdmin в OpenZeppelin 5.x.
UUPS размещает логику обновления в реализации и использует proxiableUUID, чтобы отклонять реализации с несовместимым слотом хранения.
- upgradeToAndCall выполняется через прокси с модификатором onlyProxy, который проверяет контекст delegatecall и то, что прокси сейчас указывает на эту реализацию.
- Переопределённая в реализации функция _authorizeUpgrade должна разрешить вызывающего до изменения слота реализации.
- Обновление вызывает proxiableUUID у новой реализации и требует слот реализации EIP-1967; сам proxiableUUID использует notDelegated, чтобы запретить вызовы через прокси.
Зачем это спрашивают: Сильный ответ разделяет авторизацию вызывающего и проверку совместимости ERC-1822, а также понимает, где выполняется код обновления UUPS.
Transparent-прокси размещает диспетчеризацию обновления в прокси, а UUPS размещает её в каждой обновляемой реализации.
- TransparentUpgradeableProxy разворачивает отдельный ProxyAdmin и содержит диспетчеризацию по отправителю, поэтому его развёртывание дороже, чем у обычного ERC1967Proxy.
- В UUPS прокси остаётся небольшим, но каждая новая реализация должна сохранять правильную авторизацию обновления и совместимость с ERC-1822.
- Transparent-диспетчеризация не даёт администратору случайно вызвать функцию реализации, а в UUPS нет отдельного правила fallback для администратора.
Зачем это спрашивают: Интервьюер проверяет, можете ли вы сравнить расположение кода, стоимость развёртывания, интерфейс управления и ответственность за авторизацию, не объявляя один паттерн всегда лучшим.
Конструктор инициализирует собственное хранилище реализации, поэтому состояние прокси нужно настраивать через защищённый инициализатор, выполненный с delegatecall.
- Инициализатор использует версию 1 и обычно выполняется в контексте хранилища прокси только один раз.
- Передача закодированного вызова инициализатора в конструктор прокси объединяет развёртывание и инициализацию в одну атомарную транзакцию.
- Reinitializer с более высокой версией настраивает состояние, добавленное последующим обновлением, причём каждую версию можно использовать лишь один раз.
- Reinitializer нельзя вкладывать друг в друга, а порядок вызовов унаследованных инициализаторов нужно задавать вручную, чтобы не инициализировать родителя дважды.
Зачем это спрашивают: Интервьюер проверяет понимание отдельного хранилища прокси, версионированной инициализации и обязанностей при наследовании.
_disableInitializers навсегда блокирует состояние инициализации реализации, чтобы никто не мог захватить этот отдельно развёрнутый контракт.
- OpenZeppelin устанавливает версию инициализации в максимальное значение uint64, поэтому последующие вызовы initializer и reinitializer завершаются ошибкой.
- Обычно функция вызывается в конструкторе реализации, поэтому меняет хранилище реализации, а не хранилище прокси.
- Прокси остаётся доступным для инициализации, поскольку delegatecall читает и меняет его отдельный слот инициализации.
- Такая блокировка не заменяет быструю инициализацию прокси, которую лучше выполнить через calldata конструктора в той же транзакции развёртывания.
Зачем это спрашивают: Сильный ответ отличает блокировку реализации от инициализации прокси и объясняет, почему нужны оба действия.
Обновление должно сохранить каждый существующий слот, потому что новая реализация интерпретирует состояние, уже записанное в прокси.
- Нельзя менять порядок, удалять или менять тип существующих переменных состояния; новые переменные добавляют только после совместимого существующего layout.
- Линеаризация наследования Solidity влияет на порядок слотов, поэтому перестановка базовых контрактов или вставка переменных в базовый контракт может сдвинуть хранилище потомков.
- Зарезервированные слоты __gap позволяют позже добавлять переменные в унаследованный контракт, уменьшая gap на то же число занятых слотов.
- Обновляемые контракты OpenZeppelin 5.x используют изолированное хранилище ERC-7201, чтобы снизить риск коллизий при наследовании, но layout каждого namespace всё равно должен оставаться совместимым и проходить проверку.
Зачем это спрашивают: Интервьюер проверяет, воспринимаете ли вы хранилище прокси как постоянную схему и учитываете ли не только собственные, но и унаследованные переменные.
Паттерн Transparent разрешает коллизии селекторов прокси и реализации по сочетанию селектора и статуса администратора у вызывающего.
- Селектор состоит только из первых четырёх байтов хеша сигнатуры функции, поэтому разные сигнатуры могут иметь одинаковый селектор.
- Вызов не от администратора всегда делегируется, включая вызов с селектором upgradeToAndCall, поэтому функция реализации остаётся доступной пользователям.
- Вызов администратора попадает только в обработчик обновления прокси, а с любым другим селектором завершается ошибкой без fallback в реализацию.
- OpenZeppelin не рекомендует добавлять внешние функции в TransparentUpgradeableProxy, поскольку новая функция может перекрыть неявный селектор обновления и сделать обновления недоступными.
Зачем это спрашивают: Сильный ответ объясняет и четырёхбайтовую коллизию, и причину, по которой прозрачная диспетчеризация зависит не только от селектора, но и от адреса отправителя.
Паттерн прокси определяет место проверки авторизации, а timelock может заставить разрешённое обновление ждать в течение публично известной задержки.
- В UUPS авторизация делегируется функции _authorizeUpgrade, которую обычно защищают onlyOwner или отдельной ролью.
- Обновления Transparent авторизует владелец ProxyAdmin, поэтому владельцем может быть governance-контракт, а не отдельный аккаунт.
- TimelockController разделяет роли proposer, executor и canceller и требует, чтобы запланированная операция выдержала минимальную задержку до исполнения.
- Timelock ограничивает, кто и когда может обновлять контракт, но не доказывает совместимость хранилища или корректность реализации, для которых всё равно нужна техническая проверка.
Зачем это спрашивают: Интервьюер проверяет, разделяете ли вы полномочия на обновление, отложенное governance-исполнение и проверки безопасности реализации.
Закрытые вопросы
- 21
Как ERC-4626 описывает конвертацию между активами и долями хранилища?
secrets - 22
Какие направления округления ERC-4626 требует от функций конвертации и preview?
- 23
Почему пустое хранилище ERC-4626 уязвимо для inflation-атаки через donation?
vulnerabilitiessecrets - 24
Как виртуальные доли, виртуальные активы и смещение decimals снижают риск donation-атак в текущих контрактах OpenZeppelin ERC-4626?
- 25
Чем балансы, разрешения и пакетные операции ERC-1155 отличаются от моделей с одним типом токена?
batchtokens - 26
Какие receiver hooks требует ERC-1155 и почему они создают границу reentrancy?
hookstokensreentrancy - 27
Как процесс ERC-2612 permit создаёт allowance ERC-20 без транзакции approve от владельца?
tokenstransactions - 28
Как семантика nonce и deadline ограничивает повторное использование ERC-2612 permit?
estimationtransactions - 29
Как строятся domain separator и итоговый digest типизированных данных EIP-712?
- 30
Как ERC-1271 стандартизирует проверку подписей контрактных аккаунтов?
validation - 31
Как Solidity назначает слоты хранения статическим полям состояния?
storagesolidsolidity - 32
Как вычисляется слот хранения значения в mapping Solidity?
soliditydata-structuressolid - 33
Как динамические массивы, bytes и string представлены в хранилище Solidity?
data-structuressoliditysolid - 34
Какими компромиссами следует руководствоваться при упаковке хранилища EVM-контракта?
evm - 35
Как разработчику рассуждать о холодном и теплом SLOAD, а также о текущей стоимости и возвратах SSTORE?
- 36
Почему расширение памяти EVM имеет квадратичную составляющую стоимости?
componentsmemoryevm - 37
Как ABI-кодирование и нулевые либо ненулевые байты влияют на стоимость calldata?
data-location - 38
Какой жизненный цикл и варианты применения дает временное хранилище EIP-1153?
- 39
Как topics, data и bloom-фильтры логов влияют на проектирование и индексацию событий?
indexesdesign - 40
Из каких основных частей состоит subgraph в The Graph и как его индексация должна учитывать реорганизации цепочки?
indexes - 41
Что должен проверить контракт перед использованием значения, полученного из Chainlink Data Feed через latestRoundData?
oracles - 42
Почему потребители Chainlink Data Feed обычно обращаются к адресу прокси, а не напрямую к текущему агрегатору?
proxyupgradeabilityoracles - 43
Почему для распределения Ether или токенов между многими получателями стоит использовать паттерн pull-over-push?
tokens - 44
Чем отличаются CREATE и CREATE2 при развертывании контрактов фабрикой и что делает адрес CREATE2 детерминированным?
deployment - 45
Что такое минимальный прокси-клон EIP-1167 и как инициализация может сделать клоны небезопасными?
proxyupgradeability - 46
Как задать полезные области входных данных для fuzz-тестов Foundry и исследовать контрпример?
foundry - 47
Как handlers и ghost state помогают организовать invariant-тест в Foundry?
foundry - 48
В чем базовое различие optimistic- и ZK-роллапов с точки зрения доверия и финальности?
lockinglayer2 - 49
Какую роль на L2 играют sequencer, доступность данных и финальность L1 и как используется Chainlink Sequencer Uptime Feed?
oracles - 50
Как проходит жизненный цикл сообщения в каноническом мосте lock-and-mint, включая обратный путь и основные проверки?
validationbridges - 51
Как преобразовать контракт с конструктором в реализацию UUPS?
- 52
Как авторизовать обновления UUPS через роли и timelock?
- 53
В обновляемый контракт нужно добавить состояние. Как сделать это без поломки storage layout?
upgradeability - 54
После обновления прокси с плохим layout состояние выглядит поврежденным. Как провести диагностику и восстановление?
proxyupgradeability - 55
Как инициализировать состояние, добавленное во второй версии UUPS-контракта?
- 56
Как развернуть UUPS-прокси, чтобы ни реализацию, ни прокси нельзя было захватить во время инициализации?
proxyupgradeabilitydeployment - 57
Команда безопасности платформы должна владеть обновлениями, а несколько продуктовых команд выпускать реализации без кода обновления. Вы выберете Transparent или UUPS прокси?
- 58
Как проверить совместимость хранилища перед обновлением с помощью инструментов OpenZeppelin upgrades?
validation - 59
Как отрепетировать обновление прокси и доказать, что старое состояние и поведение сохранились?
proxyupgradeability - 60
Вызов обновления Transparent-прокси завершается ошибкой, а бизнес-вызов по пути администратора не доходит до реализации. Как это отлаживать?
proxyupgradeability - 61
Vault защищает withdraw от reentrancy, но вредоносный получатель повторно входит через transferCollateral и дважды расходует один и тот же залог. Как исправить и протестировать общий инвариант?
secretsreentrancy - 62
Во время withdrawal из vault callback видит завышенную цену доли после уменьшения supply, но до уменьшения учтенных активов, а затем использует эту цену в lending-протоколе. Как исправить этот путь read-only reentrancy?
secretsreentrancycallbacks - 63
Lending market использовал текущее соотношение резервов одного AMM как oracle для залога, и атакующий через flash loan завысил стоимость залога на одну транзакцию. Чем заменить этот источник и как проверить замену?
oraclesdefitransactions - 64
Пользователей вашего swap router атакуют sandwich-транзакциями, потому что swaps допускают amountOutMin, равный нулю, и остаются действительными час. Как ограничить потери, не обещая полного устранения MEV?
transactions - 65
Аудит AccessControl показал, что один EOA деплоера имеет DEFAULT_ADMIN_ROLE и может выдавать роли minting, upgrading, pausing и treasury. Как исправить admin graph и обеспечить least privilege?
least-privilegedeployment - 66
Подпись EIP-712 для withdrawal через relayer можно отправить повторно, и она также работает в копии контракта в другой сети. Как сделать каждую авторизацию уникальной, ограниченной доменом и сроком?
auth - 67
Wallet позволяет пользователю передать любой адрес plugin в delegatecall, и вредоносный plugin перезаписывает slot владельца и выводит активы. Как изменить границу plugin-системы?
delegationwallets - 68
Settlement contract отмечает ордер оплаченным после target.call(data), не проверяя success flag, поэтому неудачная выплата оставляет завершенный учет. Как сохранить атомарность?
concurrency - 69
ERC-1155 marketplace уменьшает inventory листинга только после safeTransferFrom, поэтому контракт покупателя повторно входит через onERC1155Received и снова покупает те же единицы. Как защитить учет?
tokens - 70
Модуль залога считает 8-знаковую цену Chainlink 18-знаковой, занижает стоимость одного актива в 10 миллиардов раз и ломает liquidation thresholds. Как исправить и протестировать scaling?
scalingoracles - 71
Распределитель выручки отправляет Ether 8 000 получателям в одной транзакции, и теперь вызов превышает лимит газа блока или откатывается из-за одного вредоносного получателя. Как бы вы изменили архитектуру?
transactionsgaserror-handling - 72
Обновляемому прокси нужны новые поля treasury, settlementEpoch и feeBps, а предложенный патч переставляет старые переменные ради упаковки. Как сократить стоимость нового хранилища и не повредить прокси?
proxyupgradeability - 73
Горячий путь settleAccount несколько раз читает один и тот же баланс аккаунта и общий итог, а также записывает промежуточные значения, которые перезаписываются до возврата. Что бы вы изменили?
- 74
Внешняя функция quoteBatch принимает большой массив структур в memory, только проверяет и читает его, а стоимость быстро растет с размером пакета. Как бы вы оптимизировали путь данных?
optimizationmemorybatch - 75
Платежный контракт навсегда сохраняет каждую историческую структуру Payment, но историю использует только продуктовый дашборд, а логике возврата нужны текущие итоги и статус получения. Что должно остаться on-chain?
- 76
Массив members сканируется при каждой проверке прав, а удаление сдвигает все следующие элементы, поэтому обе операции становятся слишком дорогими. Как обеспечить поиск и удаление за постоянное время?
auth - 77
finalizeEpoch теперь обновляет десятки тысяч позиций и больше не может завершиться в одном блоке. Как сделать переход состояния возобновляемым и не обработать аккаунты дважды?
concurrency - 78
Часто вызываемый протокол использует reentrancy guard в постоянном storage, а все целевые сети теперь поддерживают EIP-1153. Как перейти на transient guard и доказать, что multicall остается композируемым?
decision-makingtypingreentrancy - 79
Путь execute в необновляемом router стоит дороже ожидаемого, а ревью предлагает custom errors, immutables и широкие блоки unchecked. Как бы вы выбрали и применили оптимизации?
upgradeabilityoptimizationimmutability - 80
Отправитель пакетов в L2 тратит большую часть комиссии на публикацию данных транзакции в L1, а каждый элемент сейчас занимает стандартные ABI-слова. Как уменьшить calldata и не создать небезопасный decoder?
batchtransactionsdata-location - 81
Вы подключаете фид Chainlink ETH/USD к контракту залога. Какие проверки и нормализацию вы выполните перед возвратом цены с 18 знаками после запятой?
normalizationoracles - 82
Lending-контракт с ценами Chainlink разворачивают в Arbitrum. Как вы добавите Sequencer Uptime Feed и льготный период после восстановления?
oraclesdeployment - 83
У вас есть фид TOKEN/ETH с 18 знаками и ETH/USD с 8 знаками. Как вычислить TOKEN/USD с 18 знаками без потери точности и переполнения?
tokens - 84
Основной оракул устарел, пока у пользователей открыты позиции в lending-протоколе. Какое fail-closed или fallback-поведение вы выберете?
oracles - 85
Как вы реализуете OpenZeppelin ERC4626 vault с ERC-20 стратегией, не нарушив учет стандарта?
secretstokens - 86
Как вы настроите и протестируете актуальный OpenZeppelin ERC4626 vault против inflation-атаки на пустой vault?
secretsconfig - 87
Продукт просит принимать в vault токены с комиссией при переводе и ребейзинг-токены. Что вы будете поддерживать?
tokenssecrets - 88
Donation может изменить курс ERC4626 между preview пользователя и исполнением. Как ограничить проскальзывание и не нарушить округление стандарта?
- 89
Какие fuzz-свойства Foundry вы напишете для deposit и redeem в ERC4626 vault?
secretsfoundry - 90
Как построить invariant handler Foundry для ERC4626 vault, если базовый актив также можно передавать напрямую как donation?
secretsfoundry - 91
Продакшен-транзакция попала в блок со status 0, но кошелек не показывает причину, а тот же вызов проходит на последнем блоке. Как найти точную причину сбоя до предложения исправления?
walletstransactions - 92
Трасса вызова через proxy возвращает 0x8e4a23d6000000000000000000000000... вместо читаемой причины, и команда считает это Error(string). Как безопасно определить реальную ошибку?
proxyupgradeability - 93
Swap падает только в mainnet на блоке 22 450 100, тогда как локальные mocks и fork последнего блока проходят. Как построить детерминированное воспроизведение, полезное и после изменения состояния сети?
mocking - 94
После рефакторинга все тесты проходят, но gas для executeOrder вырос со 118 000 до 151 000, а автор считает это шумом optimizer. Как найти и оценить регрессию с помощью Foundry?
optimizationgastesting - 95
Release script готов к запуску в L2, но его RPC называется production, у deployer есть ETH в нескольких сетях, а команда собирается ждать двенадцать подтверждений как в L1. Что вы проверите и настроите до deployment?
deploymentconfig - 96
UUPS proxy успешно развернут, но explorer показывает только bytecode proxy, чтения через proxy падают, а implementation address никто не пытался верифицировать. Как исправить и проверить deployment?
proxyupgradeabilitydeployment - 97
Команда хочет получить один CREATE2 address в Ethereum и двух L2, но расчетные адреса различаются, хотя все scripts используют одинаковый salt. Как спроектировать и проверить multichain deployment?
designethereumdeployment - 98
Frontend с production wallet отправляет approvals тестовому deployment, потому что environment variable содержала правильный ABI, но неверный address. Какие защиты вы добавите в clients и deployment scripts?
deploymentconfigwallets - 99
Bridge deposit финален в source chain, но через два часа отсутствует в destination, и оператор предлагает повторно отправить тот же payload. Как диагностировать проблему, не выполнив уже доставленное message дважды?
bridges - 100
Explorer сообщает о несовпадении deployed bytecode при verification, хотя source выглядит одинаково, и коллега предлагает менять flattening, пока проверка не пройдет. Как устранить mismatch и когда Sourcify подходит как fallback?
deployment