---
# System prepended metadata

title: Staking contract audit

---

# Staking contract audit 


BSC Network Contract Address: [0xee083cF813041562B5C736E60e901E248d113280](https://bscscan.com/address/0xee083cF813041562B5C736E60e901E248d113280)



---

🟥 CRITICAL ISSUES (critical, high severity): 0

> Bugs and vulnerabilities that enable theft of funds, lock access to funds without possibility to restore it, or lead to any other loss of funds to be transferred to any party; high priority unacceptable bugs for deployment at mainnet.

🟧 ERRORS, BUGS (medium, low severity): 6

> Bugs that can trigger a contract failure, with further recovery only possible through manual modification of the contract state or contract replacement altogether.

🟨 WARNINGS (any severity): 2

> Lack of necessary security precautions; other warnings for owners and users.

⬜ OPTIMIZATION POSSIBILITIES (very low severity): 4

> *Possibilities to decrease cost of transactions and data storage of Smart-Contracts.*

⬜ NOTES AND RECOMMENDATIONS (very low severity): 3

> *Tips and tricks, all other issues and recommendations, as well as errors that do not affect the functionality of the Smart-Contract.*

❓ QUESTIONS (any severity): 3

> *Questions to the developers and owner of smart-contract.*


#
# AUDIT RESULT:

🟧 **ERRORS, BUGS** 

1. (low severity) Владелец имеет право изменять feePeriod в пределах от 5% до 14.99 а также изменять feePeriod в пределах от 30 до 364 дней. Скорее всего в данных функциях была допущена ошибка из-за чего верхние пределы не округлены до 15 и 365. Знак < нужно заменить на <=.

2. (medium severity) [369, 376] При вычитании из _stakesBalance суммы вклада юзера не учитываются fee, которые в дальнейшем никогда не будут вычтены из _stakesBalance. Это происходит из-за того что в строке 369 переменная stake уменьшается на fee, а далее в строке 376 именно stake будет вычтен из _stakesBalance.

3. (medium severity) [418-419, 500-508] проверки в функции setParameters допускают выставление minimum, medium и maximum на одинаковое значение. В этом случае условия в функции getPercent ломаются и возвращают 0 (из-за использования знака &&)

4. (medium severity) Комиссия удерживается от вклада юзера при выводе вклада [369, 379] (если пользователь не в вайтлисте и выводит не позднее 180 дней) и остается невыводимым остатком на балансе смарт-контракта. Сумма отправленная как комиссия при совершении вклада не в счет, так как она была отправлена из дивидендных средств, а не из вклада (об этом говорят проверки в строках [271, 277]) .

5. (low severity) каждый юзер для совершения вклада обязан выставить свой pool address [268], но данный адрес абсолютно не используется в коде если юзер в вайтлисте [272]. В данном случае выставление pool address было бессмысленным, более того юзер мог выставить сам себя.

6. (medium severity) неправильное разделение fallback и receive функций: receive используется при отправке BNB без msg.data следовательно в строках [234-237] становится нерабочим. fallback в смарт-контрактах используется при наличии msg.data но код функции абсолютно пустой что делает возможным безвозвратную потерю BNB через fallback (так как в fallback не реализован возврат средств как в receive). P.S. в оригинальном контракте не было receive функции в следствие чего она автоматически заменялась на fallback.

🟨 **WARNINGS**

1. Полномочия владельца:

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

Владелец смарт-контракта имеет право добавлять пользователей в «Белый список»: для них начисление происходит по максимальной ставке для любого размера депозита.

Владелец имеет право менять параметры стейкинга (minimum/medium/maximum/minPercent/medPercent/maxPercent). Данная функция может быть вызвана ограниченное количество раз в течение одного года (yearSettingsLimit). Все дивиденды при изменениях параметров рассчитываются корректно.

`P.S. Данный комментарий носит информационный характер и будет присутствовать в публичном отчете`

2. Циклы по динамичным массивам:   В коде встречаются циклы по растущим переменным (_stages) в функции getStaked. 

В случае если пользователь не делал выводы дивидендов в период, когда владелец несколько раз изменил настройки смарт-контракта (minimum/maximum/minPercent/maxPercent), то стоимость транзакции для данного пользователя возрастает. 
В коде реализовано ограничение для владельца на количество изменений параметров в год (yearSettingsLimit), но предупреждение остается: стоимость транзакции не должна превышать текущий лимит газа в блоке, иначе вывод дивидендов станет невозможным.

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

`P.S. Данный комментарий носит информационный характер и будет присутствовать в публичном отчете`

⬜ **OPTIMIZATION POSSIBILITIES** 

1. [213] параметр 'date' в struct 'User' является излишним и не используется в функционале смарт-контракта.

2. [303-305] излишние проверки: можно оставить только последнюю проверку на whitelist (так как нулевой адрес нельзя добавить в вайтлист и вы не станете вайтлистить адрес собственного токена), которая гарантирует непрохождение других двух проверок.

3. [302] всю функцию 'setUserPool' можно убрать, а функционал интегрировать в функцию 'stake' добавив там третий параметр 'pool' автоматически устанавливая адрес для юзера в начале кода.

4. [450-453, 464-468] сохранение текущих дивидендов при добавлении/удалении в вайтлист не требуется. данный функционал присутствовал в оригинальном коде так как вайтлист имел другую роль связанную с дивидендами. 

⬜ **NOTES AND RECOMMENDATIONS**

1. В ивентах SetUserPool, SetFeePercent, SetFeePeriod скорее всего нет смысла индексировать числовые значения.

2. Название ивента TotalStaking не соответствует его смыслу: используется он в функции donate.

3. Условие в строке [367] можно переписать следующим образом:
> было:
> if(!(user.stakeDate > 0 && ((now - user.stakeDate) >= (feePeriod * ONE_DAY)))){
> стало:
> if (now - user.stakeDate < feePeriod * ONE_DAY) {

❓ **QUESTIONS**

1. Адрес pool юзер может менять сколько угодно раз при повторных вкладах.

2. Логика минимума и максимума процентов в оригинальном контракте работала так: меньшим депозитам - больший процент. В данном контракте все наоборот.

3. В документе "[внесенные изменения](https://docs.google.com/document/d/1yn3smmCOApBWmIHscXBj7sn0TnUFv8h5xtiJOYBMbh0/edit)" сказано: 
> "Убрана функция withdrawERC20: Ее убрали с целью чтоб нельзя было вывести деньги со смарт контракта; В Диджексе получается можно разлочить сумму на стейкинге и запустить ее в рынок что може быть опасным для цены. Попросили чтоб убрали."

Данное замечание неверно: код функции withdrawERC20 не позволял выводить токены Digex (это исключала специальная проверка). Функция могла быть использована только в целях вывода по ошибке отправленных и рекламных токенов других проектов.



---

Authors: ([Grox Solutions](https://grox.solutions) | [@gafagilm](https://t.me/gafagilm))
