From 1d70777adf843c95cd559a3a9070966204f7135a Mon Sep 17 00:00:00 2001 From: boivlad Date: Mon, 17 Jul 2023 19:19:13 +0300 Subject: [PATCH 1/7] feat: added ua language(main file + 2 tasks) --- client/src/constants.js | 2 +- client/src/containers/Header.js | 7 +- client/src/gamedata/ar/strings.json | 1 + client/src/gamedata/en/strings.json | 1 + client/src/gamedata/es/strings.json | 1 + client/src/gamedata/fr/strings.json | 1 + client/src/gamedata/ja/strings.json | 1 + client/src/gamedata/pt_br/strings.json | 1 + client/src/gamedata/ru/strings.json | 1 + client/src/gamedata/tr/strings.json | 1 + .../ua/descriptions/levels/aliencodex.md | 7 ++ .../levels/aliencodex_complete.md | 5 + .../ua/descriptions/levels/coinflip.md | 5 + .../descriptions/levels/coinflip_complete.md | 5 + client/src/gamedata/ua/strings.json | 114 ++++++++++++++++++ client/src/gamedata/zh_cn/strings.json | 7 +- client/src/gamedata/zh_tw/strings.json | 1 + package.json | 4 +- yarn.lock | 12 +- 19 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 client/src/gamedata/ua/descriptions/levels/aliencodex.md create mode 100644 client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/coinflip.md create mode 100644 client/src/gamedata/ua/descriptions/levels/coinflip_complete.md create mode 100644 client/src/gamedata/ua/strings.json diff --git a/client/src/constants.js b/client/src/constants.js index 7a636004c..c68406871 100644 --- a/client/src/constants.js +++ b/client/src/constants.js @@ -196,4 +196,4 @@ export const ALIAS_PATH = "https://raw.githubusercontent.com/OpenZeppelin/ethern export const getLeaderboardPath = (network) => { return `https://raw.githubusercontent.com/OpenZeppelin/ethernaut-leaderboard/update/boards/networkleaderboards/${network}LeaderBoard.json` -} \ No newline at end of file +} diff --git a/client/src/containers/Header.js b/client/src/containers/Header.js index f9b94e192..882812252 100644 --- a/client/src/containers/Header.js +++ b/client/src/containers/Header.js @@ -232,6 +232,7 @@ class Header extends React.Component { en: strings.english, es: strings.spanish, pt_br: strings.portuguese, + ua: strings.ukrainian, ja: strings.japanese, zh_cn: strings.chinese_simplified, zh_tw: strings.chinese_traditional, @@ -240,7 +241,7 @@ class Header extends React.Component { ar: strings.arabic, tr: strings.turkish, }; - + const ddOpen = Boolean(this.state.multiDDOpen); return (
this.closeDropdown()}> @@ -319,11 +320,11 @@ class Header extends React.Component { this.toggleDropdownState()} to={constants.PATH_LEADERBOARD}>
+ className="element-in-row filled-icon">
- + )} { diff --git a/client/src/gamedata/ar/strings.json b/client/src/gamedata/ar/strings.json index 16f79acfb..ebf611ea9 100644 --- a/client/src/gamedata/ar/strings.json +++ b/client/src/gamedata/ar/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/en/strings.json b/client/src/gamedata/en/strings.json index 331462fc4..9ebbdb2ec 100644 --- a/client/src/gamedata/en/strings.json +++ b/client/src/gamedata/en/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/es/strings.json b/client/src/gamedata/es/strings.json index 8b3f5bfe6..18a518dc5 100644 --- a/client/src/gamedata/es/strings.json +++ b/client/src/gamedata/es/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/fr/strings.json b/client/src/gamedata/fr/strings.json index 3fa13c08f..4ee99819f 100644 --- a/client/src/gamedata/fr/strings.json +++ b/client/src/gamedata/fr/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/ja/strings.json b/client/src/gamedata/ja/strings.json index dac3bddd3..d99dd88bb 100644 --- a/client/src/gamedata/ja/strings.json +++ b/client/src/gamedata/ja/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/pt_br/strings.json b/client/src/gamedata/pt_br/strings.json index dd74eebcd..b4deb3e12 100644 --- a/client/src/gamedata/pt_br/strings.json +++ b/client/src/gamedata/pt_br/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/ru/strings.json b/client/src/gamedata/ru/strings.json index 74c6d6500..a3b46e812 100644 --- a/client/src/gamedata/ru/strings.json +++ b/client/src/gamedata/ru/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/tr/strings.json b/client/src/gamedata/tr/strings.json index 56eed471c..3f3b1dd64 100644 --- a/client/src/gamedata/tr/strings.json +++ b/client/src/gamedata/tr/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/client/src/gamedata/ua/descriptions/levels/aliencodex.md b/client/src/gamedata/ua/descriptions/levels/aliencodex.md new file mode 100644 index 000000000..1b56a23ea --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/aliencodex.md @@ -0,0 +1,7 @@ +Ви виявили контракт інопланетян. Претендуйте на власність, щоб завершити рівень. + +  +Речі, які можуть допомогти +* Розуміння, як працює зберігання масивів +* Розуміння [специфікацій ABI](https://solidity.readthedocs.io/en/v0.4.21/abi-spec.html) +* Використання дуже `підступного` підходу diff --git a/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md b/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md new file mode 100644 index 000000000..d626c2a9d --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md @@ -0,0 +1,5 @@ +Цей рівень використовує той факт, що EVM не перевіряє довжину масиву, кодовану ABI, відносно його реального вмісту. + +Додатково, він використовує арифметичне недолік довжини масиву, розширюючи межі масиву до всієї області зберігання `2^256`. Потім користувач може змінювати усе зберігання контракту. + +Обидва вразливості надихнуті [конкурсом підступного кодування 2017 року](https://medium.com/@weka/announcing-the-winners-of-the-first-underhanded-solidity-coding-contest-282563a87079) diff --git a/client/src/gamedata/ua/descriptions/levels/coinflip.md b/client/src/gamedata/ua/descriptions/levels/coinflip.md new file mode 100644 index 000000000..387d1ce05 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/coinflip.md @@ -0,0 +1,5 @@ +Це гра в підкидання монети, де вам потрібно збільшувати вашу переможну серію, вгадуючи результат підкидання монети. Щоб завершити цей рівень, вам потрібно використовувати свої екстрасенсорні здібності, щоб вгадати правильний результат 10 разів поспіль. + +  +Речі, які можуть допомогти +* Перегляньте сторінку ["?"](https://ethernaut.openzeppelin.com/help) в меню в правому верхньому куті, розділ "По ту сторону консолі" diff --git a/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md b/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md new file mode 100644 index 000000000..418ddb554 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md @@ -0,0 +1,5 @@ +Генерація випадкових чисел у Solidity може бути складною. Наразі не існує рідного способу їх генерації, і все, що ви використовуєте в розумних контрактах, є публічно видимим, включаючи локальні змінні та змінні стану, позначені як приватні. Також майнери мають контроль над такими речами, як блокхеши, часові мітки, та включення певних транзакцій - що дозволяє їм зміщувати ці значення на свою користь. + +Щоб отримати криптографічно доведені випадкові числа, ви можете використовувати [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number), який використовує оракул, токен LINK, та контракт на блокчейні для перевірки того, що число дійсно випадкове. + +Деякі інші варіанти включають використання заголовків блоків Bitcoin (перевірених через [BTC Relay](http://btcrelay.org)), [RANDAO](https://github.com/randao/randao), або [Oraclize](http://www.oraclize.it/)). diff --git a/client/src/gamedata/ua/strings.json b/client/src/gamedata/ua/strings.json new file mode 100644 index 000000000..fd2952ad3 --- /dev/null +++ b/client/src/gamedata/ua/strings.json @@ -0,0 +1,114 @@ +{ + "ethernaut": "Ethernaut", + "title": "Ethernaut", + "hiring": "Ми наймаємо", + "info": "

Ethernaut це Web3/Solidity варгейм на базі Ethereum Virtual Machine, натхненний overthewire.org. Кожен рівень є смарт-контрактом, який потрібно 'зламати'. Вихідний код гри повністю відкритий, а всі рівні створені іншими гравцями. У тебе є цікава ідея для нового рівня? !

", + "home": "Назад", + "help": "Допомога", + "stats": "Статистика", + "ethernautHelp": "Правила гри", + "footer": "розроблено з та командою OpenZeppelin", + "english": "English", + "arabic": "عربي", + "spanish": "Español", + "ukrainian": "Українська", + "portuguese": "Português", + "japanese": "日本語", + "turkish": "Türkçe", + "chinese_simplified": "簡體中文", + "chinese_traditional": "正體中文", + "french": "Français", + "russian": "Русский", + "playNow": "Грати!", + "toggleNavigation": "Показати або приховати панель навігації", + "levelCompleted": "Рівень пройдено!", + "sources": "Вихідний код", + "submitInstance": "Надіслати інстанс на перевірку", + "getNewInstance": "Створити новий інстанс", + "deployMessageTitle": "Гра не розгорнута", + "deployMessage": "На даний момент гра підтримує тільки ці мережі:", + "deployConfirmation": "Ви хочете розгорнути контракти в цій мережі або переключитись на мережу Sepolia??", + "deployNote": "Примітка. Якщо ви розгорнете всі рівні, ми порадимо вам відправити всю розгорнуту гру в цю мережу.", + "deployGame": "Розгорнути гру", + "switchToSepolia": "Переключитись на Sepolia", + "deployLevel": "Рівень розгортання", + "helperDeployAllContracts": "Розгорніть всі залишені контракти в поточній мережі.", + "confirmMainnetDeploy": "Ви перебуваєте в основній мережі, гра не має грошової вартості, вам не слід розгортати її в цій мережі.", + "submitLevelFooter": "Розгорніть всі рівні (deployAllContracts() в консолі), щоб додати поточну мережу в наш репозиторій Github як нову підтримувану мережу.", + "submitGameFooter": "Чудово! Вся гра розгорнута в цій мережі. Натисніть тут, щоб висунути питання на GitHub і відправити його нам :)", + "nextLevel": "Наступний рівень", + "uLevels": "Рівні", + "lLevels": "рівні", + "refresh": "Оновити", + "uCompleted": "Пройдено", + "lCompleted": "пройдено", + "players": "Гравці", + "player": "Гравець", + "levelName": "Назва рівня", + "levelAddress": "Адреса рівня", + "blockNum": "Номер блоку", + "uCreated": "Створено", + "lCreated": "створено", + "instance": "Інстанс", + "numberOf": "Кількість", + "warning": "Попередження", + "warningMessage": "Провайдер web3 відсутній, і гра знаходиться в режимі тільки для читання", + "levelAuthor": "Автор(и) рівня:", + "pleaseWait": "БУДЬ ЛАСКА, ЗАЧЕКАЙТЕ", + "donate": "Рівень допоміг вам дізнатись щось нове? У вас є можливість підтримати автора(ів) цього рівня (на мейннеті):", + "openConsole": "ВІДКРИЙТЕ КОНСОЛЬ БРАУЗЕРА, ЩОБ РОЗПОЧАТИ ГРУ", + "difficulty": "Складність", + "error": "Помилка", + "retrying": "повторюю запит...", + "typeHelpMessage": "Введи help() щоб отримати список об'єктів і функцій, які допоможуть тобі в процесі гри", + "slowNetworkMessage": "Повідомлення 'Slow network detected' можна приховати за допомогою пункту 'Показувати тільки користувацькі повідомлення' в інструментах розробника або флага 'chrome://flags/#enable-webfonts-intervention-v2'", + "notContractSetMessage": "Інстанс не знайдено, натисни 'Створити новий інстанс' на сторінці з рівнем, щоб створити новий інстанс", + "levelAddressMessage": "Адреса рівня", + "instanceAddressMessage": "Адреса інстанса", + "playerAddressMessage": "Адреса гравця", + "selectedNetworkMessage": "Поточна мережа: ", + "ethernautAddressMessage": "Адреса Ethernaut-а", + "noLevelsDataMessage": "Дані рівнів не знайдено", + "ethernautNotFoundMessage": "Контракт Ethernaut не знайдено в поточній мережі. Будь ласка, переконайтеся, що (1) ви використовуєте MetaMask, (2) воно працює в підтримуваній мережі, (3) воно розблоковано, (4, необов'язково) з 2 листопада ви можете увімкнути приватний режим (вимкнений за замовчуванням) в налаштуваннях MetaMask, якщо не хочете відкривати свою інформацію за замовчуванням. (5, необов'язково) Якщо приватний режим увімкнено, ви повинні дозволити MetaMask використовувати цю сторінку. І (6) потім оновіть сторінку.", + "requestingNewInstanceMessage": "Запитую новий інстанс...", + "unableToRetrieveLevelMessage": "Не вдалося отримати інстанс! Перевірте параметри газу і спробуйте запросити інстанс знову.", + "transactionNoLogsMessage": "Транзакція не містить журналів", + "noPlayerAddressMessage": "Адресу гравця не виявлено! Переконайтеся, що MetaMask плагін (1) встановлено і (2) розблоковано. Якщо в MetaMask увімкнено приватний режим, то в налаштуваннях MetaMask вам необхідно авторизувати поточну сторінку. Оновіть сторінку після виконання вищезазначених дій.", + "noEthersMessage": "Ой, у вас немає ефіру! Отримайте його в дійсному крані для вашої обраної мережі", + "submitLevelMessage": "Інстанс перевіряється...", + "wellDoneMessage": "Чудово", + "completedLevelMessage": "Рівень пройдено!", + "uncompletedLevelMessage": "Ой! Здається, ви ще не взломали цей рівень", + "metamaskKnownIssue": "Ой! Ймовірно, виникла проблема з MetaMask. Спробуйте вимкнути та увімкнути плагін MetaMask. Якщо це не вирішило проблему, то перезавантажте браузер.", + "eventsCompletionMessage": "Під час обробки подій сталася помилка:", + "unexpectedAddressMessage": "Неочікувана адреса в події LevelCompletedLog:", + "helperPlayer": "адреса гравця", + "helperEthernaut": "адреса Ethernaut-а", + "helperLevel": "адреса поточного рівня", + "helperContract": "об'єкт поточного рівня (якщо створено)", + "helperInstance": "об'єкт поточного інстансу (якщо створено)", + "helperVersion": "версія гри", + "helperGetBalance": "отримати баланс адреси (одиниця вимірювання: ефір)", + "helperGetBlockNumber": "отримати номер останнього блоку", + "helperSendTransaction": "надіслати транзакцію", + "helperGetNetworkId": "отримати ідентифікатор мережі", + "helperToWei": "конвертувати число з ефіру в вей", + "helperFromWei": "конвертувати число з вей в ефір", + "levelNotTranslated": "Цей рівень не перекладено українською мовою або переклад не завершено", + "contributeTranslation": "Вдосконалити переклад", + "usingConsole": "Взаємодія з грою відбувається через консоль браузера. Щоб отримати список об'єктів та функцій, які допоможуть вам у грі, введіть у консолі браузера команду:\n\nhelp()\n\n Більшість функцій асинхронні, тому вам знадобиться ключове слово await. Наприклад, замість:\n\ngetBalance(player)\n> PROMISE\n\nкраще використовувати:\n\nawait getBalance(player)\n> '1.11002387'\n\n", + "gameMechanics": "За допомогою веб-інтерфейсу гравець запитує створення нового інстансу. Запит направляється в контракт Ethernaut.sol, який, у свою чергу, делегує запит відповідному рівню, кожен з яких успадковується від контракта Level.sol та створює новий інстанс. Після цього гравець взаємодіє з інстансом до тих пір, поки не 'зламає' його, після чого надсилає інстанс на перевірку за допомогою веб-інтерфейса.\n\nЗ кожним інстансом можна взаємодіяти через консоль браузера як з об'єктом типу TruffleContract. Більше інформації про механіку гри можна знайти в описі першого рівня.", + "beyondConsole": "Для проходження деяких рівнів вам знадобиться написати код на мові Solidity, скомпілювати його в байткод і викласти байткод в мережу. Ці кроки можна виконати за допомогою різних інструментів, наприклад:\n\n1) Remix Solidity IDE\n\n2) Hardhat\n\n3) Truffle Framework", + "troubleshooting": "При виникненні проблем спробуйте: (1) оновити сторінку, (2) вимкнути та увімкнути MetaMask, (3) перезавантажити браузер, (4) очистити куки та інші дані сторінки.\n\nЯкщо після виконання цих кроків проблема не вирішена, повідомити про проблему можна за адресою ethernaut@zeppelin.solutions.", + "poweredBy": "підтримується", + "setupMetamask": "Якщо у вас ще немає, встановіть розширення браузера MetaMask (в Chrome, Firefox, Brave або Opera на вашому настільному комп'ютері). \n\n Налаштуйте гаманець розширення та використайте вибір мережі, щоб вказати бажану мережу у верхній лівій частині інтерфейсу розширення. Ви також можете використовувати кнопку користувацького інтерфейсу для перемикання між мережами. Якщо ви виберете непідтримувану мережу, гра повідомить вас і перенесе вас до тестової мережі Sepolia за замовчуванням. \n\nПісля завершення поверніться сюди та перезавантажте веб-сторінку", + "FifthyPercentMessage": "Чудова робота! Ви вже на півдорозі до Ethernaut і досить добре вправляєтеся в ламанні речей. Працювати дослідником безпеки блокчейну в OpenZeppelin могло б бути весело... https://grnh.se/fdbf1c043us", + "SeventyFivePercentMessage": "75%: Добра робота... ви вже глибоко в кроличій норі.... хто знає, куди вона вас приведе... https://grnh.se/d4a786e43us", + "NinetyPercentMessage": "90%: Ви майже там! Лишилося лише кілька викликів, поки ви не завершите Ethernaut! Чи розглядали ви кар'єру в області безпеки блокчейну?https://grnh.se/cfcca8c83us", + "HundredPercentMessage": "100%: Вітаємо! Ваша подорож по кроличій норі web3 вражає і заслуговує на святкування! Тепер у вас є навички ламати розумні контракти! Що далі звідси? Подайте заявку на посаду дослідника безпеки блокчейну в OpenZeppelin і долучіться до захисту провідних протоколів у web3! https://grnh.se/26c05aac3us", + "Menu": "Меню", + "Networks": "Мережі", + "Languages": "Мови", + "PageNotFoundTitle": "Помилка 404 - Сторінку не знайдено", + "PageNotFoundText": "Ой! Сторінка, яку ви шукаєте, не може бути знайдена." +} diff --git a/client/src/gamedata/zh_cn/strings.json b/client/src/gamedata/zh_cn/strings.json index 981a5429a..14a3d2d98 100644 --- a/client/src/gamedata/zh_cn/strings.json +++ b/client/src/gamedata/zh_cn/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", @@ -95,9 +96,9 @@ "helperFromWei": "从wei转换到ether", "levelNotTranslated": "这一关卡还没有被翻译或是翻译不完全 ", "contributeTranslation": "来帮助我们翻译吧", - "usingConsole": "大多数的游戏互动时通过浏览器的控制台: `Dev Tools -> Console`. 打开控制台然后输入这个命令:\n\n`help()`\n\n 可以得到一个列表, 包含了被这个游戏放入控制台的对象和函数. 鉴于多数的互动是异步的, 我们推荐使用Chrome v62 并且使用 `async`/`await` 关键词, 所以相比于使用:\n\n`getBalance(player)> PROMISE`\n\n我们推荐使用 await/async, 你可以这样使用: \n\n`await getBalance(player)> 1.11002387`\n\n", - "gameMechanics": "这个游戏使用主合约 `Ethernaut.sol` 来管理玩家进度, 代理玩家和 `Level.sol` 互动. 每一关的合约会产生一个实例供玩家操作, 攻破, 摧毁, 修复等等. 玩家请求一个实例, 操作之后返回,然后将会被评判完成度.\n\n 请求和提交实例都是通过每一关界面上的按钮. 当这个 app 从 `Ethernaut.sol` 取回实例时, 会把它包装在 `TruffleContract` 对象中, 然后暴露在浏览器的控制台里. 尝试第一关来看看怎么玩这个游戏.", - "beyondConsole": "有些关卡需要在控制台之外的操作. 比如, 用 solidity 写一些代码, 部署合约在网络上, 然后攻击实例. 这可以通过很多方式完成, 比如: \n\n1) 使用 Remix 写代码并部署在相应的网络上 参见 [Remix Solidity IDE](https://remix.ethereum.org/).\n\n2) 设置一个本地 truffle 项目, 开发并部署攻击合约. 参见 [Truffle Framework](http://truffleframework.com/).", + "usingConsole": "大多数的游戏互动时通过浏览器的控制台: `Dev Tools -> Console`. 打开控制台然后输入这个命令:\n\n`help()`\n\n 可以得到一个列表, 包含了被这个游戏放入控制台的对象和函数. 鉴于多数的互动是异步的, 我们推荐使用Chrome v62 并且使用 `async`/`await` 关键词, 所以相比于使用:\n\n`getBalance(player)> PROMISE`\n\n我们推荐使用 await/async, 你可以这样使用: \n\n`await getBalance(player)> 1.11002387`\n\n", + "gameMechanics": "这个游戏使用主合约 `Ethernaut.sol` 来管理玩家进度, 代理玩家和 `Level.sol` 互动. 每一关的合约会产生一个实例供玩家操作, 攻破, 摧毁, 修复等等. 玩家请求一个实例, 操作之后返回,然后将会被评判完成度.\n\n 请求和提交实例都是通过每一关界面上的按钮. 当这个 app 从 `Ethernaut.sol` 取回实例时, 会把它包装在 `TruffleContract` 对象中, 然后暴露在浏览器的控制台里. 尝试第一关来看看怎么玩这个游戏.", + "beyondConsole": "有些关卡需要在控制台之外的操作. 比如, 用 solidity 写一些代码, 部署合约在网络上, 然后攻击实例. 这可以通过很多方式完成, 比如: \n\n1) 使用 Remix 写代码并部署在相应的网络上 参见 [Remix Solidity IDE](https://remix.ethereum.org/).\n\n2) 设置一个本地 truffle 项目, 开发并部署攻击合约. 参见 [Truffle Framework](http://truffleframework.com/).", "troubleshooting": "有的时候, \n\napp 或者 MetaMask 插件会有点问题, 特别是当你转换网络和解锁时. \n\n如果你遇到什么莫名其妙的问题, 尝试刷新 app, 多次刷新. 重启 MetaMask 插件, 甚至是重启浏览器.\n\n如果你发现其他问题, 欢迎提交给我们 ethernaut@zeppelin.solutions", "poweredBy": "powered by ", "setupMetamask": "如果你还没有,请安装[MetaMask浏览器扩展](https://metamask.io/)(在电脑上的Chrome、Firefox、Brave或Opera浏览器中)。\n\n配置好浏览器扩展的钱包,然后在扩展界面的左上角选择偏好的网络,或者你也可以用网页界面的按钮来切换网络。\n\n如果你选择了一个不支持的网络,这个游戏将提示你并且为你切换到默认的Sepolia测试网络", diff --git a/client/src/gamedata/zh_tw/strings.json b/client/src/gamedata/zh_tw/strings.json index ce97df2b9..1b101e3e6 100644 --- a/client/src/gamedata/zh_tw/strings.json +++ b/client/src/gamedata/zh_tw/strings.json @@ -11,6 +11,7 @@ "english": "English", "arabic": "عربي", "spanish": "Español", + "ukrainian": "Українська", "portuguese": "Português", "japanese": "日本語", "turkish": "Türkçe", diff --git a/package.json b/package.json index 114594912..3cf7dc40a 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "compile:contracts": "cd contracts && hardhat clean && hardhat compile", "deploy:contracts": "yarn compile:contracts && node --experimental-json-modules client/scripts/deploy_contracts.mjs", "upgrade:proxy": "yarn compile:contracts && node --experimental-json-modules client/scripts/upgrade_proxy.mjs", - "supersede:level": "yarn compile:contracts && node --experimental-json-modules client/scripts/supersede_level.mjs", + "supersede:level": "yarn compile:contracts && node --experimental-json-modules client/scripts/supersede_level.mjs", "network": "cd contracts && hardhat node", "build:ethernaut": "yarn compile:contracts && yarn --cwd client build", "start:ethernaut": "cd client && yarn start", @@ -28,4 +28,4 @@ "leaderboard:newCrawler": "node client/leaderboard/scripts/crawlers/crawlNewData/index.cjs", "leaderboard:triggerNextCrawl": "node client/leaderboard/scripts/actuate/index.cjs" } -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index 69c455767..35c59719f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5455,9 +5455,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001400: - version "1.0.30001431" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz" - integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== + version "1.0.30001516" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz" + integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== capture-exit@^2.0.0: version "2.0.0" @@ -9406,9 +9406,9 @@ highlight.js@^10.4.1: highlight.js "^10.7.2" highlight.js@^10.7.2: - version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + version "10.7.2-local" + dependencies: + highlight.js "^10.7.2" highlightjs-solidity@^2.0.5: version "2.0.5" From 9e22d7927703708206dea3ec285d385ccf0ff771 Mon Sep 17 00:00:00 2001 From: boivlad Date: Tue, 25 Jul 2023 15:04:48 +0300 Subject: [PATCH 2/7] feat: added ua translates part 2 --- .../ua/descriptions/levels/delegate.md | 7 ++ .../descriptions/levels/delegate_complete.md | 3 + .../ua/descriptions/levels/fallback.md | 12 ++++ .../descriptions/levels/fallback_complete.md | 5 ++ .../ua/descriptions/levels/fallout.md | 5 ++ .../descriptions/levels/fallout_complete.md | 15 ++++ .../gamedata/ua/descriptions/levels/force.md | 9 +++ .../ua/descriptions/levels/force_complete.md | 3 + .../ua/descriptions/levels/instances.md | 69 +++++++++++++++++++ .../descriptions/levels/instances_complete.md | 6 ++ .../gamedata/ua/descriptions/levels/king.md | 5 ++ .../ua/descriptions/levels/king_complete.md | 3 + .../ua/descriptions/levels/reentrancy.md | 9 +++ .../levels/reentrancy_complete.md | 12 ++++ .../ua/descriptions/levels/telephone.md | 5 ++ .../descriptions/levels/telephone_complete.md | 21 ++++++ .../gamedata/ua/descriptions/levels/token.md | 7 ++ .../ua/descriptions/levels/token_complete.md | 12 ++++ .../gamedata/ua/descriptions/levels/vault.md | 1 + .../ua/descriptions/levels/vault_complete.md | 3 + client/src/gamedata/ua/strings.json | 4 +- 21 files changed, 214 insertions(+), 2 deletions(-) create mode 100644 client/src/gamedata/ua/descriptions/levels/delegate.md create mode 100644 client/src/gamedata/ua/descriptions/levels/delegate_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/fallback.md create mode 100644 client/src/gamedata/ua/descriptions/levels/fallback_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/fallout.md create mode 100644 client/src/gamedata/ua/descriptions/levels/fallout_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/force.md create mode 100644 client/src/gamedata/ua/descriptions/levels/force_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/instances.md create mode 100644 client/src/gamedata/ua/descriptions/levels/instances_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/king.md create mode 100644 client/src/gamedata/ua/descriptions/levels/king_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/reentrancy.md create mode 100644 client/src/gamedata/ua/descriptions/levels/reentrancy_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/telephone.md create mode 100644 client/src/gamedata/ua/descriptions/levels/telephone_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/token.md create mode 100644 client/src/gamedata/ua/descriptions/levels/token_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/vault.md create mode 100644 client/src/gamedata/ua/descriptions/levels/vault_complete.md diff --git a/client/src/gamedata/ua/descriptions/levels/delegate.md b/client/src/gamedata/ua/descriptions/levels/delegate.md new file mode 100644 index 000000000..96bd57ed3 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/delegate.md @@ -0,0 +1,7 @@ +Метою цього рівня є те, щоб вам заявити про власність над екземпляром, який вам дано. + +  +Речі, які можуть допомогти +* Загляньте в документацію Solidity про функцію низького рівня `delegatecall`, як вона працює, як вона може використовуватися для делегування операцій до бібліотек на блокчейні, і які вона має наслідки для області виконання. +* Запасні методи +* Ідентифікатори методів diff --git a/client/src/gamedata/ua/descriptions/levels/delegate_complete.md b/client/src/gamedata/ua/descriptions/levels/delegate_complete.md new file mode 100644 index 000000000..275e84999 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/delegate_complete.md @@ -0,0 +1,3 @@ +Використання `delegatecall` є особливо ризикованим і було використано як вектор атаки в декількох історичних хаках. З його допомогою ваш контракт фактично говорить: "ось, -інший контракт- або -інша бібліотека-, робіть з моїм станом все, що вам заманеться". Делегати мають повний доступ до стану вашого контракту. Функція `delegatecall` - це потужна особливість, але небезпечна, і її треба використовувати з крайньою обережністю. + +Будь ласка, зверніться до статті [The Parity Wallet Hack Explained](https://blog.openzeppelin.com/on-the-parity-wallet-multisig-hack-405a8c12e8f7) для точного пояснення, як ця ідея була використана для крадіжки 30 млн доларів США. diff --git a/client/src/gamedata/ua/descriptions/levels/fallback.md b/client/src/gamedata/ua/descriptions/levels/fallback.md new file mode 100644 index 000000000..182231749 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/fallback.md @@ -0,0 +1,12 @@ +Уважно подивіться на код контракту нижче. + +Ви пройдете цей рівень, якщо +1) ви претендуєте на власність контракту +2) ви зменшите його баланс до 0 + +  +Речі, які можуть допомогти +* Як відправити ефір, взаємодіючи з ABI +* Як відправити ефір за межами ABI +* Конвертація в одиниці wei/ether та навпаки (див. команду `help()`) +* Запасні методи diff --git a/client/src/gamedata/ua/descriptions/levels/fallback_complete.md b/client/src/gamedata/ua/descriptions/levels/fallback_complete.md new file mode 100644 index 000000000..1fdb45fe3 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/fallback_complete.md @@ -0,0 +1,5 @@ +Ви знаєте основи того, як ефір потрапляє до контрактів і виходить з них, включаючи використання запасного методу. + +Ви також дізналися про контракт Ownable від OpenZeppelin і як він може бути використаний для обмеження використання деяких методів для привілейованої адреси. + +Переходьте на наступний рівень, коли будете готові! diff --git a/client/src/gamedata/ua/descriptions/levels/fallout.md b/client/src/gamedata/ua/descriptions/levels/fallout.md new file mode 100644 index 000000000..10c4c0aea --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/fallout.md @@ -0,0 +1,5 @@ +Заявіть про власність контракту нижче, щоб завершити цей рівень. + +  +Речі, які можуть допомогти +* Solidity Remix IDE diff --git a/client/src/gamedata/ua/descriptions/levels/fallout_complete.md b/client/src/gamedata/ua/descriptions/levels/fallout_complete.md new file mode 100644 index 000000000..d21129e14 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/fallout_complete.md @@ -0,0 +1,15 @@ +Це було дурнувато, чи не так? Контракти у реальному світі повинні бути набагато безпечнішими, і тому їх має бути набагато важче взламати, чи не так? + +Ну... Не зовсім. + +Історія з Rubixi - це дуже відомий випадок в екосистемі Ethereum. Компанія змінила свою назву з 'Dynamic Pyramid' на 'Rubixi', але якось вони не перейменували метод конструктора свого контракту: + +``` +contract Rubixi { + address private owner; + function DynamicPyramid() { owner = msg.sender; } + function collectAllFees() { owner.transfer(this.balance) } + ... +``` + +Це дало змогу атакуючому викликати старий конструктор та претендувати на власність контракту, а також вкрасти деякі кошти. Так. У світі розумних контрактів можуть статися великі помилки. diff --git a/client/src/gamedata/ua/descriptions/levels/force.md b/client/src/gamedata/ua/descriptions/levels/force.md new file mode 100644 index 000000000..3c1dd7155 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/force.md @@ -0,0 +1,9 @@ +Деякі контракти просто не приймуть ваші гроші `¯\_(ツ)_/¯` + +Метою цього рівня є зробити баланс контракту більше нуля. + +  +Речі, які можуть допомогти: +* Запасні методи +* Іноді найкращий спосіб атакувати контракт - це використовувати інший контракт. +* Дивіться сторінку ["?"](https://ethernaut.openzeppelin.com/help) вище, розділ "За рамками консолі" diff --git a/client/src/gamedata/ua/descriptions/levels/force_complete.md b/client/src/gamedata/ua/descriptions/levels/force_complete.md new file mode 100644 index 000000000..5115c1533 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/force_complete.md @@ -0,0 +1,3 @@ +У Solidity, щоб контракт міг отримувати ефір, запасний метод повинен бути позначений як `payable`. + +Однак, немає способу зупинити атакувача від надсилання ефіру до контракту шляхом самознищення. Тому важливо не розраховувати на інваріант `address(this).balance == 0` для будь-якої логіки контракту. diff --git a/client/src/gamedata/ua/descriptions/levels/instances.md b/client/src/gamedata/ua/descriptions/levels/instances.md new file mode 100644 index 000000000..cd4ce7413 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/instances.md @@ -0,0 +1,69 @@ +Цей рівень проводить вас через основи того, як грати в гру. + +  +#### 1. Налаштування MetaMask +Якщо у вас його ще немає, встановіть [розширення MetaMask для браузера](https://metamask.io/) (в Chrome, Firefox, Brave або Opera на вашому настільному комп'ютері). +Налаштуйте гаманець розширення і використовуйте вибір мережі, щоб вказати бажану мережу в верхньому лівому куті інтерфейсу розширення. Або ви можете використовувати кнопку UI для перемикання між мережами. Якщо ви виберете непідтримувану мережу, гра повідомить вас і переведе вас на тестову мережу Sepolia за замовчуванням. + +#### 2. Відкриття консолі браузера +Відкрийте консоль вашого браузера: `Інструменти > Інструменти розробника`. + +Ви повинні побачити кілька повідомлень від гри. Одне з них повинно вказувати адресу вашого гравця. Це буде важливо під час гри! Ви завжди можете побачити адресу вашого гравця, введіть наступну команду: + +`player` + +Слідкуйте за попередженнями та помилками, оскільки вони можуть надати важливу інформацію під час гри. + +#### 3. Використання помічників консолі + +Ви також можете побачити ваш поточний баланс ether, набравши: + +`getBalance(player)` + +###### ЗАМІТКА: Розгорніть обіцянку, щоб побачити реальне значення, навіть якщо воно відображається як "очікується". Якщо ви використовуєте Chrome v62, ви можете використовувати `await getBalance(player)` для більш комфортного використання консолі. + +Чудово! Щоб побачити, які інші службові функції у вас є в консолі, наберіть: + +`help()` + +Вони будуть надзвичайно корисними під час гри. + +#### 4. Контракт ethernaut +Введіть наступну команду в консоль: + +`ethernaut` + +Це основний розумний контракт гри. Вам не потрібно взаємодіяти з ним безпосередньо через консоль (оскільки цей додаток зробить це за вас), але ви можете, якщо хочете. Гратися з цим об'єктом зараз - чудовий спосіб дізнатися, як взаємодіяти з іншими розумними контрактами гри. + +Продовжуйте і розгорніть об'єкт ethernaut, щоб побачити, що всередині. + +#### 5. Взаємодія з ABI +`ethernaut` - це об'єкт `TruffleContract`, який обгортає контракт `Ethernaut.sol`, який був розгорнутий на блокчейні. + +Між іншим, ABI контракту відкриває всі публічні методи `Ethernaut.sol`, такі як `owner`. Наприклад, введіть наступну команду: + +`ethernaut.owner()` або `await ethernaut.owner()`, якщо ви використовуєте Chrome v62. + +Ви можете побачити, хто є власником контракту ethernaut. + +#### 6. Отримання тестового ether +Щоб грати в гру, вам потрібен тестовий ether. Найпростіший спосіб отримати деякий тестовий ether - це через діючий кран для вашої вибраної мережі. + +Як тільки ви побачите деякі монети на своєму балансі, перейдіть до наступного кроку. + +#### 7. Отримання екземпляру рівня +Коли ви граєте на рівні, ви не взаємодієте безпосередньо з контрактом ethernaut. Замість цього, ви просите його створити для вас **екземпляр рівня**. Щоб це зробити, натисніть кнопку "Отримати новий екземпляр" внизу сторінки. Зробіть це зараз та поверніться! + +Вам має бути запропоновано MetaMask авторизувати транзакцію. Зробіть це, і ви повинні побачити деякі повідомлення в консолі. Зверніть увагу, що це впроваджує новий контракт у блокчейн і може зайняти декілька секунд, тому будьте терплячими, коли запитуєте нові екземпляри рівня! + +#### 8. Інспектування контракту +Так само, як ви це зробили з контрактом ethernaut, ви можете інспектувати ABI цього контракту через консоль, використовуючи змінну `contract`. + +#### 9. Взаємодія з контрактом для завершення рівня +Ознайомтеся з методом info рівня `contract.info()` або `await contract.info()`, якщо ви використовуєте Chrome v62. +Ви повинні мати все, що вам потрібно, для завершення рівня в контракті. +Коли ви знаєте, що ви завершили рівень, надішліть контракт, використовуючи кнопку подачі внизу сторінки. +Це відправляє ваш екземпляр назад до ethernaut, який визначить, чи ви його завершили. + + +##### Порада: не забувайте, що ви завжди можете подивитися в ABI контракту! diff --git a/client/src/gamedata/ua/descriptions/levels/instances_complete.md b/client/src/gamedata/ua/descriptions/levels/instances_complete.md new file mode 100644 index 000000000..e5f5e7b36 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/instances_complete.md @@ -0,0 +1,6 @@ +Вітаємо! Ви завершили навчання. +Подивіться на код Solidity для контракту, з яким ви щойно взаємодіяли, нижче. + +Тепер ви готові пройти всі рівні гри, і з цього моменту ви самостійні. + +Швидкого вам просування!! diff --git a/client/src/gamedata/ua/descriptions/levels/king.md b/client/src/gamedata/ua/descriptions/levels/king.md new file mode 100644 index 000000000..e52ba06a7 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/king.md @@ -0,0 +1,5 @@ +Контракт нижче представляє дуже просту гру: той, хто надсилає йому суму ефіру, що більша за поточний приз, стає новим королем. При такій події, звергнутий король отримує новий приз, заробляючи трохи ефіру в процесі! Це чистий понзі xD + +Така весела гра. Ваша мета - зламати її. + +Коли ви подаєте екземпляр назад на рівень, рівень знову проголошує королівство. Ви пройдете рівень, якщо зможете уникнути такого самопроголошення. diff --git a/client/src/gamedata/ua/descriptions/levels/king_complete.md b/client/src/gamedata/ua/descriptions/levels/king_complete.md new file mode 100644 index 000000000..0564a3316 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/king_complete.md @@ -0,0 +1,3 @@ +Більшість рівнів Ethernaut намагається викрити (звичайно, у спрощеній формі) щось, що насправді сталося - реальний хак або реальний баг. + +У цьому випадку, див.: [King of the Ether](https://www.kingoftheether.com/thrones/kingoftheether/index.html) та [King of the Ether Postmortem](http://www.kingoftheether.com/postmortem.html). diff --git a/client/src/gamedata/ua/descriptions/levels/reentrancy.md b/client/src/gamedata/ua/descriptions/levels/reentrancy.md new file mode 100644 index 000000000..c5345960c --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/reentrancy.md @@ -0,0 +1,9 @@ +Мета цього рівня - вкрасти всі кошти з контракту. + +  +Речі, які можуть допомогти: +* Ненадійні контракти можуть виконувати код там, де ви цього найменше очікуєте. +* Запасні методи +* Викидання/відміна бульбашки +* Іноді найкращий спосіб атакувати контракт - це використовувати інший контракт. +* Дивіться сторінку ["?"](https://ethernaut.openzeppelin.com/help) вище, розділ "За консоллю" diff --git a/client/src/gamedata/ua/descriptions/levels/reentrancy_complete.md b/client/src/gamedata/ua/descriptions/levels/reentrancy_complete.md new file mode 100644 index 000000000..1b5cb2744 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/reentrancy_complete.md @@ -0,0 +1,12 @@ +Для того, щоб запобігти атакам реентрантности при виведенні коштів з вашого контракту, використовуйте [паттерн Перевірка-Ефекти-Взаємодії](https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern), пам'ятаючи, що `call` лише поверне false, не перериваючи потік виконання. Можна також використовувати рішення, такі як [ReentrancyGuard](https://docs.openzeppelin.com/contracts/2.x/api/utils#ReentrancyGuard) або [PullPayment](https://docs.openzeppelin.com/contracts/2.x/api/payment#PullPayment). + +`transfer` та `send` вже не рекомендуються, оскільки вони можуть потенційно зламати контракти після хардфорку Istanbul [Джерело 1](https://diligence.consensys.net/blog/2019/09/stop-using-soliditys-transfer-now/) [Джерело 2](https://forum.openzeppelin.com/t/reentrancy-after-istanbul/1742). + +Завжди враховуйте, що одержувач коштів, які ви відправляєте, може бути іншим контрактом, а не просто звичайною адресою. Отже, він може виконувати код у своєму оплачуваному методі запасу і *повторно увійти* у ваш контракт, можливо, зіпсувавши ваш стан/логіку. + +Реентрантність - це поширена атака. Ви повинні завжди бути до неї готові! + +  +#### Хак DAO + +У знаменитій атакі DAO було використано реентрантність для виведення великої суми ефіру з потерпілого контракту. Дивіться [15 рядків коду, які могли б виключити можливість атаки на TheDAO](https://blog.openzeppelin.com/15-lines-of-code-that-could-have-prevented-thedao-hack-782499e00942). diff --git a/client/src/gamedata/ua/descriptions/levels/telephone.md b/client/src/gamedata/ua/descriptions/levels/telephone.md new file mode 100644 index 000000000..1b7332fe0 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/telephone.md @@ -0,0 +1,5 @@ +Заявіть про власність контракту нижче, щоб завершити цей рівень. + +  +Речі, які можуть допомогти +* Див. сторінку ["?"](https://ethernaut.openzeppelin.com/help) вище, розділ "За рамками консолі" diff --git a/client/src/gamedata/ua/descriptions/levels/telephone_complete.md b/client/src/gamedata/ua/descriptions/levels/telephone_complete.md new file mode 100644 index 000000000..6f2faace1 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/telephone_complete.md @@ -0,0 +1,21 @@ +Хоча цей приклад може бути простим, плутанина з `tx.origin` та `msg.sender` може призвести до атак типу "фішинг", таких як [ця](https://blog.ethereum.org/2016/06/24/security-alert-smart-contract-wallets-created-in-frontier-are-vulnerable-to-phishing-attacks/). + +Приклад можливої атаки наведено нижче. + +1) Використовуйте `tx.origin` для визначення, чиї токени перевести, наприклад: + +``` +function transfer(address _to, uint _value) { + tokens[tx.origin] -= _value; + tokens[_to] += _value; +} +``` +2) Атакуючий змушує жертву надіслати кошти зловмисному контракту, який викликає функцію переводу контракту токенів, наприклад: + +``` +function () payable { + token.transfer(attackerAddress, 10000); +} +``` + +3) У цьому сценарії `tx.origin` буде адресою жертви (поки `msg.sender` буде адресою зловмисного контракту), що призведе до переказу коштів від жертви до атакуючого. diff --git a/client/src/gamedata/ua/descriptions/levels/token.md b/client/src/gamedata/ua/descriptions/levels/token.md new file mode 100644 index 000000000..f897e97d9 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/token.md @@ -0,0 +1,7 @@ +Метою цього рівня є те, щоб вам взламати основний контракт токену нижче. + +Вам дається 20 токенів на початку, і ви пройдете рівень, якщо якимось чином зумієте заволодіти будь-якими додатковими токенами. Бажано дуже великою кількістю токенів. + +  +Речі, які можуть допомогти: +* Що таке одометр? diff --git a/client/src/gamedata/ua/descriptions/levels/token_complete.md b/client/src/gamedata/ua/descriptions/levels/token_complete.md new file mode 100644 index 000000000..eec73360d --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/token_complete.md @@ -0,0 +1,12 @@ +Переповнення дуже поширені в Solidity і їх потрібно перевіряти за допомогою контрольних операторів, таких як: +``` +if(a + c > a) { + a = a + c; +} +``` + +Легшою альтернативою є використання бібліотеки SafeMath від OpenZeppelin, яка автоматично перевіряє переповнення у всіх математичних операторах. Вихідний код виглядає так: +``` +a = a.add(c); +``` +Якщо стається переповнення, код відкочується. diff --git a/client/src/gamedata/ua/descriptions/levels/vault.md b/client/src/gamedata/ua/descriptions/levels/vault.md new file mode 100644 index 000000000..371e34871 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/vault.md @@ -0,0 +1 @@ +Відкрийте сховище, щоб пройти рівень! diff --git a/client/src/gamedata/ua/descriptions/levels/vault_complete.md b/client/src/gamedata/ua/descriptions/levels/vault_complete.md new file mode 100644 index 000000000..be17ca758 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/vault_complete.md @@ -0,0 +1,3 @@ +Важливо пам'ятати, що позначення змінної як приватної лише перешкоджає доступу до неї інших контрактів. Змінні стану, позначені як приватні, та локальні змінні все ще доступні публічно. + +Щоб гарантувати, що дані є приватними, їх потрібно шифрувати перед тим, як вносити на блокчейн. У цьому сценарії ключ розшифровки ніколи не повинен надсилатися в блокчейн, оскільки тоді він буде видимий для всіх, хто його шукає. [zk-SNARKs](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/) надають спосіб визначити, чи має хтось секретний параметр, не розкриваючи ніколи цей параметр. diff --git a/client/src/gamedata/ua/strings.json b/client/src/gamedata/ua/strings.json index fd2952ad3..0a3cd6865 100644 --- a/client/src/gamedata/ua/strings.json +++ b/client/src/gamedata/ua/strings.json @@ -2,7 +2,7 @@ "ethernaut": "Ethernaut", "title": "Ethernaut", "hiring": "Ми наймаємо", - "info": "

Ethernaut це Web3/Solidity варгейм на базі Ethereum Virtual Machine, натхненний overthewire.org. Кожен рівень є смарт-контрактом, який потрібно 'зламати'. Вихідний код гри повністю відкритий, а всі рівні створені іншими гравцями. У тебе є цікава ідея для нового рівня? !

", + "info": "

Ethernaut це Web3/Solidity варгейм на базі Ethereum Virtual Machine, натхненний overthewire.org. Кожен рівень є смарт-контрактом, який потрібно 'зламати'. Вихідний код гри повністю відкритий, а всі рівні створені іншими гравцями. У тебе є цікава ідея для нового рівня?

", "home": "Назад", "help": "Допомога", "stats": "Статистика", @@ -94,7 +94,7 @@ "helperGetNetworkId": "отримати ідентифікатор мережі", "helperToWei": "конвертувати число з ефіру в вей", "helperFromWei": "конвертувати число з вей в ефір", - "levelNotTranslated": "Цей рівень не перекладено українською мовою або переклад не завершено", + "levelNotTranslated": "Цей рівень не перекладено українською мовою або переклад не завершено. ", "contributeTranslation": "Вдосконалити переклад", "usingConsole": "Взаємодія з грою відбувається через консоль браузера. Щоб отримати список об'єктів та функцій, які допоможуть вам у грі, введіть у консолі браузера команду:\n\nhelp()\n\n Більшість функцій асинхронні, тому вам знадобиться ключове слово await. Наприклад, замість:\n\ngetBalance(player)\n> PROMISE\n\nкраще використовувати:\n\nawait getBalance(player)\n> '1.11002387'\n\n", "gameMechanics": "За допомогою веб-інтерфейсу гравець запитує створення нового інстансу. Запит направляється в контракт Ethernaut.sol, який, у свою чергу, делегує запит відповідному рівню, кожен з яких успадковується від контракта Level.sol та створює новий інстанс. Після цього гравець взаємодіє з інстансом до тих пір, поки не 'зламає' його, після чого надсилає інстанс на перевірку за допомогою веб-інтерфейса.\n\nЗ кожним інстансом можна взаємодіяти через консоль браузера як з об'єктом типу TruffleContract. Більше інформації про механіку гри можна знайти в описі першого рівня.", From dfcfb8d56d3454bcfed4ef2b031bac545f25dd4b Mon Sep 17 00:00:00 2001 From: boivlad Date: Tue, 25 Jul 2023 16:13:00 +0300 Subject: [PATCH 3/7] feat: added ua translates part 3 --- .../gamedata/ua/descriptions/levels/denial.md | 3 + .../ua/descriptions/levels/denial_complete.md | 7 +++ .../gamedata/ua/descriptions/levels/dex.md | 18 ++++++ .../gamedata/ua/descriptions/levels/dex2.md | 9 +++ .../ua/descriptions/levels/dex2_complete.md | 9 +++ .../ua/descriptions/levels/dex_complete.md | 59 +++++++++++++++++++ .../descriptions/levels/doubleentrypoint.md | 10 ++++ .../levels/doubleentrypoint_complete.md | 13 ++++ .../ua/descriptions/levels/elevator.md | 5 ++ .../descriptions/levels/elevator_complete.md | 4 ++ .../ua/descriptions/levels/gatekeeper1.md | 5 ++ .../levels/gatekeeper1_complete.md | 1 + .../ua/descriptions/levels/gatekeeper2.md | 6 ++ .../levels/gatekeeper2_complete.md | 1 + .../ua/descriptions/levels/gatekeeper3.md | 6 ++ .../levels/gatekeeper3_complete.md | 1 + .../ua/descriptions/levels/magicnum.md | 11 ++++ .../descriptions/levels/magicnum_complete.md | 3 + .../ua/descriptions/levels/motorbike.md | 9 +++ .../descriptions/levels/motorbike_complete.md | 9 +++ .../ua/descriptions/levels/naughtcoin.md | 6 ++ .../levels/naughtcoin_complete.md | 1 + .../ua/descriptions/levels/preservation.md | 11 ++++ .../levels/preservation_complete.md | 5 ++ .../ua/descriptions/levels/privacy.md | 11 ++++ .../descriptions/levels/privacy_complete.md | 3 + .../ua/descriptions/levels/puzzle_wallet.md | 18 ++++++ .../levels/puzzle_wallet_complete.md | 7 +++ .../ua/descriptions/levels/recovery.md | 3 + .../descriptions/levels/recovery_complete.md | 7 +++ .../gamedata/ua/descriptions/levels/shop.md | 5 ++ .../ua/descriptions/levels/shop_complete.md | 3 + 32 files changed, 269 insertions(+) create mode 100644 client/src/gamedata/ua/descriptions/levels/denial.md create mode 100644 client/src/gamedata/ua/descriptions/levels/denial_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/dex.md create mode 100644 client/src/gamedata/ua/descriptions/levels/dex2.md create mode 100644 client/src/gamedata/ua/descriptions/levels/dex2_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/dex_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/doubleentrypoint.md create mode 100644 client/src/gamedata/ua/descriptions/levels/doubleentrypoint_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/elevator.md create mode 100644 client/src/gamedata/ua/descriptions/levels/elevator_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper1.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper1_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper2.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper2_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper3.md create mode 100644 client/src/gamedata/ua/descriptions/levels/gatekeeper3_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/magicnum.md create mode 100644 client/src/gamedata/ua/descriptions/levels/magicnum_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/motorbike.md create mode 100644 client/src/gamedata/ua/descriptions/levels/motorbike_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/naughtcoin.md create mode 100644 client/src/gamedata/ua/descriptions/levels/naughtcoin_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/preservation.md create mode 100644 client/src/gamedata/ua/descriptions/levels/preservation_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/privacy.md create mode 100644 client/src/gamedata/ua/descriptions/levels/privacy_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/puzzle_wallet.md create mode 100644 client/src/gamedata/ua/descriptions/levels/puzzle_wallet_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/recovery.md create mode 100644 client/src/gamedata/ua/descriptions/levels/recovery_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/shop.md create mode 100644 client/src/gamedata/ua/descriptions/levels/shop_complete.md diff --git a/client/src/gamedata/ua/descriptions/levels/denial.md b/client/src/gamedata/ua/descriptions/levels/denial.md new file mode 100644 index 000000000..dabcbf7d7 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/denial.md @@ -0,0 +1,3 @@ +Це простий гаманець, який випускає кошти з часом. Ви можете повільно знімати кошти, ставши партнером по зняттю. + +Якщо ви зможете заборонити власнику знімати кошти, коли він викликає `withdraw()` (поки у контракті ще є кошти, і транзакція становить 1М газу або менше), ви виграєте цей рівень. diff --git a/client/src/gamedata/ua/descriptions/levels/denial_complete.md b/client/src/gamedata/ua/descriptions/levels/denial_complete.md new file mode 100644 index 000000000..c3d3f6eed --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/denial_complete.md @@ -0,0 +1,7 @@ +Цей рівень демонструє, що зовнішні виклики до невідомих контрактів все ще можуть створювати вектори атаки на відмову у обслуговуванні, якщо не вказано фіксовану кількість газу. + +Якщо ви використовуєте низькорівневий `call` для продовження виконання у разі відкату зовнішнього виклику, переконайтеся, що ви вказали фіксовану кількість газу. Наприклад, `call.gas(100000).value()`. + +Зазвичай слід дотримуватися шаблону [checks-effects-interactions](http://solidity.readthedocs.io/en/latest/security-considerations.html#use-the-checks-effects-interactions-pattern), щоб уникнути атак на повторний вхід, але можуть виникнути інші обставини (наприклад, кілька зовнішніх викликів в кінці функції), де можуть виникнути такі проблеми. + +*Примітка*: Зовнішній `CALL` може використовувати не більше 63/64 від поточно доступного газу на момент `CALL`. Таким чином, залежно від того, скільки газу потрібно для завершення транзакції, можна використовувати транзакцію з достатньо високим газом (тобто таку, що 1/64 газу здатна завершити залишкові опкоди в батьківському виклику), щоб зменшити цю конкретну атаку. diff --git a/client/src/gamedata/ua/descriptions/levels/dex.md b/client/src/gamedata/ua/descriptions/levels/dex.md new file mode 100644 index 000000000..3b4dc2f19 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/dex.md @@ -0,0 +1,18 @@ +Мета цього рівня полягає в тому, щоб ви зламали базовий контракт [DEX](https://en.wikipedia.org/wiki/Decentralized_exchange), що наведений нижче, та вкрали кошти, маніпулюючи ціною. + +Ви починаєте з 10 токенами `token1` та 10 токенами `token2`. У контракті DEX початково є 100 кожного токена. + +Цей рівень буде успішно пройдено, якщо вам вдасться вичерпати всі токени одного з двох видів від контракту та змусити контракт повідомити "некоректну" ціну активів. + +  +### Коротке зауваження +Зазвичай, коли ви робите обмін з токеном ERC20, вам потрібно `approve` контракту витратити ваші токени за вас. Щоб зберегти синтаксис гри, ми просто додали метод `approve` до самого контракту. Тому не соромтеся використовувати `contract.approve(contract.address, )` замість безпосереднього виклику токенів, і він автоматично схвалить витрату обох токенів на бажану суму. Будь ласка, ігноруйте контракт `SwappableToken`. + +  +Речі, які можуть допомогти: +* Як розраховується ціна токена? +* Як працює метод `swap`? +* Як ви `approve` транзакцію з ERC20? +* Існує більше ніж один спосіб взаємодії з контрактом! +* Remix може допомогти +* Що робить "At Address"? diff --git a/client/src/gamedata/ua/descriptions/levels/dex2.md b/client/src/gamedata/ua/descriptions/levels/dex2.md new file mode 100644 index 000000000..dbbc2d98c --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/dex2.md @@ -0,0 +1,9 @@ +Цей рівень попросить вас зламати `DexTwo`, контракт `Dex`, що був дещо змінений відносно попереднього рівня, іншим способом. + +Вам потрібно вичерпати всі баланси token1 та token2 з контракту `DexTwo`, щоб пройти цей рівень. + +Ви все ще починаєте з 10 токенами `token1` та 10 токенами `token2`. У контракті DEX досі є 100 кожного токена. + +  +Речі, які можуть допомогти: +* Як було змінено метод `swap`? diff --git a/client/src/gamedata/ua/descriptions/levels/dex2_complete.md b/client/src/gamedata/ua/descriptions/levels/dex2_complete.md new file mode 100644 index 000000000..a54d1ec61 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/dex2_complete.md @@ -0,0 +1,9 @@ +Як ми неодноразово бачили, взаємодія між контрактами може бути джерелом несподіваної поведінки. + +Те, що контракт претендує на реалізацію [специфікації ERC20](https://eips.ethereum.org/EIPS/eip-20), не означає, що йому можна довіряти. + +Деякі токени відхиляються від специфікації ERC20, не повертаючи булеве значення зі своїх методів `transfer`. Дивіться [Missing return value bug - At least 130 tokens affected](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). + +Інші токени ERC20, особливо ті, що були розроблені ворогами, можуть поводитися більш зловмисно. + +Якщо ви створюєте DEX, де будь-хто може вивести свої токени без дозволу центральної влади, то правильність DEX може залежати від взаємодії контракту DEX і контрактів токенів, що обмінюються. diff --git a/client/src/gamedata/ua/descriptions/levels/dex_complete.md b/client/src/gamedata/ua/descriptions/levels/dex_complete.md new file mode 100644 index 000000000..e210a5c81 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/dex_complete.md @@ -0,0 +1,59 @@ +За виключенням частини, що стосується цілочисельної математики, отримання цін або будь-яких даних від будь-якого єдиного джерела є великим вектором атаки в розумних контрактах. + +Ви ясно бачите з цього прикладу, що людина з великим капіталом може маніпулювати ціною одним рухом, що призведе до того, що всі застосунки, що використовують ціну, будуть використовувати неправильну ціну. + +Обмін сам по собі є децентралізованим, але ціна активу є централізованою, оскільки вона походить з одного dex. Однак, якщо ми розглядатимемо токени, що представляють справжні активи, а не вигадані, більшість з них матимуть пари обміну на декількох dexes і мережах. Це зменшить вплив на ціну активу у разі специфічного dex, який став мішенню для такої атаки. + +[Оракули](https://betterprogramming.pub/what-is-a-blockchain-oracle-f5ccab8dbd72?source=friends_link&sk=d921a38466df8a9176ed8dd767d8c77d) використовуються для отримання даних в розумні контракти і з них. + +[Chainlink Data Feeds](https://docs.chain.link/docs/get-the-latest-price) - це безпечний, надійний спосіб отримати децентралізовані дані в ваших розумних контрактах. Вони мають велику бібліотеку з багатьма різними джерелами, а також пропонують [безпечний випадковий](https://docs.chain.link/docs/chainlink-vrf), можливість робити [будь-який API виклик](https://docs.chain.link/docs/make-a-http-get-request), [створення модульної мережі оракулів](https://docs.chain.link/docs/architecture-decentralized-model), [технічне обслуговування, дії та обслуговування](https://docs.chain.link/docs/kovan-keeper-network-beta), та необмежене налаштування. + +[Uniswap TWAP Oracles](https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles) покладаються на модель вагової ціни в часі, відому як [TWAP](https://en.wikipedia.org/wiki/Time-weighted_average_price#). Хоча дизайн може бути привабливим, цей протокол сильно залежить від ліквідності протоколу DEX, і якщо вона дуже низька, ціни можна легко маніпулювати. + + +Ось приклад отримання ціни на Bitcoin в USD з каналу даних Chainlink (на тестовій мережі Sepolia): + +``` +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.7; + +import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; + +contract PriceConsumerV3 { + AggregatorV3Interface internal priceFeed; + + /** + * Network: Sepolia + * Aggregator: BTC/USD + * Address: 0 + +x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 + */ + constructor() { + priceFeed = AggregatorV3Interface( + 0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43 + ); + } + + /** + * Returns the latest price. + */ + function getLatestPrice() public view returns (int) { + // prettier-ignore + ( + /* uint80 roundID */, + int price, + /*uint startedAt*/, + /*uint timeStamp*/, + /*uint80 answeredInRound*/ + ) = priceFeed.latestRoundData(); + return price; + } +} + +``` +[Спробуйте на Remix](https://remix.ethereum.org/#url=https://docs.chain.link/samples/PriceFeeds/PriceConsumerV3.sol) + +Перевірте сторінку з каналом даних Chainlink [тут](https://data.chain.link/ethereum/mainnet/crypto-usd/btc-usd), щоб побачити, що ціна на Bitcoin запитується з до 31 різного джерела. + +Ви також можете перевірити [список](https://docs.chain.link/data-feeds/price-feeds/addresses/) всіх адрес каналів даних Chainlink. diff --git a/client/src/gamedata/ua/descriptions/levels/doubleentrypoint.md b/client/src/gamedata/ua/descriptions/levels/doubleentrypoint.md new file mode 100644 index 000000000..b27972a57 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/doubleentrypoint.md @@ -0,0 +1,10 @@ +Цей рівень представляє `CryptoVault` з особливою функціональністю - функцією `sweepToken`. Це звичайна функція, що використовується для отримання токенів, які застрягли в контракті. `CryptoVault` працює з `underlying` токеном, який не можна "замести", оскільки він є важливим компонентом ядра `CryptoVault`. Будь-які інші токени можна "замести". + +Основний токен - це екземпляр токена DET, реалізований у визначенні контракту `DoubleEntryPoint`, і в `CryptoVault` зберігається 100 одиниць цього токена. Крім того, `CryptoVault` також містить 100 `LegacyToken LGT`. + +На цьому рівні вам слід виявити, де в `CryptoVault` помилка, і захистити його від витікання токенів. + +Контракт містить контракт `Forta`, де будь-який користувач може зареєструвати свій власний контракт `detection bot`. Forta - це децентралізована, заснована на спільноті мережа моніторингу, яка виявляє загрози та аномалії в DeFi, NFT, управлінні, мостах та інших системах Web3 якомога швидше. Ваше завдання - реалізувати `detection bot` і зареєструвати його в контракті `Forta`. Реалізація бота повинна викликати відповідні сповіщення, щоб запобігти потенційним атакам або експлуатації помилок. + +Речі, які можуть допомогти: +- Як працює подвійна точка входу для контракту токена? diff --git a/client/src/gamedata/ua/descriptions/levels/doubleentrypoint_complete.md b/client/src/gamedata/ua/descriptions/levels/doubleentrypoint_complete.md new file mode 100644 index 000000000..a2b683e04 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/doubleentrypoint_complete.md @@ -0,0 +1,13 @@ +Вітаємо! + +Це ваш перший досвід роботи з [ботом Forta](https://docs.forta.network/en/latest/). + +Forta включає в себе децентралізовану мережу незалежних операторів вузлів, які сканують усі транзакції та зміни стану блок за блоком для виявлення викидів транзакцій та загроз. Коли виявляється проблема, оператори вузлів надсилають попередження передплатникам про потенційні ризики, що дозволяє їм вжити заходів. + +Представлений приклад призначений лише для навчальних цілей, оскільки бот Forta не моделюється у розумних контрактах. У Forta бот - це скрипт коду для виявлення специфічних умов або подій, але коли випускається сповіщення, воно не запускає автоматичні дії - принаймні, поки що. На цьому рівні сповіщення бота ефективно викликає відкат транзакції, відхиляючись від призначеного дизайну бота Forta. + +Боти для виявлення сильно залежать від остаточних реалізацій контрактів, і деякі з них можуть бути оновлюваними та ламати інтеграції ботів, але для зменшення цього ви можете навіть створити специфічного бота для пошуку оновлень контрактів і реагування на них. Дізнайтеся, як це зробити [тут](https://docs.forta.network/en/latest/quickstart/). + +Ви також пройшли через недавній проблему безпеки, яка була виявлена під час останньої [співпраці OpenZeppelin з протоколом Compound](https://compound.finance/governance/proposals/76). + +Наявність токенів, які представляють подвійну точку входу, є нетривіальним шаблоном, який може вплинути на багато протоколів. Це тому, що зазвичай припускається, що на один токен припадає один контракт. Але цього разу це було не так :) Ви можете прочитати всі деталі того, що сталося, [тут](https://blog.openzeppelin.com/compound-tusd-integration-issue-retrospective/). diff --git a/client/src/gamedata/ua/descriptions/levels/elevator.md b/client/src/gamedata/ua/descriptions/levels/elevator.md new file mode 100644 index 000000000..ea7c74855 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/elevator.md @@ -0,0 +1,5 @@ +Цей ліфт не дозволить вам дістатися верхнього поверху вашого будинку. Правильно? + +##### Речі, які можуть допомогти: +* Інколи solidity не дуже добре дотримується обіцянок. +* Цей `Elevator` очікує, що його буде використовувати `Building`. diff --git a/client/src/gamedata/ua/descriptions/levels/elevator_complete.md b/client/src/gamedata/ua/descriptions/levels/elevator_complete.md new file mode 100644 index 000000000..1c0ecfe62 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/elevator_complete.md @@ -0,0 +1,4 @@ +Ви можете використовувати модифікатор `view` у інтерфейсі, щоб запобігти змінам стану. Модифікатор `pure` також запобігає змінам стану функціями. +Переконайтеся, що ви прочитали [документацію Solidity](http://solidity.readthedocs.io/en/develop/contracts.html#view-functions) та зрозуміли її нюанси. + +Альтернативний спосіб вирішення цього рівня полягає у створенні view-функції, яка повертає різні результати залежно від вхідних даних, але не змінює стан, наприклад, `gasleft()`. diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper1.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper1.md new file mode 100644 index 000000000..71d2a2da6 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper1.md @@ -0,0 +1,5 @@ +Пройдіть повз вартового та зареєструйтеся як учасник, щоб пройти цей рівень. + +##### Що може допомогти: +* Пам'ятайте, що ви навчилися на рівнях Telephone та Token. +* Ви можете дізнатися більше про спеціальну функцію `gasleft()`, в документації Solidity (див. [тут](https://docs.soliditylang.org/en/v0.8.3/units-and-global-variables.html) та [тут](https://docs.soliditylang.org/en/v0.8.3/control-structures.html#external-function-calls)). diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper1_complete.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper1_complete.md new file mode 100644 index 000000000..9da8edda9 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper1_complete.md @@ -0,0 +1 @@ +Молодець! Тепер спробуйте свої сили з другим вартовим... diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper2.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper2.md new file mode 100644 index 000000000..374057430 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper2.md @@ -0,0 +1,6 @@ +Цей вартовий представляє декілька нових викликів. Зареєструйтеся як учасник, щоб пройти цей рівень. + +##### Що може допомогти: +* Пам'ятайте, чого ви навчилися, обходячи першого вартового - перший шлюз залишився тим самим. +* Ключове слово `assembly` у другому шлюзі дозволяє контракту отримувати доступ до функціональності, яка не є рідною для чистого Solidity. Дивіться [тут](http://solidity.readthedocs.io/en/v0.4.23/assembly.html) для отримання додаткової інформації. Виклик `extcodesize` в цьому шлюзі отримує розмір коду контракту за заданою адресою - ви можете дізнатися більше про те, як і коли він встановлюється, у розділі 7 [жовтої брошури](https://ethereum.github.io/yellowpaper/paper.pdf). +* Символ `^` у третьому шлюзі - це операція з бітовими масками (XOR), і вона використовується тут для застосування іншої поширеної бітової операції (дивіться [тут](http://solidity.readthedocs.io/en/v0.4.23/miscellaneous.html#cheatsheet)). Рівень Coin Flip також є хорошим початком при підході до цього виклику. diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper2_complete.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper2_complete.md new file mode 100644 index 000000000..d3db92fbd --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper2_complete.md @@ -0,0 +1 @@ +Чудова робота! Тепер, коли ви можете обійти вартового, у вас є те, що потрібно, щоб приєднатися до [theCyber](https://etherscan.io/address/thecyber.eth#code), децентралізованого клубу в основній мережі Ethereum. Отримайте пароль, зв'язавшись зі створювачем на [reddit](https://www.reddit.com/user/0age) або через [email](mailto:0age@protonmail.com) та використайте його для реєстрації з контрактом на [gatekeepertwo.thecyber.eth](https://etherscan.io/address/gatekeepertwo.thecyber.eth#code) (майте на увазі, що контракт прийме лише перших 128 учасників). diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper3.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper3.md new file mode 100644 index 000000000..7616a6fea --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper3.md @@ -0,0 +1,6 @@ +Впорайтеся з воротами та станьте учасником. + +##### Що може допомогти: +* Пригадайте значення, що повертають низькорівневі функції. +* Будьте уважні до семантики. +* Оновіть свої знання про те, як працює зберігання в Ethereum. diff --git a/client/src/gamedata/ua/descriptions/levels/gatekeeper3_complete.md b/client/src/gamedata/ua/descriptions/levels/gatekeeper3_complete.md new file mode 100644 index 000000000..c11c2664e --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/gatekeeper3_complete.md @@ -0,0 +1 @@ +Добра робота! Для отримання більш детальної інформації прочитайте [це](https://web3js.readthedocs.io/en/v1.2.9/web3-eth.html?highlight=getStorageAt#getstorageat) та [це](https://medium.com/loom-network/ethereum-solidity-memory-vs-storage-how-to-initialize-an-array-inside-a-struct-184baf6aa2eb). diff --git a/client/src/gamedata/ua/descriptions/levels/magicnum.md b/client/src/gamedata/ua/descriptions/levels/magicnum.md new file mode 100644 index 000000000..7841954f6 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/magicnum.md @@ -0,0 +1,11 @@ +Щоб вирішити цей рівень, вам потрібно лише надати Ethernaut `Solver`, контракту, який відповідає на `whatIsTheMeaningOfLife()` з правильним числом. + +Легко, правда? +Ну... є одне "але". + +Код вирішувача повинен бути дуже маленьким. Дійсно дууууже маленьким. Як справді дуже, дуже мініатюрний: максимум 10 опкодів. + +Підказка: Можливо, настав час на мить покинути комфорт компілятора Solidity і скласти цей один вручну O_o. +Так, ми говоримо про сиру EVM байт-коду. + +Удачі! diff --git a/client/src/gamedata/ua/descriptions/levels/magicnum_complete.md b/client/src/gamedata/ua/descriptions/levels/magicnum_complete.md new file mode 100644 index 000000000..2ddfb65c3 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/magicnum_complete.md @@ -0,0 +1,3 @@ +Вітаємо! Якщо ви вирішили цей рівень, вважайте себе Володарем Всесвіту. + +Тепер ви можете пронизати своїм взором будь-який предмет у кімнаті. Спробуйте перемістити його здалеку; можливо, у вас щойно почали працювати здібності телекінезу. diff --git a/client/src/gamedata/ua/descriptions/levels/motorbike.md b/client/src/gamedata/ua/descriptions/levels/motorbike.md new file mode 100644 index 000000000..8bff70b3c --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/motorbike.md @@ -0,0 +1,9 @@ +Мотоцикл Ethernaut має новий двигун з можливістю модернізації. + +Чи зможете ви `selfdestruct` його двигун і зробити мотоцикл непридатним для використання? + +Речі, які можуть допомогти: + +- [EIP-1967](https://eips.ethereum.org/EIPS/eip-1967) +- Шаблон модернізації [UUPS](https://forum.openzeppelin.com/t/uups-proxies-tutorial-solidity-javascript/7786) +- Контракт [Initializable](https://github.com/OpenZeppelin/openzeppelin-upgrades/blob/master/packages/core/contracts/Initializable.sol) diff --git a/client/src/gamedata/ua/descriptions/levels/motorbike_complete.md b/client/src/gamedata/ua/descriptions/levels/motorbike_complete.md new file mode 100644 index 000000000..a59840466 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/motorbike_complete.md @@ -0,0 +1,9 @@ +Перевагою використання шаблону UUPS є мінімальний проксі, який потрібно розгорнути. Проксі виступає як шар зберігання, тому будь-яка модифікація стану в контракті-реалізації зазвичай не викликає побічних ефектів для систем, що використовують його, оскільки через delegatecall використовується тільки логіка. + +Це не означає, що вам не слід бути обережними з вразливостями, які можуть бути експлуатовані, якщо ми залишимо контракт-реалізацію неініціалізованим. + +Це була трохи спрощена версія того, що насправді було виявлено через кілька місяців після випуску шаблону UUPS. + +Висновки: ніколи не залишайте контракти-реалізації неініціалізованими ;) + +Якщо ви зацікавлені в тому, що сталося, дізнайтеся більше [тут](https://forum.openzeppelin.com/t/uupsupgradeable-vulnerability-post-mortem/15680). diff --git a/client/src/gamedata/ua/descriptions/levels/naughtcoin.md b/client/src/gamedata/ua/descriptions/levels/naughtcoin.md new file mode 100644 index 000000000..5c7fd068b --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/naughtcoin.md @@ -0,0 +1,6 @@ +NaughtCoin є токеном ERC20 і ви вже володієте всіма їхніми копіями. Але існує певне "але" - ви зможете переказати їх тільки після 10-річного періоду блокування. Ви зможете знайти спосіб вивести їх на іншу адресу, щоб ви могли переказувати їх вільно? Завершіть цей рівень, знизивши баланс своїх токенів до 0. + +  +Може бути корисним: +* Специфікація [ERC20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md) +* База коду [OpenZeppelin](https://github.com/OpenZeppelin/zeppelin-solidity/tree/master/contracts) diff --git a/client/src/gamedata/ua/descriptions/levels/naughtcoin_complete.md b/client/src/gamedata/ua/descriptions/levels/naughtcoin_complete.md new file mode 100644 index 000000000..a4c797006 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/naughtcoin_complete.md @@ -0,0 +1 @@ +Коли ви використовуєте код, який не є вашим власним, гарною ідеєю буде ознайомитись з ним, щоб добре зрозуміти, як все співпрацює. Це може бути особливо важливим, коли є кілька рівнів імпорту (ваши імпорти мають імпорти) або коли ви впроваджуєте контроль за доступом, наприклад, коли ви дозволяєте або забороняєте людям щось робити. У цьому прикладі розробник може просканувати код і подумати, що `transfer` - це єдиний спосіб переміщення токенів, але виявляється, існують інші способи виконання тієї самої операції з іншою реалізацією. diff --git a/client/src/gamedata/ua/descriptions/levels/preservation.md b/client/src/gamedata/ua/descriptions/levels/preservation.md new file mode 100644 index 000000000..ab3b7ca52 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/preservation.md @@ -0,0 +1,11 @@ +Цей контракт використовує бібліотеку для зберігання двох різних часів для двох різних часових поясів. Конструктор створює два екземпляри бібліотеки для кожного часу, який потрібно зберегти. + +Мета цього рівня - претендувати на власність над екземпляром, який вам надано. + +  Речі, які можуть допомогти +* Перегляньте документацію Solidity про функцію низького рівня `delegatecall`, + як вона працює, як вона може бути використана для делегування операцій до бібліотек на ланцюгу, + і які наслідки вона має для контексту виконання. +* Розуміння того, що означає "зберігання контексту" для `delegatecall`. +* Розуміння того, як змінні зберігаються та доступні. +* Розуміння того, як працює приведення типів між різними типами даних. diff --git a/client/src/gamedata/ua/descriptions/levels/preservation_complete.md b/client/src/gamedata/ua/descriptions/levels/preservation_complete.md new file mode 100644 index 000000000..b388076dc --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/preservation_complete.md @@ -0,0 +1,5 @@ +Як згадує попередній рівень `delegate`, використання `delegatecall` для виклику +бібліотек може бути ризикованим. Це особливо стосується контрактних бібліотек, які +мають свій власний стан. Цей приклад демонструє, чому слід використовувати ключове слово `library` +для створення бібліотек, оскільки воно перешкоджає бібліотекам +зберігання та доступ до змінних стану. diff --git a/client/src/gamedata/ua/descriptions/levels/privacy.md b/client/src/gamedata/ua/descriptions/levels/privacy.md new file mode 100644 index 000000000..7d80f2bd6 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/privacy.md @@ -0,0 +1,11 @@ +Творець цього контракту був достатньо обережний, щоб захистити чутливі області свого зберігання. + +Розблокуйте цей контракт, щоб пройти рівень. + +Що може допомогти: +* Розуміння того, як працює зберігання +* Розуміння того, як працює парсинг параметрів +* Розуміння того, як працює приведення типів + +Поради: +* Пам'ятайте, що metamask - це лише зручність. Використовуйте інший інструмент, якщо виникають проблеми. Просунута гра може включати використання remix або вашого власного провайдера web3. diff --git a/client/src/gamedata/ua/descriptions/levels/privacy_complete.md b/client/src/gamedata/ua/descriptions/levels/privacy_complete.md new file mode 100644 index 000000000..8f642db5e --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/privacy_complete.md @@ -0,0 +1,3 @@ +Ніщо в блокчейні Ethereum не є приватним. Ключове слово private - це лише штучна конструкція мови Solidity. `getStorageAt(...)` від Web3 можна використовувати для читання будь-чого зі зберігання. Однак, може бути складно прочитати те, що вам потрібно, оскільки використовуються декілька правил оптимізації та технік для максимального стиснення зберігання. + +Не можна ускладнити ситуацію більше, ніж те, що було виявлено на цьому рівні. Для отримання додаткової інформації перегляньте цю чудову статтю від "Darius": [Як читати зберігання контракту Ethereum](https://medium.com/aigang-network/how-to-read-ethereum-contract-storage-44252c8af925) diff --git a/client/src/gamedata/ua/descriptions/levels/puzzle_wallet.md b/client/src/gamedata/ua/descriptions/levels/puzzle_wallet.md new file mode 100644 index 000000000..d5b8b8661 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/puzzle_wallet.md @@ -0,0 +1,18 @@ +В наш час, оплата за операції DeFi є неможливою, факт. + +Група друзів виявила спосіб трохи зменшити вартість виконання кількох транзакцій, об'єднавши їх в одну транзакцію, тому вони розробили смарт-контракт для цього. + +Вони потребували, щоб цей контракт міг бути модернізований у випадку, якщо код містить помилку, і вони також хотіли запобігти використанню контракту людьми, що не належать до групи. Щоб цього досягти, вони проголосували та призначили двох людей з особливими ролями в системі: +Адміністратор, який має право оновлювати логіку смарт-контракту. +Власник, який контролює білий список адрес, дозволених для використання контрактом. +Контракти були розгорнуті, і група була внесена до білого списку. Всі віталися з їхніми досягненнями проти злих майнерів. + +Вони мало знали, що їх гроші на обід були під загрозою... + +  +Вам потрібно буде перехопити цей гаманець, щоб стати адміністратором проксі. + +  +Речі, які можуть допомогти: +* Розуміння того, як працює `delegatecall` та як поводиться `msg.sender` та `msg.value` при його виконанні. +* Знання про шаблони проксі та спосіб їх обробки змінних зберігання. diff --git a/client/src/gamedata/ua/descriptions/levels/puzzle_wallet_complete.md b/client/src/gamedata/ua/descriptions/levels/puzzle_wallet_complete.md new file mode 100644 index 000000000..3f1622587 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/puzzle_wallet_complete.md @@ -0,0 +1,7 @@ +На наступний раз ці друзі запросять аудиторську перевірку, перш ніж внести гроші в контракт. Вітаємо! + +Часто рекомендується використовувати проксі-контракти, щоб забезпечити можливість модернізації та зменшити витрати газу на розгортання. Проте розробники повинні бути обережні, щоб не виникло зіткнень у зберіганні, як це було в цьому рівні. + +Додатково, ітерування над операціями, що споживають ETH, може призвести до проблем, якщо це не контролюється відповідним чином. Навіть якщо ETH витрачено, `msg.value` залишиться таким же, тому розробник повинен самостійно відстежувати фактичну залишкову кількість при кожній ітерації. Це також може призвести до проблем при використанні мульти-виклику, оскільки виконання кількох `delegatecall` до функції, яка виглядає безпечною сама по собі, може призвести до небажаних переказів ETH, оскільки `delegatecall` зберігає оригінальний `msg.value`, відправлений контракту. + +Перейдіть на наступний рівень, коли будете готові! diff --git a/client/src/gamedata/ua/descriptions/levels/recovery.md b/client/src/gamedata/ua/descriptions/levels/recovery.md new file mode 100644 index 000000000..98c68d161 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/recovery.md @@ -0,0 +1,3 @@ +Створювач контракту розробив дуже простий контракт-фабрику токенів. Будь-хто може з легкістю створювати нові токени. Після розгортання першого контракту токену, створювач відправив `0.001` ефіра, щоб отримати більше токенів. З того часу вони втратили адресу контракту. + +Цей рівень буде завершено, якщо ви зможете відновити (або видалити) `0.001` ефіра з втраченої адреси контракту. diff --git a/client/src/gamedata/ua/descriptions/levels/recovery_complete.md b/client/src/gamedata/ua/descriptions/levels/recovery_complete.md new file mode 100644 index 000000000..74529fee4 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/recovery_complete.md @@ -0,0 +1,7 @@ +Ці адреси контрактів є детермінованими і обчислюються за допомогою `keccak256(address, nonce)`, де `address` - це адреса контракту (або ефірна адреса, яка створила транзакцію), а `nonce` - це кількість контрактів, які створив породжуючий контракт (або нонс транзакції, для звичайних транзакцій). + +Через це, можна відправити ефір на попередньо визначену адресу (яка не має приватного ключа) і пізніше створити контракт за цією адресою, який відновить ефір. Це неінтуїтивний та дещо таємничий спосіб (небезпечно) зберігати ефір без приватного ключа. + +Цікава [стаття в блозі](https://swende.se/blog/Ethereum_quirks_and_vulns.html) Мартіна Свенде деталізує потенційні сценарії використання цього. + +Якщо ви збираєтеся впроваджувати цю техніку, переконайтеся, що ви не пропустили нонс, інакше ваші кошти будуть втрачені назавжди. diff --git a/client/src/gamedata/ua/descriptions/levels/shop.md b/client/src/gamedata/ua/descriptions/levels/shop.md new file mode 100644 index 000000000..81a0905cf --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/shop.md @@ -0,0 +1,5 @@ +Чи можете ви отримати товар з магазину за ціну, яка нижча за запитану? + +##### Речі, які можуть допомогти: +* `Shop` очікує використання від `Buyer` +* Розуміння обмежень функцій перегляду diff --git a/client/src/gamedata/ua/descriptions/levels/shop_complete.md b/client/src/gamedata/ua/descriptions/levels/shop_complete.md new file mode 100644 index 000000000..1be26f5c4 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/shop_complete.md @@ -0,0 +1,3 @@ +Договори можуть маніпулювати даними, які бачать інші договори, як їм заманеться. + +Це небезпечно змінювати стан на основі логіки зовнішніх та недовірених договорів. From 6b6a29f4e0dbff60c27afd28063b3f313f7fb701 Mon Sep 17 00:00:00 2001 From: boivlad Date: Wed, 2 Aug 2023 12:07:15 +0300 Subject: [PATCH 4/7] feat: added ua translates part 4 --- .../src/gamedata/ua/descriptions/levels/goodsamaritan.md | 7 +++++++ .../ua/descriptions/levels/goodsamaritan_complete.md | 3 +++ client/src/gamedata/ua/descriptions/levels/switch.md | 4 ++++ .../src/gamedata/ua/descriptions/levels/switch_complete.md | 1 + 4 files changed, 15 insertions(+) create mode 100644 client/src/gamedata/ua/descriptions/levels/goodsamaritan.md create mode 100644 client/src/gamedata/ua/descriptions/levels/goodsamaritan_complete.md create mode 100644 client/src/gamedata/ua/descriptions/levels/switch.md create mode 100644 client/src/gamedata/ua/descriptions/levels/switch_complete.md diff --git a/client/src/gamedata/ua/descriptions/levels/goodsamaritan.md b/client/src/gamedata/ua/descriptions/levels/goodsamaritan.md new file mode 100644 index 000000000..bfa924337 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/goodsamaritan.md @@ -0,0 +1,7 @@ +Цей екземпляр представляє доброго самарянина, який є багатим і готовим пожертвувати кілька монет будь-кому, хто цього запросить. + +Чи змогли б ви спустошити всю його гаманець? + +Речі, які можуть допомогти: + +- [Користувацькі помилки Solidity](https://blog.soliditylang.org/2021/04/21/custom-errors/) diff --git a/client/src/gamedata/ua/descriptions/levels/goodsamaritan_complete.md b/client/src/gamedata/ua/descriptions/levels/goodsamaritan_complete.md new file mode 100644 index 000000000..7797ca580 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/goodsamaritan_complete.md @@ -0,0 +1,3 @@ +Вітаємо! + +Користувацькі помилки в Solidity ідентифікуються за їх 4-байтовим 'селектором', таким же як і виклик функції. Вони піднімаються вгору по ланцюжку викликів, доки їх не зловить оператор catch в блоку try-catch, як це бачимо в функції `requestDonation()` у GoodSamaritan. З цих причин, не безпечно припускати, що помилка була викинута безпосередньо ціллю виклику контракту (тобто Wallet в цьому випадку). Будь-який інший контракт далі по ланцюжку викликів може оголосити ту саму помилку і викинути її в непередбачуваному місці, такому як функція `notify(uint256 amount)` у вашому контракті-атакувачі. diff --git a/client/src/gamedata/ua/descriptions/levels/switch.md b/client/src/gamedata/ua/descriptions/levels/switch.md new file mode 100644 index 000000000..859c9ced8 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/switch.md @@ -0,0 +1,4 @@ +Просто потрібно перевести перемикач. Не може бути так важко, правда? + +##### Що може допомогти: +Розуміння того, як кодується `CALLDATA`. diff --git a/client/src/gamedata/ua/descriptions/levels/switch_complete.md b/client/src/gamedata/ua/descriptions/levels/switch_complete.md new file mode 100644 index 000000000..b05bdc1ca --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/switch_complete.md @@ -0,0 +1 @@ +Припущення позицій в `CALLDATA` з динамічними типами може бути помилковим, особливо при використанні жорстко закодованих позицій `CALLDATA`. From 6af08e28af9a06c9233cdf61083abfffda41a7fd Mon Sep 17 00:00:00 2001 From: boivlad Date: Wed, 2 Aug 2023 12:10:56 +0300 Subject: [PATCH 5/7] feat: added ua translates part 5 --- client/src/gamedata/ua/descriptions/levels/unstoppable.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 client/src/gamedata/ua/descriptions/levels/unstoppable.md diff --git a/client/src/gamedata/ua/descriptions/levels/unstoppable.md b/client/src/gamedata/ua/descriptions/levels/unstoppable.md new file mode 100644 index 000000000..b04cb7b59 --- /dev/null +++ b/client/src/gamedata/ua/descriptions/levels/unstoppable.md @@ -0,0 +1,5 @@ +Є пул з позик, що має мільйон токенів на балансі, що пропонує миттєві позики безкоштовно. + +Якби тільки був спосіб атакувати та зупинити пул від пропозиції миттєвих позик ... + +Ви починаєте з балансом 100 токенів. From a1b97a97241b59d914ed685a59bcfce1caf995f2 Mon Sep 17 00:00:00 2001 From: boivlad Date: Wed, 2 Aug 2023 12:17:02 +0300 Subject: [PATCH 6/7] chore: clear yarn.lock --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 35c59719f..69c455767 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5455,9 +5455,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001400: - version "1.0.30001516" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001516.tgz" - integrity sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g== + version "1.0.30001431" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001431.tgz" + integrity sha512-zBUoFU0ZcxpvSt9IU66dXVT/3ctO1cy4y9cscs1szkPlcWb6pasYM144GqrUygUbT+k7cmUCW61cvskjcv0enQ== capture-exit@^2.0.0: version "2.0.0" @@ -9406,9 +9406,9 @@ highlight.js@^10.4.1: highlight.js "^10.7.2" highlight.js@^10.7.2: - version "10.7.2-local" - dependencies: - highlight.js "^10.7.2" + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== highlightjs-solidity@^2.0.5: version "2.0.5" From f698df8b1b99cb8c57d5b057d804b6481e563d70 Mon Sep 17 00:00:00 2001 From: boivlad Date: Wed, 13 Sep 2023 18:38:34 +0300 Subject: [PATCH 7/7] feat: updated translations from @Kyrylog --- client/src/gamedata/ua/descriptions/levels/aliencodex.md | 2 +- .../gamedata/ua/descriptions/levels/aliencodex_complete.md | 4 ++-- .../src/gamedata/ua/descriptions/levels/coinflip_complete.md | 4 ++-- client/src/gamedata/ua/strings.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/gamedata/ua/descriptions/levels/aliencodex.md b/client/src/gamedata/ua/descriptions/levels/aliencodex.md index 1b56a23ea..b6163400c 100644 --- a/client/src/gamedata/ua/descriptions/levels/aliencodex.md +++ b/client/src/gamedata/ua/descriptions/levels/aliencodex.md @@ -1,4 +1,4 @@ -Ви виявили контракт інопланетян. Претендуйте на власність, щоб завершити рівень. +Захопіть власність (ownership), щоб завершити рівень.   Речі, які можуть допомогти diff --git a/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md b/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md index d626c2a9d..06721adfa 100644 --- a/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md +++ b/client/src/gamedata/ua/descriptions/levels/aliencodex_complete.md @@ -1,5 +1,5 @@ Цей рівень використовує той факт, що EVM не перевіряє довжину масиву, кодовану ABI, відносно його реального вмісту. -Додатково, він використовує арифметичне недолік довжини масиву, розширюючи межі масиву до всієї області зберігання `2^256`. Потім користувач може змінювати усе зберігання контракту. +Додатково, він використовує антипереповнення довжини масиву, шляхом збільшення розміру масиву до всього storage `2^256`, що дозволяє користувачу змінювати весь storage контракту. -Обидва вразливості надихнуті [конкурсом підступного кодування 2017 року](https://medium.com/@weka/announcing-the-winners-of-the-first-underhanded-solidity-coding-contest-282563a87079) +Обидві вразливості надихнуті [конкурсом підступного кодування 2017 року](https://medium.com/@weka/announcing-the-winners-of-the-first-underhanded-solidity-coding-contest-282563a87079) diff --git a/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md b/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md index 418ddb554..9f51b560b 100644 --- a/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md +++ b/client/src/gamedata/ua/descriptions/levels/coinflip_complete.md @@ -1,5 +1,5 @@ -Генерація випадкових чисел у Solidity може бути складною. Наразі не існує рідного способу їх генерації, і все, що ви використовуєте в розумних контрактах, є публічно видимим, включаючи локальні змінні та змінні стану, позначені як приватні. Також майнери мають контроль над такими речами, як блокхеши, часові мітки, та включення певних транзакцій - що дозволяє їм зміщувати ці значення на свою користь. +Генерація випадкових чисел у Solidity є складною. Наразі не існує нативного способу їх генерації, і все, що ви використовуєте в смартконтрактах, є публічно видимим, включаючи локальні змінні та змінні стану, позначені як приватні. Також майнери мають контроль над такими речами, як блокхеши, часові мітки, та включення певних транзакцій - що дозволяє їм змінювати ці значення на свою користь. -Щоб отримати криптографічно доведені випадкові числа, ви можете використовувати [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number), який використовує оракул, токен LINK, та контракт на блокчейні для перевірки того, що число дійсно випадкове. +Щоб отримати криптографічно стійкі випадкові числа, ви можете використовувати [Chainlink VRF](https://docs.chain.link/docs/get-a-random-number), який використовує оракул, токен LINK, та контракт на блокчейні для перевірки того, що число дійсно випадкове. Деякі інші варіанти включають використання заголовків блоків Bitcoin (перевірених через [BTC Relay](http://btcrelay.org)), [RANDAO](https://github.com/randao/randao), або [Oraclize](http://www.oraclize.it/)). diff --git a/client/src/gamedata/ua/strings.json b/client/src/gamedata/ua/strings.json index 0a3cd6865..72b6060a2 100644 --- a/client/src/gamedata/ua/strings.json +++ b/client/src/gamedata/ua/strings.json @@ -56,7 +56,7 @@ "levelAuthor": "Автор(и) рівня:", "pleaseWait": "БУДЬ ЛАСКА, ЗАЧЕКАЙТЕ", "donate": "Рівень допоміг вам дізнатись щось нове? У вас є можливість підтримати автора(ів) цього рівня (на мейннеті):", - "openConsole": "ВІДКРИЙТЕ КОНСОЛЬ БРАУЗЕРА, ЩОБ РОЗПОЧАТИ ГРУ", + "openConsole": "ВІДКРИЙТЕ КОНСОЛЬ БРАУЗЕРА (More Tools - Developer Tools - Console), ЩОБ РОЗПОЧАТИ ГРУ", "difficulty": "Складність", "error": "Помилка", "retrying": "повторюю запит...",