Skip to content

Latest commit

 

History

History
180 lines (132 loc) · 5.95 KB

RACE-2.md

File metadata and controls

180 lines (132 loc) · 5.95 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

[Answers] 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

[Answers] 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

[Answers] 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

[Answers] 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

[Answers] 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

[Answers] 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

[Answers] 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

[Answers] B