Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StdDaoToken vulnerability fix: startNewVoting() and finishVoting() ca… #209

Closed
wants to merge 4 commits into from

Conversation

RostyslavBortman
Copy link
Contributor

…n be called BY ANYONE! #202

Copy link
Member

@AnthonyAkentiev AnthonyAkentiev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

И тесты дико перестали проходить)

super.finishEvent(_votingID);
emit VotingFinished(msg.sender, _votingID);
}

function isContract(address addr) returns (bool) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это зачем тут?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это метод для проверки адреса, является ли он контрактом. Ты имеешь ввиду что я его расположил неудачно?

@@ -59,17 +62,28 @@ contract StdDaoToken is DetailedERC20, PausableToken, CopyOnWriteToken, ITokenVo
// ITokenVotingSupport implementation
// TODO: VULNERABILITY! no onlyOwner!
function startNewVoting() public whenNotPaused returns(uint) {
require (isContract(msg.sender));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На самом деле это не защищает ни от чего. Ну создаст атакующий просто контракт, который нас дернет)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну это защищает от вызова простого аккаунта. Я пока не вижу других решений

emit VotingStarted(msg.sender, idOut);
return idOut;
}

// TODO: VULNERABILITY! no onlyOwner!
function finishVoting(uint _votingID) whenNotPaused public {
require (votingOwners[_votingID] == msg.sender);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше сделать модификатор отдельный для этого имхо

@AnthonyAkentiev
Copy link
Member

@RostyslavBortman Тесты не проходят. Нужно поправить

@RostyslavBortman RostyslavBortman requested a review from enkogu July 23, 2018 13:21
@@ -156,7 +156,7 @@ contract DaoBase is IDaoBase, Ownable {
if(isCan){
bool isVotingFound = false;
bool votingResult = false;
(isVotingFound, votingResult) = store.getProposalVotingResults(_a);
(isVotingFound, votingResult) = store.getProposalVotingResults(_a,0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Почему тут 0? А что если голосование не первое запущенное. Это не будет работать, правильно?

Copy link
Contributor Author

@RostyslavBortman RostyslavBortman Jul 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, правильно. Это заглушка чтобы не лезть дальше

@@ -59,17 +76,43 @@ contract StdDaoToken is DetailedERC20, PausableToken, CopyOnWriteToken, ITokenVo
// ITokenVotingSupport implementation
// TODO: VULNERABILITY! no onlyOwner!
function startNewVoting() public whenNotPaused returns(uint) {
uint idOut = super.startNewEvent();
require (isContract(msg.sender));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isContract() нужно убрать. Это ни от чего не защищает

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну в этом весь смысл таска. Тогда таск получается бесполезен, или я чего то не увидел/не понял

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Точнее не таска, а того что мы обсуждали. Возможно стоит подумать еще, каким образом можно еще сделать проверку. Но это уже больше похоже на этот таск
#210

emit VotingFinished(msg.sender, _votingID);
}

function startNewEvent() whenNotPaused public returns(uint){
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эти методы не должны быть тут.
Клиент контракта StdDaoToken не знает понятия "Event" (это понятие только низлежащего контракта CopyOnWriteToken)

Зачем ты вынес отдельные startnNewEvent/finishEvent и EventStarted/EventFinished сюда тоже не понятно. Нужно это убрать.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

" учти, что закрыть нужно еще и startNewEvent и finishEvent (переопределить их, а не прямо в CopyOnWriteToken!) " => Я их переопределил же

@@ -9,15 +9,15 @@ pragma solidity ^0.4.22;
contract IVoting {
// _tokenAmount -> if this voting type DOES NOT use tokens -> set to any value (e.g., 0);
// will execute action automatically if the voting is finished
function vote(bool _yes, uint _tokenAmount) public;
function vote(bool _yes, uint _tokenAmount, uint _votingID) public;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ты добавил ВО ВСЕ методы Voting'ов _votingID. Так быть не должно:

  1. путается понятие "голосование" (сам адрес контракта Voting) и понятие "индекс голосования в токене" (то что называется _votingID)
  2. Не понятно, как ОДИН voting может быть связан с несколькими "индексами голосований в токене"
  3. Чисто логически не понятно, почему Voting не может ВНУТРИ себя хранить всю нужную инфу (допустим даже votingID), а должен ее откуда-то получать
  4. Кто и где хранит тогда votingID?
    Короче, это очень плохое решение

@@ -17,7 +17,7 @@ contract LiquidVoting is IDelegationTable, Voting_SimpleToken {
event DelegatedTo(address _sender, uint _tokensAmount);
event DelegationRemoved(address _from, address _to);

mapping (address => Delegation[]) delegations;
mapping (uint => mapping(address => Delegation[])) delegations;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как понять логику "в одном контракте Voting может быть МНОЖЕСТВО привязанных индексов голосований токена"? Зачем тут uint => mapping появился?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ну типо, у одного инстанса Voting может быть 20 votings с разными ID

@RostyslavBortman RostyslavBortman deleted the dev2Rostyslav4 branch July 24, 2018 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants