Skip to content

Latest commit

 

History

History
171 lines (140 loc) · 6 KB

7. Audit Fndings 101.md

File metadata and controls

171 lines (140 loc) · 6 KB

**Note: All 8 questions in this quiz are based on the InSecureumDAO contract snippet shown below. This is the same contract snippet you will see for all the 8 questions in this quiz. **

The InSecureumDAO contract snippet illustrates some basic functionality of a Decentralized Autonomous Organization (DAO) which includes the opening of the DAO for memberships, allowing users to join as members by depositing a membership fee, creating proposals for voting, casting votes, etc. Assume that all other functionality (that is not shown or represented by ...) is implemented correctly.

pragma solidity 0.8.4;
import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol';
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/Pausable.sol";

contract InSecureumDAO is Pausable, ReentrancyGuard {
    
    // Assume that all functionality represented by ... below is implemented as expected
     
    address public admin;
    mapping (address => bool) public members;
    mapping (uint256 => uint8[]) public votes;
    mapping (uint256 => uint8) public winningOutcome;
    uint256 memberCount = 0;
    uint256 membershipFee = 1000;
     
    modifier onlyWhenOpen() {
        require(address(this).balance > 0, 'InSecureumDAO: This DAO is closed');
        _;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin);
        _;
    }

    modifier voteExists(uint256 _voteId) {
       // Assume this correctly checks if _voteId is present in votes
        ...
        _;
    }
    
    constructor (address _admin) {
        require(_admin == address(0));
        admin = _admin;
    }
  
    function openDAO() external payable onlyAdmin {
        // Admin is expected to open DAO by making a notional deposit
        ...
    }

    function join() external payable onlyWhenOpen nonReentrant {
        require(msg.value == membershipFee, 'InSecureumDAO: Incorrect ETH amount');
        members[msg.sender] = true;
        ...
    }

    function createVote(uint256 _voteId, uint8[] memory _possibleOutcomes) external onlyWhenOpen whenNotPaused {
        votes[_voteId] = _possibleOutcomes;
        ...
    }

    function castVote(uint256 _voteId, uint8 _vote) external voteExists(_voteId) onlyWhenOpen whenNotPaused {
        ...
    }

    function getWinningOutcome(uint256 _voteId) public view returns (uint8) {
        // Anyone is allowed to view winning outcome
        ...
        return(winningOutcome[_voteId]);
    }
  
    function setMembershipFee(uint256 _fee) external onlyAdmin {
        membershipFee = _fee;
    }
  
    function removeAllMembers() external onlyAdmin {
        delete members[msg.sender];
    }  
}

Q1 Based on the comments and code shown in the InSecureumDAO snippet

  • A) DAO is meant to be opened only by the admin by making an Ether deposit to the contract
  • B) DAO can be opened by anyone by making an Ether deposit to the contract
  • C) DAO requires an exact payment of membershipFee to join the DAO
  • D) None of the above
Click the reveal the answer A,B,C

Q2 Based on the code shown in the InSecureumDAO snippet

  • A) Guarded launch via circuit breakers has been implemented correctly for all state modifying functions
  • B) Zero-address check(s) has/have been implemented correctly
  • C) All critical privileged-role functions have events emitted
  • D) None of the above
Click the reveal the answer D

Q3 Reentrancy protection only on join() (assume it’s correctly specified) indicates that

  • A) Only payable functions require this protection because of handling msg.value
  • B) join() likely makes untrusted external call(s) but not the other contract functions
  • C) Both A and B
  • D) Neither A nor B
Click the reveal the answer B

Q4 Access control on msg.sender for DAO membership is required in

  • A) createVote() to prevent non-members from creating votes
  • B) castVote() to prevent non-members from casting votes
  • C) getWinningOutcome() to prevent non-members from viewing winning outcomes
  • D) None of the above
Click the reveal the answer A,B

Q5 A commit/reveal scheme (a cryptographic primitive that allows one to commit to a chosen value while keeping it hidden from others, with the ability to reveal the committed value later) is relevant for

  • A) join() to not disclose msg.sender while joining the DAO
  • B) createVote() to not disclose the possible outcomes during creation
  • C) castVote() to not disclose the vote being cast
  • D) All the above
Click the reveal the answer C

Q6 Security concern(s) from missing input validation(s) is/are present in

  • A) createVote() for duplicate _voteId
  • B) castVote() for existing _voteId
  • C) getWinningOutcome() for existing _voteId
  • D) setMembershipFee() for sanity/threshold checks on _fee
Click the reveal the answer A,D

Q7 removeAllMembers() function

  • A) Will not work as expected to remove all the members from the DAO
  • B) Will work as expected to remove all the members from the DAO
  • C) Is a critical function missing an event emission
  • D) None of the above
Click the reveal the answer A,C

Q8 InSecureumDAO will not be susceptible to something like the 2016 “DAO exploit”

  • A) Because it derives from ReentrancyGuard.sol which protects all contract functions by default
  • B) Only if it does not have a withdraw Ether function vulnerable to reentrancy and makes no external calls
  • C) Because Ethereum protocol was fixed after the DAO exploit to prevent such exploits
  • D) Because Solidity language was fixed after the DAO exploit to prevent such exploits
Click the reveal the answer B