Solidity. Смарт контракты и аудит – Telegram
Solidity. Смарт контракты и аудит
2.62K subscribers
246 photos
7 videos
18 files
547 links
Обучение Solidity. Уроки, аудит, разбор кода и популярных сервисов
Download Telegram
Архитектура Uniswap V2

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

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

В ее основе лежит контракт UniswapV2Pair, в котором хранятся два токена ERC20. Через него трейдеры могут менять токены один на другой, а поставщики ликвидности - предоставлять эти самые токены.

Для каждой возможной пары UniswapV2Pair существует свой одноименный контракт, который управляет ею. Если нужный контракт UniswapV2Pair не существует, новый может быть создан из контракта UniswapV2Factory.

Контракты UniswapV2Pair также являются токенами ERC20 (и наследуют от ERC20). Этот токен используется для отслеживания депозитов аналогично тому, как работает ERC4626.

Хотя продвинутые трейдеры или смарт-контракты могут напрямую взаимодействовать с контрактом пары, большинство пользователей будут взаимодействовать с токенами через контракт Router, который имеет несколько удобных функций, например, торговля между парами в одной транзакции и создание «синтетической» пары, если таковой не существует.

Паттерн "core - periphery"

Обратите внимание, что контракт маршрутизатора находится в репозитории под названием «v2 periphery», а пара - в репозитории «v2 core».

Uniswap V2 следует шаблону проектирования «ядро / периферия», где наиболее важная логика находится в ядре, а «необязательная» логика - на периферии.

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

Как определить адрес пула через токены?

Вместо того чтобы обращаться к маппингу пар токенов с адресом пула, смарт-контракты вычисляют адрес пула, предсказывая адрес через create2, как функцию от адресов токенов и адреса фабрики.

Поскольку при этом не происходит обращения к хранилищу, это очень экономит газ. Ниже приведена вспомогательная функция из UniswapV2Library для вычисления адреса парного контракта:

    function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(uint(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'
))));
}


Почему не использовать клоны контрактов через EIP1167?

Многие знают, что иногда копии контрактов создаются с помощью стандарта EIP1167, так почему же Uniswap не использует данную логику?

На самом деле все также просто.

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

Надеюсь, вам понравились наши небольшие разборы Uniswap V2. На этой неделе выйдет еще пара постов про AMM, а потом перейдем к AAVE и Compound.

#uniswap #core #periphery
🌭4👍2👌1
Погружение в DeFi. Все о Uniswap V2

Пора подвести некоторые итоги нашего разбора Uniswap V2 и обозначить все посты, где мы говорили про эту платформу.


Сводный пост про основные DeFi

Гайд по изучению Uniswap (2 части)

Архитектура Uniswap V2

Как Uniswap V2 вычисляет mintFee? (5 частей)

Разбор Uniswap V2: Router контракты (3 части)

Uniswap V2: UniswapV2Library (2 части)

Как работает TWAP в Uniswap V2 (3 части)

Разбор Uniswap V2: mint() & burn() (3 части)

Uniswap V2: swap() (5 частей)

Сборник ресурсов по Uniswap V2/V3


Всего было написано 26 постов! Ух, даже самому не верится!

Далее в планах пара слов о Sushiswap и Aave, а также более детальное погружение в Compound.

Будет сложно, но интересно!

#defi
🔥14🌭2👍1🤔1
Введение в Automated Market Makers (AMM)

Uniswap, который мы так старательно разбирали ранее, это приложение DeFi, позволяющее трейдерам обменивать один токен на другой. По сути, он был одним из первых автоматизированных маркет-мейкеров (AMM) для торговли, хоть и не первый.

P.S.Автоматические маркет-мейкеры - это альтернатива книге заявок, о которой мы поговорим чуть позже.

Как работают АММ?


Автоматический маркет-мейкер хранит в пуле (смарт-контракте) два токена (токен X и токен Y). Он позволяет любому вывести токен X из пула, но при этом он должен внести такое количество токена Y, чтобы «общая сумма» активов в пуле не уменьшилась.

«Общая сумма» - это произведение сумм двух активов:

𝒳𝒴 ≤ 𝒳′𝒴′


Здесь 𝒳′ и 𝒴′ - остатки токенов в пуле после сделки, а 𝒳 и 𝒴 - количество токенов в пуле до сделки.

Это гарантирует, что активы пула могут либо оставаться неизменными, либо увеличиваться.

Большинство пулов также взимают определенную комиссию. В этом случае произведение балансов должно не только увеличиться, но и вырасти на определенную сумму, с учетом комиссии.

Активы предоставляются пулу поставщиками ликвидности, которые получают так называемые LP-токены, представляющие их долю в пуле.

Балансы поставщиков ликвидности отслеживается аналогично тому, как это работает в ERC4626.

Разница между AMM и ERC4626 заключается в том, что ERC4626 поддерживает только один актив, а AMM работает с двумя токенами. Поэтому как и в vault, доля поставщиков ликвидности в пуле остается прежней, при этом сам продукт 𝒳𝒴 может становиться больше, увеличивая долю поставщиков.

Преимущества АММ

1. В АММ определение цены актива происходит автоматически. Оно определяется соотношением активов в пуле.

В частности, если у нас есть токен 𝒳 и токен 𝒴, цена определяется следующим образом:

price (x) = poolHoldings_Y / poolHoldings_X

И наоборот для 𝒴. То есть, чем больше актива 𝒳 попадает в пул, тем больше его «изобилие», и цена 𝒳 снижается.

2. Также у нас нет необходимости ждать, пока появится подходящий ордер «бид» или «аск». Он существует всегда.

3. Если существует несоответствие между ценой в AMM и на другой бирже, то трейдер будет арбитражировать разницу, возвращая цены в равновесие.

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

4. АММ удваивается как оракул.

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

5. AMM отличаются высокой газовой эффективностью по сравнению с книгами заявок.

Книги заявок требуют значительного объема бухгалтерского учета. В AMM нужно хранить только два токена и передавать их в соответствии с простыми правилами. Это делает их более эффективными в применении.

На этом пока все, а в следующем посты мы поговорим про недостатки AMM.

#amm
7
Введение в Automated Market Makers (AMM). Часть 2

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

У автоматических маркет-мейкеров есть два основных недостатка:

1. цена всегда движется и
2. постоянные потери для поставщиков ликвидности

Даже небольшие ордера двигают цену в АММ.

Если вы разместите ордер на покупку 100 акций Apple, ваш ордер не приведет к движению цены, потому что существуют тысячи акций, доступных для продажи по указанной вами цене. С автоматическим маркет-мейкером дело обстоит иначе. Каждая сделка, какой бы маленькой она ни была, приводит цену в движение.

И это имеет свои последствия.

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

Сэндвич атаки, в значительной степени, неизбежны в любом AMM.

Поскольку каждый ордер будет двигать цену, трейдеры MEV (Maximal Extractable Value) будут ждать, пока поступит достаточно большой ордер, затем сразу за ним выставят ордер на покупку, а сразу после него - на продажу. Опережающий ордер на покупку поднимет цену для первоначального трейдера, что обеспечит ему худшее исполнение. Это и называется «сэндвич-атакой», поскольку сделка жертвы «зажата» между атакующими.

Грубо говоря:

1) Первая покупка атакующего (frontrun): повышает цену для жертвы;

2) Покупка жертвы: рост цены еще больше;

3) Продажа атакующего: продажа первой покупки с прибылью;

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

По причинам, которые мы обсудим позже, поставщики ликвидности могут предоставлять активы только пропорционально текущему соотношению токенов в пуле. Например, если есть 100 токенов 𝒳 и 200 токенов 𝒴, новый поставщик ликвидности должен предоставить в два раза больше токенов 𝒴, чем 𝒳.

В традиционной книге заявок маркет-мейкер может размещать лимитные ордера на уровнях, которые, по его мнению, отражают желательную цену покупки или продажи (например, размещать ордер на покупку ниже текущей рыночной цены или ордер на продажу выше текущей рыночной цены), но это невозможно в случае с автоматизированным маркет-мейкером.

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

Именно поэтому поставщики ликвидности для АММ могут пострадать от непостоянных убытков.

Допустим, в гипотетическом сценарии Эфир начинается с $10 и позже будет стоить $1000.

Если у кого-то есть портфель из 1 Ether и 10 USD, то его портфель начинается с 20 долларов и заканчивается 1010 долларами (1 ETH + 10 долларов). Их прибыль составит $990.

