Skip to content

Commit

Permalink
update Dapp 30 to Solidity 0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
jklepatch committed Apr 30, 2021
1 parent da158a9 commit 47091a0
Show file tree
Hide file tree
Showing 21 changed files with 898 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pragma solidity ^0.8.0;

contract SimpleSmartContract {
}
33 changes: 33 additions & 0 deletions dapp-30/day10-escrow/smart-contract-solidity-0-8-update/Escrow.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
pragma solidity ^0.8.0;

contract Escrow{
address public payer;
address payable public payee;
address public lawyer;
uint public amount;

constructor(
address _payer,
address payable _payee,
uint _amount) {
payer = _payer;
payee = _payee;
lawyer = msg.sender;
amount = _amount;
}

function deposit() payable public {
require(msg.sender == payer, 'Sender must be the payer');
require(address(this).balance <= amount, 'Cant send more than escrow amount');
}

function release() public {
require(address(this).balance == amount, 'cannot release funds before full amount is sent');
require(msg.sender == lawyer, 'only lawyer can release funds');
payee.transfer(amount);
}

function balanceOf() view public returns(uint) {
return address(this).balance;
}
}
2 changes: 1 addition & 1 deletion dapp-30/day10-escrow/smart-contract/Escrow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract Escrow{
}

function deposit() payable public {
require(msg.sender = payer, 'Sender must be the payer');
require(msg.sender == payer, 'Sender must be the payer');
require(address(this).balance <= amount, 'Cant send more than escrow amount');
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
pragma solidity ^0.8.0;

contract Strings {
function length(string memory str) pure public returns(uint) {
bytes memory str_bytes = bytes(str);
return str_bytes.length;
}

function concatenate(string memory str1, string memory str2) pure public returns(string memory) {
bytes memory str_bytes1 = bytes(str1);
bytes memory str_bytes2 = bytes(str2);
string memory str = new string(str_bytes1.length + str_bytes2.length);
bytes memory str_bytes = bytes(str);

uint k = 0;
for(uint i = 0; i < str_bytes1.length; i++) {
str_bytes[k] = str_bytes1[i];
k++;
}
for(uint i = 0; i < str_bytes2.length; i++) {
str_bytes[k] = str_bytes2[i];
k++;
}

return string(str_bytes);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
pragma solidity ^0.8.0;

contract Fibonacci {
function fib(uint n) pure external returns(uint) {
if(n == 0) {
return 0;
}
uint fi_1 = 1;
uint fi_2 = 1;
for(uint i = 2; i < n; i++) {
uint fi = fi_1 + fi_2;
fi_2 = fi_1;
fi_1 = fi;
}
return fi_1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
pragma solidity ^0.8.0;

contract Wallet {
address[] public approvers;
uint public quorum;
struct Transfer {
uint id;
uint amount;
address payable to;
uint approvals;
bool sent;
}
mapping(uint => Transfer) transfers;
uint nextId;
mapping(address => mapping(uint => bool)) approvals;

constructor(address[] memory _approvers, uint _quorum) payable {
approvers = _approvers;
quorum = _quorum;
}

function createTransfer(uint amount, address payable to) onlyApprover() external {
transfers[nextId] = Transfer(
nextId,
amount,
to,
0,
false
);
nextId++;
}

function sendTransfer(uint id) onlyApprover() external {
require(transfers[id].sent == false, 'transfer has already been sent');
if(transfers[id].approvals >= quorum) {
transfers[id].sent = true;
address payable to = transfers[id].to;
uint amount = transfers[id].amount;
to.transfer(amount);
return;
}
//BUG: put this BEFORE if(transfers[id].approvals >= quorum)
if(approvals[msg.sender][id] == false) {
approvals[msg.sender][id] = true;
transfers[id].approvals++;
}
}

modifier onlyApprover() {
bool allowed = false;
for(uint i; i < approvers.length; i++) {
if(approvers[i] == msg.sender) {
allowed = true;
}
}
require(allowed == true, 'only approver allowed');
_;
}
}
68 changes: 68 additions & 0 deletions dapp-30/day14-voting/smart-contract-solidity-0-8-update/Voting.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
pragma solidity ^0.8.0;

contract Voting {
mapping(address => bool) public voters;
struct Choice {
uint id;
string name;
uint votes;
}
struct Ballot {
uint id;
string name;
Choice[] choices;
uint end;
}
mapping(uint => Ballot) ballots;
uint nextBallotId;
address public admin;
mapping(address => mapping(uint => bool)) votes;

constructor() {
admin = msg.sender;
}

function addVoters(address[] calldata _voters) external onlyAdmin() {
for(uint i = 0; i < _voters.length; i++) {
voters[_voters[i]] = true;
}
}

function createBallot(
string memory name,
string[] memory _choices,
uint offset
) public onlyAdmin() {
ballots[nextBallotId].id = nextBallotId;
ballots[nextBallotId].name = name;
ballots[nextBallotId].end = now + offset;
for(uint i = 0; i < _choices.length ; i++) {
ballots[nextBallotId].choices.push(Choice(i, _choices[i], 0));
}
nextBallotId++;
}

function vote(uint ballotId, uint choiceId) external {
require(voters[msg.sender] == true, 'only voters can vote');
require(votes[msg.sender][ballotId] == false, 'voter can only vote once for a ballot');
require(now < ballots[ballotId].end, 'can only vote until ballot end date');
votes[msg.sender][ballotId] = true;
ballots[ballotId].choices[choiceId].votes++;
}

//If `pragma experimental ABIEncoderV2`
function results(uint ballotId)
view
external
returns(Choice[] memory) {
require(now >= ballots[ballotId].end, 'cannot see the ballot result before ballot end');
return ballots[ballotId].choices;
}

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


129 changes: 129 additions & 0 deletions dapp-30/day15-dao/smart-contract-solidity-0-8-update/DAO.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
pragma solidity ^0.8.0;

/**
* DAO contract:
* 1. Collects investors money (ether) & allocate shares
* 2. Keep track of investor contributions with shares
* 3. Allow investors to transfer shares
* 4. allow investment proposals to be created and voted
* 5. execute successful investment proposals (i.e send money)
*/

contract DAO {
struct Proposal {
uint id;
string name;
uint amount;
address payable recipient;
uint votes;
uint end;
bool executed;
}

mapping(address => bool) public investors;
mapping(address => uint) public shares;
mapping(address => mapping(uint => bool)) public votes;
mapping(uint => Proposal) public proposals;
uint public totalShares;
uint public availableFunds;
uint public contributionEnd;
uint public nextProposalId;
uint public voteTime;
uint public quorum;
address public admin;

constructor(
uint contributionTime,
uint _voteTime,
uint _quorum) {
require(_quorum > 0 && _quorum < 100, 'quorum must be between 0 and 100');
contributionEnd = block.timestamp + contributionTime;
voteTime = _voteTime;
quorum = _quorum;
admin = msg.sender;
}

function contribute() payable external {
require(block.timestamp < contributionEnd, 'cannot contribute after contributionEnd');
investors[msg.sender] = true;
shares[msg.sender] += msg.value;
totalShares += msg.value;
availableFunds += msg.value;
}

function redeemShare(uint amount) external {
require(shares[msg.sender] >= amount, 'not enough shares');
require(availableFunds >= amount, 'not enough available funds');
shares[msg.sender] -= amount;
availableFunds -= amount;
payable(msg.sender).transfer(amount);
}

function transferShare(uint amount, address to) external {
require(shares[msg.sender] >= amount, 'not enough shares');
shares[msg.sender] -= amount;
shares[to] += amount;
investors[to] = true;
}

function createProposal(
string memory name,
uint amount,
address payable recipient)
public
onlyInvestors() {
require(availableFunds >= amount, 'amount too big');
proposals[nextProposalId] = Proposal(
nextProposalId,
name,
amount,
recipient,
0,
block.timestamp + voteTime,
false
);
availableFunds -= amount;
nextProposalId++;
}

function vote(uint proposalId) external onlyInvestors() {
Proposal storage proposal = proposals[proposalId];
require(votes[msg.sender][proposalId] == false, 'investor can only vote once for a proposal');
require(block.timestamp < proposal.end, 'can only vote until proposal end date');
votes[msg.sender][proposalId] = true;
proposal.votes += shares[msg.sender];
}

function executeProposal(uint proposalId) external onlyAdmin() {
Proposal storage proposal = proposals[proposalId];
require(block.timestamp >= proposal.end, 'cannot execute proposal before end date');
require(proposal.executed == false, 'cannot execute proposal already executed');
require((proposal.votes / totalShares) * 100 >= quorum, 'cannot execute proposal with votes # below quorum');
_transferEther(proposal.amount, proposal.recipient);
}

function withdrawEther(uint amount, address payable to) external onlyAdmin() {
_transferEther(amount, to);
}

function _transferEther(uint amount, address payable to) internal {
require(amount <= availableFunds, 'not enough availableFunds');
availableFunds -= amount;
to.transfer(amount);
}

//For ether returns of proposal investments
receive() external payable {
availableFunds += msg.value;
}

modifier onlyInvestors() {
require(investors[msg.sender] == true, 'only investors');
_;
}

modifier onlyAdmin() {
require(msg.sender == admin, 'only admin');
_;
}
}
Loading

0 comments on commit 47091a0

Please sign in to comment.