Emirate Coin е ERC20 токен, изграден върху Ethereum. Повече информация можете да намерите на началната страница на проекта на адрес emiratecoin.io. Екипът на Trustless Design беше помолен да извърши одит на сигурността на интелигентните договори.

Одитори

Одитът беше извършен от Logan Saether и Daniel Kmak от Trustless Design.

Въведение

Кодовата база се състои от два интелигентни договора: EmcoToken.sol и EmcoVoucher.sol. Договорите са написани на езика на интелигентните договори Solidity и използват библиотеката от стандарти OpenZeppelin.

В допълнение към интелигентните договори, ние също бяхме помолени да одитираме JavaScript файлове, свързани със сървъра, който ще генерира ваучерите.

Установихме, че кодовата база съдържа автоматизиран тестов пакет, използващ рамката Truffle, което беше полезно по време на проверката на бизнес логиката на интелигентните договори. Добавихме и написахме наши собствени автоматизирани тестови случаи, докато участвахме в процеса на одит.

EmcoToken

EmcoToken е стандартен ERC20 токен и съдържа някои персонализирани логики, внедрени в допълнение към основната функционалност. Персонализираната логика обработва специалния случай на употреба на EmcoToken до почти mine повече токени. Докато потребителите винаги поддържат контрол върху всичките си токени, на практика има 2 баланса: стандартен баланс ERC20 и персонализиран баланс за копаене. Потребителите могат да превключват токени между тези два баланса в рамките на определени глобални ограничения. Колкото по-висок е майнинг балансът на потребителя, толкова по-добра възвръщаемост получава.

Проблеми

Не бяха открити уязвимости от КРИТИЧНО ниво.

[СРЕДЕН] Стандартната функция ERC20 balanceOf беше презаписана, за да върне баланса както на стандартния баланс на потребителя, така и на баланса за копаене. Сумата на токена, върната от тази функция, може да представлява токени, които не могат да се прехвърлят (поради това, че са заключени в баланса за копаене, който първо трябва да бъде изтеглен). Препоръчва се функцията balanceOf да се върне обратно към стандартната логика и или да се добави нова функция totalTokensOwned, която ще върне стойността и на двата отделни баланса на потребителя, ИЛИ изчислението просто да се извърши на клиента странично приложение чрез добавяне на общите стойности, върнати от двете повиквания заедно.

Следва повече информация защо смятаме, че това е проблем със средна тежест.

В интерфейси като MetaMask, MyCrypto, MyEtherWallet или други се предполага, че функцията ERC20 balanceOf връща токени, които могат незабавно да се прехвърлят. Потребителите ще видят, че имат токени и ще си помислят, че могат да ги прехвърлят, но всъщност интелигентните договори няма да им позволят да направят това, защото някои токени може да са в баланса за копаене.

Това може да направи токена проблематичен за използване с децентрализирани борси (в някои случаи, когато потребителите държат известно количество токени в баланса за копаене) и популярни портфейли като MetaMask. Дори ако тази логика е отчетена в персонализирано приложение, потребителите пак могат да се опитат да използват общи интерфейси, открити в портфейлите, и да се объркат.

[LOW] Параметърът currentDay и currentDayDeposited се презаписват за всеки нов ден, това прави определени неща проблематични, което води до код, подобен на открития във функцията getCurrentDayDeposited(), която изрично проверява дали currentDay е актуализиран. Актуализацията се случва само когато някой извика функцията depositToMiningBalance. Това може да доведе до остаряла променлива currentDay.

По-елегантно решение би било параметърът currentDayDeposited да се превърне в mapping(uint256 => uin256), в който currentDay ще стане key и депозираната сума е стойността. Логиката в договора може да бъде преработена, за да се възползва от това, което би улеснило по-добри помощни функции като getDepositsForDay(uint256 _day), което също ще показва история на депозитите.

ЕмкоВаучер

Договорът EmcoVoucher отговаря за активирането на ваучерите. Ваучерите са като доказателства за токени, които се предават на този интелигентен договор, за да ги осребрите срещу действителни токени.

Проблеми

[КРИТИЧНО] setSignerAddress позволява на всеки да зададе адреса, който се проверява спрямо подписа, отваряйки възможността някой да открадне всички токени, съхранявани в договора за ваучер, в 2 транзакции. Нападателят първо ще зададе адрес, за който притежава частния ключ, като signerAddress, използвайки функцията public setSignerAddress и след това ще изпрати фалшив ваучер, който е подписан със собствения си ключ в договора, който има пълен контрол върху всички символични средства в договора.

Забележка: знаем, че този проблем вече е докладван вътрешно на екипа за разработка на Emirate Coin, но той присъстваше във версията на кодовата база, която одитирахме, така че все пак го включихме тук.

[НИСКО] Средствата за финансиране на ваучер не са обезпечени по никакъв начин. Ваучерът може да бъде генериран за потребителя, но договорът може да има нулеви токени.

Решение

Потребителят или приложението могат да проверят дали ваучерът е „изпълним“ (ако в момента в договора за ваучер има достатъчно средства за изпълнение на ваучера).

[НИСКО] Използвайте фиксирани версии на зависимости, за да избегнете прекъсване на договори в бъдеще поради актуализации. Това е лесно решение и всъщност може да доведе до проблеми със средна и висока тежест в определени случаи. Ако например бъде пусната нова версия на openzeppelin, която променя основните договори, които се използват, нововъведената версия може да има напълно различна логика на изпълнение.

Препоръчваме да използвате 1.12 версия на OpenZeppelin. Това е така, защото версия 2 идва скоро и ще се промени много, включително премахването на StandardToken, на който разчита договорът за токени.

[НИСКО]Секцията на бялата книга „Автоматична продажба на токен“ споменава функции: CreateTradeBundle и BuyTradeBundle, които не присъстват в интелигентния договор.

Решение

Актуализирайте бялата книга.

Сървър за ваучери

Ваучер сървърът е малка услуга, която се грижи за генерирането на ваучери. Написано е на JavaScript.

Проблеми

Не бяха открити уязвимости от КРИТИЧНО ниво.

[СРЕДЕН]Договорът за ваучер изисква nonce да е различен от 0 при активиране на ваучер, но за първия генериран ваучер nonce всъщност е 0. Това прави първия ваучер неизползваем.

Решение

Накарайте сървъра да генерира nonces, започвайки от 1.

Забележка относно внедряването на сървър за ваучери:

Системата за ваучери трябва да бъде защитена и използвана вътрешно в рамките на затворен сървър (хостван на затворен порт, недостъпен извън машината, която го изпълнява). Още по-добре би било да го поставите зад друг сървър, който може да проксира някои обаждания към него.

Тази препоръка се дължи на факта, че сървърът има латентен достъп до личния ключ на подписващия и не е ограничен по друг начин при генерирането на нови ваучери.

Резюме

Открит е само един проблем или уязвимост с висок приоритет, които в момента са в процес на отстраняване. Одиторският екип на Trustless Design потвърждава сигурността на интелигентните договори на Emirate Coin и препоръчва на любопитните читатели да разгледат проекта.

Ако желаете да извършим одит на ВАШИЯ проект, свържете се с нас в Telegram (Daniel или Logan). Като алтернатива можете да изпратите имейл до [email protected].

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