Если бы они хранили деньги в AMM, то упустили бы большую часть прибыли. После изменения цены в AMM осталось бы 0,1 ETH и 100 долларов США. Это правильно оценивает ETH в 1000 долларов, но чистая стоимость пула составляет менее 990 долларов.

Вот как будут выглядеть холдинги пула до и после изменения цены:

(ETH_before)(USD_before) <= (ETH_after)(USD_after)

(1 ETH)(10 USD) <= (0.1 ETH)(100 USD)

10 <= 10


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

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

#amm
🔥2
Что такое книги заявок (ордеров)?

В постах про АММ несколько раз упоминались книги ордеров, и сегодня хотел бы сказать пару слов о них.

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

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

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

Книга заявок динамична, то есть она постоянно обновляется в режиме реального времени в течение дня. Такие биржи, как Nasdaq, называют ее "непрерывной книгой". Ордера, которые предполагают исполнение только при открытии или закрытии рынка, хранятся отдельно. Они известны как "книга открытия (ордеров)" и "книга закрытия (ордеров)" соответственно.

Например, при открытии рынка Nasdaq книги открытия и непрерывные книги объединяются, чтобы создать единую цену открытия. То же самое происходит при закрытии рынка, когда книга закрытия и непрерывная книга консолидируются для создания единой цены закрытия.

Как читают книги заявок?

Обычно книга заявок состоит из трех частей: заявок на покупку, заявок на продажу и истории заявок.

Ордера на покупку содержат информацию о покупателях и их заявки.

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

История рыночных ордеров показывает все сделки, которые были совершены в прошлом.

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

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

Некоторые нюансы с книгами

Хотя книга заявок призвана обеспечить прозрачность для участников рынка, есть некоторые детали, которые не включены в список. К ним относятся "темные пулы". Это группы скрытых ордеров, которые хранятся у крупных игроков, не желающих, чтобы их торговые намерения были известны другим.

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

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

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

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

#orderbook
👍2
Востребованный Solidity разработчик и DeFi

Участвуя в различных конкурсах по аудиту протоколов, я стал замечать кардинальное усиление современных протоколов в финансовых и биржевых продуктах. Если раньше было очень много проектов связанных с обменом, продажей и игрой NFT, а также простые контракты с покупкой/продажей токенов (они же и мемтокены, и алькоины, и т.д.), то сейчас уже протоколы внедряют сложные деривативные и опционные торги, сложные ликвидации позиций и продуманные механики рестейкинга.

EigenLayer, Uniswap Staker, Renzo, Ethena, Venus, Morpho - это одни из топовых DeFi протоколов, которые выходили на аудиты за последние полгода и привлекали к себе много внимания. Даже сейчас Euler собирается запустить свой конкурс на $ 1 250 000!!! И почему-то мне кажется, что многие протоколы позже возьмут его контракты на форк и будут внедрять в свою базу.

Современному Solidity разработчику уже не достаточно иметь навыков написания простых контрактов токенов / NFT и уметь загружать их в разные сети (коих развелось сейчас...). Необходимо понимать и уметь разбираться в архитектуре и механизмах DeFi протоколов, таких как: стейкинг и рестейкинг, ликвидации и награды,  деривативы и опционы, perpetual futures и многое другое. При этом также, в случае необходимости, разбираться с подключением своего контракта к нужному DeFi протоколу!

Это огромная область знаний, на которую уйдет не один час обучения!

На канале мы потихоньку начали разбирать DeFi протоколы, недавно прошли и Uniswap V2 и скоро будем продвигаться дальше. Я хочу вместе с вами еще раз просмотреть контракты популярных контрактов и разобраться в суть их функционирования. Это будет сложно и долго, но мы справимся.

Практически за два года ведения канала, я ни разу не повторился с темами (не было репостов или повторов) и выпускал новые посты практически каждый день. Теперь же моей целью является собрать здесь всю самую "мясную" инфу по DeFi.

Это будет очень интересное полугодие!

#defi
👍15🔥7🌭3
Канал разбора конкурсных отчетов

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

Сейчас уже разобрали более 100 различных уязвимостей и 3 конкурсных протокола. Дальше будем смотреть на проблемы с defil протоколами и сетями l2.

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

Доступ в группу идет по месячной оплате в 1000 рублей, чтобы в ней оставались только те, кому интересная и актуальна тема.

Буду рад новым участникам!

#security
👍5🔥1
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 1

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


