β 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
Was this helpful?