Solidity. Смарт контракты и аудит
2.63K subscribers
247 photos
7 videos
18 files
557 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Подборка статей для самообучения - 1

Еще небольшая подборка из различных источников, которая идеально подходит для неспешного самообучения. Можно брать по одному источнику в день и продвигаться вместе с каналом.

1. Выпущена новая версия Sol2Uml v2.5.0, которая позволяет, вроде как, читать слоты памяти в публичных контрактах.

2. Побитовые операции в Assembly. Простая и полезная статья от одного из крутых разработчиков 0xWeiss. В аудитах я все чаще встречаю участки кода, где используются сдивиги и маскирование? (masking), поэтому хорошо бы разбираться в этом.

3. Как разбить строку в Solidity на насколько линий. Даже не могу представить случай, когда это может потребоваться, но, возможно, вам будет интересно просто прочитать про то, как разработчик решил эту проблему для себя.

4. Немного о стандарте EIP712, работа с подписями. Все больше багов и уязвимостей находится в не правильной работе с подписями в контрактах. Эта статья простым языком старается объяснить принципы работы.

5. Как работает ECDSA. Техническая статья о работе библиотеки. Очень много формул, расчетов и подробностей. Возможно, будет интересна тем, кто познает шифрование.

6. Все о стеке и памяти. Популярная и мега полезная статья о работе памяти в языке. Понять все нюансы можно, только прочитав ее несколько раз.

7. Пост про MEV. О ней сказать ничего не могу, так как еще очень давно сохранил ее и даже не просмотрел. Ее рекомендовал pashov в своем блоге.

8. Хорошая статьи от Officer CIA об AAVE v3. Там же можно найти ссылки по подобным постам про Convex, Curve V1, Balancer V1 и много чего еще. Простое и понятное объяснение многих моментов.

Если некоторые статьи у вас не будут открываться, то попробуйте использовать VPN.

В комментариях можете поделиться своими статьями и постами, которые рекомендуете к прочтению другим участникам. 

#scope #eip712 #mev #ecdsa #aave #bit #sol2uml
5👍2🔥2
Больше о побитовых операциях

На днях в одном из конкурсных аудитов встретил следующий код:

function hasBeenDistributed(uint256 _index) public view returns (bool) {

    uint256 distributedWordIndex = _index / 256;
    uint256 distributedBitIndex = _index % 256;
    uint256 distributedWord = distributedBitMap[distributedWordIndex];
    uint256 mask = (1 << distributedBitIndex);

    return distributedWord & mask == mask;
}

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

Если для вас предельно понятны функции в тестовом примере и на скрине поста, то, поздравляю, с побитовыми операциями у вас все в порядке. Если же нет, то следующие три статьи прольют больше света на этот вопрос.

Статьи на английском языке, но время на них стоит потратить, чтобы хорошо разобраться.

Во-первых, читаем эту статью на Медиум.

Потом читаем пост с Solidity Developer. Спасибо @SovaSlava, что показал мне ее.

И в конце, получаем небольшой разбор с операциями со скрина.

Надеюсь, после этого вам, как и мне, станет более понятна логики таких действий.

#bitmap #bit
👍8
Побитовые в Chainlink

На этой неделе заканчивается конкурсный аудит в Chainlink. И в одном из контрактов были использованы побитовые операции, которые я и хочу сегодня разобрать с вами.

Вообще, побитовые операции отдельная моя боль. Я пока что еще не научился понимать их на интуитивном уровне, и каждый код с ними занимает некоторое время, чтобы полноценно понимать его работу.

Контракты конкурсного аудита можно посмотреть тут, а тут ссылка на контракт и функцию из примера.

Итак, посмотрим на функцию с побитовой операцией:

  function _updateStakerHistory(
Staker storage staker,
uint256 latestPrincipal,
uint256 latestStakedAtTime
) internal {
staker.history.push(
s_checkpointId++,
(uint224(uint112(latestPrincipal)) << 112) | uint224(uint112(latestStakedAtTime))
);
}

s_checkpointId - это просто уникальный идентифкатор для ведения учета, который увеличивается на +1 при каждом вызове функции.

(uint224(uint112(latestPrincipal)) << 112) - сначала значение latestPrincipal уменьшается до uint112, а затем увеличивается до uint224, для того чтобы вместить значение для операции сдвига влево.

uint224(uint112(latestStakedAtTime)) - берем значение latestStakedAtTime и также приводим его к uint112 в начале, и к uint224 позже.

Побитовая операция OR (вот эта палочка - "|" между значениями) служит для объединения ранее сдвинутого latestPrincipal со latestStakedAtTime.

В результате получается, что latestPrincipal занимает верхние 112 бит, а latestStakedAtTime - нижние 112 бит.

Для себя и тех, кто забыл, напомню, как работает побитовое OR (ИЛИ).

Допустим у нас есть два значения:

а 1011010101
b 0111010111

Если хотябы одно значение будет равно "1", то и результат будет равен "1". Отсюда получаем:

с 1111010111

Т.е. вы поняли теперь как работает функция в chainlink? Мы берем значение, обрезаем его до uint112 и тут же увеличивает до uint224, освобождая место при помощи сдвига влево (<<) для другого значения, которое мы и записываем на освободившееся пространство.

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

Прекрасное компактное решение от команды Chainlink!

#bit #or #shift
👍4🔥3