Представьте, что у нас есть фиксированный пул из 100 000 токенов REWARD, который мы хотим справедливо распределить между пользователями в период от блока 1 по 100 блок.

Например, на момент конкретного блока стейкинг у пользователей был следующим:

| Name | Amount Staked | % of Pool |
| :-——-- | :------———-----: | --——-----: |
| Alice | 100 | 25 |
| Bob | 100 | 25 |
| Chad | 200 | 50 |

Тогда токены Rewards распределятся следующим образом:

| Name | Amount Staked | % of Pool | Rewards distribited |
| :-——-- | :----————-----: | --——-----: | ---———--------------: |
| Alice | 100 | 25 | 250 |
| Bob | 100 | 25 | 250 |
| Chad | 200 | 50 | 500 |


P.S. Токен Reward и токен стейкинга (тот же WETH или USDT) могут быть разными или одними и теми же в разных случаях. Для ясности, мы будет называть их именно Reward и просто Token.

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

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

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

Эта стратегия также повлечет за собой большие транзакционные сборы.

Отказавшись от этой системы, мы можем создавать «догоняющие» вознаграждения за блоки, в которых вознаграждения не были распределены.

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

block.number - lastUpdateBlockNumber;


Другими словами, мы можем пропустить несколько блоков, в которых мы распределяем вознаграждение, и «догнать» их, когда мы действительно делаем это.

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

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

Например, что если Чад знал, что мы собираемся измерить остатки на блоке 100, и сделал большой депозит на блоке 99, чтобы получить большую долю вознаграждения?

Эту проблему оказалось легко решить. Как? Узнает в следующем посте цикла.

#Sushiswap #MasterChef #staking
👍2🔥1
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 2

Решением проблемы из предыдущего поста является простое утверждение: нет транзакций, нет изменения балансов.

Вместо того чтобы заставлять оффчейн бота проводить транзакции каждые 20 блоков или что-то типа того, мы можем просто ждать, пока пользователь начнет взаимодействует с контрактом через функции изменения состояния, такие как deposit() или withdraw().

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

Например, если между блоком 10 и блоком 15 у Алисы было 50% стейкинга и у Боба - 50%, то мы можем выдать 5 000 REWARD (5 блоков умножить на 1 000) и дать каждому из них по 50%.

У Чада или Боба нет возможности «вскочить» и увеличить свой баланс, потому что когда они вызовут функцию deposit(), то вызовут распределение вознаграждения. А функция распределения вознаграждения запрограммирована так, чтобы не учитывать их недавний депозит.

Посмотрите на график на скрине выше, показывающий изменения баланса с течением времени.

Единственный способ, чтобы эти изменения произошли - это вызвать транзакцию со смарт-контрактом.

Однако это решение не масштабируется.

#Sushiswap #MasterChef #staking
👍4
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 3

В дополнение к предыдущему посту.

Распределять каждому стейкеру его REWARD каждый раз, когда кто-то вызывает deposit() или withdraw(), будет очень дорого, если стейкеров десятки. Трансфер токена ERC20 стоит недешево, а делать это десятки раз в цикле - непомерно дорого.

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

Для тех, кто не требует вознаграждения, оно откладывается. Вознаграждения остаются в контракте и ждут, когда они будут востребованы.

Это избавит нас от необходимости делать кучу переводов ERC 20.

Из этого следует:

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

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

Предположим, мы можем точно отследить, сколько один токен накопил вознаграждения «с начала времен» (когда контракт начал распределять вознаграждения).

Если это так, то отследить, сколько вознаграждения накопил аккаунт, можно просто умножив его баланс на то, сколько Rewards он накопил с начала времени.

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

Предположим, мы знаем, что токен с начала времени до текущего момента, собрал 12 Rewards. Поэтому если Алиса сделала депозит в 100 токенов, то ей причитается 1 200 Rewards.

Это все равно что сказать: «Доллар, который вы положили на счет в нашем банке, заработал 0,40 доллара в виде процентов с момента открытия банка. Если вы открыли счет, когда мы открыли банк, и с тех пор не пополняли и не снимали деньги, то вы заработали 40%».

Это приводит нас к двум вопросам:

1. Как отследить начисление вознаграждения за один токен с начала времени?

2. Что, если Алиса не делала депозит с начала времени, а только недавно пополнила счет?

