Quiz

**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

Comment:

While the payable openDAO() function is protected by the correctly implemented onlyAdmin modifier, it is always possible to force send Ether into a contract via selfdestruct(). The onlyWhenOpen() modifier only checks for the contracts own balance which can be bypassed by doing that. The payable join() function indeed checks for the msg.value to exactly match membershipFee.

Q2 Based on the code shown in the InSecureumDAO snippet

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

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

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

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

Q7 removeAllMembers() function

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

Last updated