Об этом в следующем посте.

#Sushiswap #MasterChef #staking
👍31
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 4

Как же мы отслеживаем начисление вознаграждения за один токен с самого начала?

Поскольку в каждом блоке выдается фиксированное количество вознаграждений (1 000 в нашем примере), чем больше стейкеров, тем меньшую долю от фиксированного вознаграждения в 1 000 токенов они получат. Не имеет значения, сколько людей делают депозит, важно только общее количество токенов, поставленных на контракт.

Рассмотрим следующий пример:

| Block        | Rewards issued/block | Supply of staked tokens | Reward token/block|
| :-——————---- | :----———————-------: | --——-———————----------: | ---———----------: |
| block 1-5 | 1000 | 100 | 10 |
| block 6-13 | 1000 | 200 | 5 |
| block 14-15 | 1000 | 100 | 10 |
| block 16-20 | 1000 | 500 | 2 |



На скрине приведена наглядная таблица. Красная линия - это количество поставленных токенов. Фиолетовая линия - размер вознаграждения, начисляемого за один токен в данном блоке. Блоки перемещаются вправо по оси x. Обратная зависимость между этими двумя переменными должна быть очевидна.

#Sushiswap #MasterChef #staking
👍2
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 5

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

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


На скрине вы можете видеть пример подобный графику из предыдущего поста с добавленным аккумулятором.

А вот таблица с теми же значениями:

| Block       | Rewards issued/block | Supply of staked tokens | Reward token/block |Number of blocks in interval | Rewards issued in interval | Accum. reward/token |
| :-——------- | :----————----------: | --——------------------: | ---———-----------: |---———---------------------: |---———--------------------: |---———-------------: |
| block 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| block 1-5 | 1000 | 100 | 10 | 5 | 50 | 50 |
| block 6-13 | 1000 | 200 | 5 | 8 | 40 | 90 |
| block 14-15 | 1000 | 100 | 10 | 2 | 20 | 110 |
| block 16-20 | 1000 | 500 | 2 | 5 | 10 | 120 |



То есть за один токен, поставленный на протяжении всего нашего сюжета, было накоплено 120 вознаграждений.

На следующей неделе поговорим уже более детально про сами контракты и приведем примеры.

#Sushiswap #MasterChef #staking
P.S. На телефонах таблицы ужасно отображаются, и я не знаю, как их удобнее сделать, если не скринить, как png. Если кто знает, как форматировать их в более читаемый вид на телефонах, маякните в комментариях.
Скрины таблиц из 4 и 5 части постов
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 6

В последний месяц наблюдаю забавную тенденцию на канале: количество участников постоянно меняется в пределах 6:-6, т.е. приходят несколько человек, потом несколько уходят после новых постов. Сложилось такое ощущение, что многие заходят на канал в поисках чего-то простого по изучению Solidity, потом видят посты по расчеты в DeFi и такие: "Да ну нахер..." и уходят.

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

Тем не менее, я подумаю, как можно сделать посты более "дружелюбными" для новичков и может выделить разборы DeFi в отдельный бесплатный канал.

А пока что, на этой неделе мы закончим читать статью про Sushiswap MasterChef и Synthetix, и для начала разберем небольшой пример, чтобы вспомнить посты с прошлой недели.

Мы снова выдаем по 1 000 Rewards за блок. За 20 блоков будет выдано 20 000 вознаграждений.

Вот что делают Алиса и Боб:

- Алиса сделала депозит 100 жетонов с блока 1 по блок 20.
- В блоке 10 Боб делает депозит 100 жетонов.
- В блоке 20 Алиса должна получить 75 % от всех вознаграждений, выданных до этого момента, или 15 000 вознаграждений.

Визуально доля пула ставок на блок будет выглядеть как на скрине выше.

С блока 1 по блок 10 награда за токен в блоке составляла 10 (1 000 ÷ 100). За этот интервал в 10 блоков каждый токен накапливал 100 Rewards (10 вознаграждений за токен в блоке x 10 блоков).

Но когда Боб пополнил счет в блоке 10, награда за токен в блоке уменьшилась до 5 (1 000 ÷ 200). За следующий интервал в 10 блоков (блоки с 11 по 20) каждый токен накопил 50 Rewards.

Таким образом, общая стоимость, накопленная токеном с блока 1 по блок 10, равна 100, а стоимость, накопленная с 11 по 20, равна 50. Таким образом, общая стоимость накопленного токена равна 100 + 50 = 150.

Поскольку Алиса положила на счет 100 токенов, а каждый токен накопил 150 вознаграждений, ей будет выдано 15 000 вознаграждений, что действительно составляет 75 % от общего количества выданных вознаграждений.

Но что, если ни кто не делал депозиты с самого начала?

Очевидный исключительный случай в приведенном выше примере заключается в том, что если бы Боб потребовал вознаграждение, то он также получил бы 15 000, потому что его ставка в блоке 20 равна 100, как и у Алисы.

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

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

Однако еще проще рассчитать сумму вознаграждений, которую он получил бы при пополнении счета в блоке 10, а затем сразу же потребовал вознаграждение. Например, в блоке 10 накопленное вознаграждение за токен составляло 100. Поскольку Боб положил на счет 100 жетонов, теоретически он мог бы сразу получить 10 000 Rewards.

Для того, чтобы этого не произошло, у нас есть переменная для Боба, которую мы называем «долг награды» (“reward debt”).

В тот момент, когда он вносит депозит, мы устанавливаем reward debt равным балансу депозита, умноженному на накопитель вознаграждения за токены. Это не позволит ему сразу же получить награду, поскольку в этот момент причитающееся ему вознаграждение будет равно нулю (текущее вознаграждение минус долг вознаграждения).

Мы создали для Боба отдельную переменную под названием «долг вознаграждения» и присвоили ей эту гипотетическую сумму вознаграждения. В блоке 10 накопленное вознаграждение за токен составляло 100, и депозит Боба был 100, поэтому его долг по вознаграждению составляет 10 000.

Если Боб потребует вознаграждение в блоке 20, мы вычтем вознаграждение в 15 000 из суммы долга в 10 000. Боб сможет получить только 5 000 Rewards в блоке 20.

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

Дальше мы поговорим про MasterChef.

#Sushiswap #MasterChef #staking
3🔥3
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 7

Различия между Synthetix и MasterChef

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

Эта разница добавляется в маппинг rewards для каждого пользователя и накапливается там до тех пор, пока пользователь не вызовет getRewards(). Эти дополнительные расчеты делают алгоритм Synthetix менее эффективным.

Остальные различия довольно незначительны:

- В MasterChef есть deposit() и withdraw().
- В Synthetix есть stake(), withdraw() и getReward().
- В MasterChef в качестве единицы времени используются блоки.
- Synthetix использует метку времени.
- MasterChef минтит вознаграждения для себя, как описано в предыдущих разделах.
- Synthetix предполагает, что администратор уже перевел вознаграждение на контракт, и не минтит вознаграждения.
- MasterChef распределяет вознаграждения от настраиваемого startBlock до lastRewardBlock.
- Synthetix жестко закодирован на распределение вознаграждений в течение недели после того, как администратор запустит часы. Synthetix будет распределять не весь баланс вознаграждений в контракте, а сумму, указанную администратором.
- MasterChef переводит вознаграждение пользователю каждый раз, когда он вызывает функцию deposit() или withdraw() с ненулевой суммой.
- Synthetix накапливает причитающееся пользователю вознаграждение в связке под названием rewards, но не передает его пользователю до тех пор, пока он явно не вызовет getRewards().
- MasterChef поддерживает несколько пулов в рамках одного контракта и делит вознаграждения по весу пула.
- В Synthetix есть только один пул

Заинтересованный читатель может ознакомиться с кодом для SushiSwap MasterChef Staking.

#Sushiswap #MasterChef #staking
Алгоритм стейкинга в Sushiswap MasterChef и Synthetix. Часть 9

На графике ниже показана подпрограмма бухгалтерского учета Synthetix, которая вызывается во время операций deposit(), withdraw() или getRewards(). В частности, это делается перед обновлением баланса при пополнении или снятии средств или при распределении вознаграждений.

На приведенном ниже графике lastUpdateTime - это время последнего вызова одной из трех функций пользователем. В приведенном ниже примере пользователь, получающий вознаграждение, - это не тот же самый пользователь, который ранее взаимодействовал с контрактом. Маркер ' означает значение переменной после завершения подпрограммы.

Ознакомиться с кодом Syntetix вы можете тут.

#Sushiswap #MasterChef #staking