Skip to content

Instantly share code, notes, and snippets.

@nnn-gif
Last active June 28, 2018 20:32
Show Gist options
  • Save nnn-gif/db53317b3faf742cf793eaed840c5bfc to your computer and use it in GitHub Desktop.
Save nnn-gif/db53317b3faf742cf793eaed840c5bfc to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.4.24+commit.e67f0147.js&optimize=false&gist=
pragma solidity ^0.4.24;
contract Multisig {
event ReceivedContribution(address indexed _contributor, uint _valueInWei);
event ProposalSubmitted(address indexed _beneficiary, uint _valueInWei);
event ProposalApproved(address indexed _approver, address indexed _beneficiary, uint _valueInWei);
event ProposalRejected(address indexed _approver, address indexed _beneficiary, uint _valueInWei);
event WithdrawPerformed(address indexed _beneficiary, uint _valueInWei);
event ContributionPeriodIsrunning();
event SubmitContribution();
//events
event BalanceContract(address indexed _beneficiary, uint _valueInWei, uint _calculated10percent);
//mapping (uint => proposals) public proposals;
bool private isAccepting = true ;
mapping (address => bool) public isSigner;
address[] public signers;
address public owner;
address public contractaddress;
mapping (address => uint) public contributers_balance;
address[] public contributers;
mapping (address => Proposal) public allProposals;
struct Proposal {
address owner;
uint value;
bool executed;
address[] approved;
address[] rejected;
mapping(address=>bool) voted;
}
function listOpenBeneficiariesProposals() external view returns (address[]){
address[] listOpenBeneficiariesProposals;
for (uint i=0; i<contributers.length; i++) {
if(allProposals[contributers[i]].approved.length+allProposals[contributers[i]].rejected.length<2){
listOpenBeneficiariesProposals.push(allProposals[contributers[i]].owner);
}
}
return listOpenBeneficiariesProposals;
}
constructor(address[] _signers) {
contractaddress = address(this);
owner = msg.sender;
for (uint i=0; i<_signers.length; i++) {
if (isSigner[_signers[i]] || _signers[i] == 0)
revert();
isSigner[_signers[i]] = true;
}
signers = _signers;
}
function endContributionPeriod() external{
require(isSigner[msg.sender],"need signer to end");
isAccepting = false;
}
modifier isInContributionPeriod() {
if (isAccepting)
revert();
_;
}
modifier isNotInContributionPeriod() {
if (!isAccepting)
revert();
_;
}
/// Fallback function allows to deposit ether.
function() payable
{
if(!isAccepting){
revert();
}
if (msg.value > 0){
//push only if contributer is not already in that array
if(contributers_balance[msg.sender] == 0)
{
contributers.push(msg.sender);
}
if(contributers_balance[msg.sender] > 0)
{
contributers_balance[msg.sender] = contributers_balance[msg.sender]+msg.value;
}else{
contributers_balance[msg.sender] = msg.value;
}
emit ReceivedContribution(msg.sender, msg.value);
}
}
function submitProposal(uint _valueInWei) external {
// only contributer can send the Proposal
emit SubmitContribution();
//dont allow to add one more proposal
require(allProposals[msg.sender].value == 0);
require(contributers_balance[msg.sender]>=_valueInWei);
// propasal value should be equal or less than 10% of available balance
uint balanceshouldbelessthan = address(this).balance/10;
require(_valueInWei<= balanceshouldbelessthan);
allProposals[msg.sender] = Proposal({
owner:msg.sender,
// withdrawhistory:null;
approved:new address[](0),
rejected:new address[](0),
value: _valueInWei,
executed: false
});
emit ProposalSubmitted(msg.sender, _valueInWei);
emit BalanceContract(address(this) ,address(this).balance , balanceshouldbelessthan);
}
function listContributors() external view returns (address[]){
return contributers;
}
function getBeneficiaryProposal(address _beneficiary) external view returns (uint){
return allProposals[_beneficiary].value;
}
function getContributorAmount(address _contributor) external view returns (uint){
return contributers_balance[_contributor];
}
function withdraw(uint _valueInWei) external {
//count votes
//check if all has given votes
// require((allProposals[msg.sender].approved.length + allProposals[msg.sender].rejected.length)==3);
require(allProposals[msg.sender].owner!=0,'No proposal exist of this sender');
require(allProposals[msg.sender].executed==true,"proposal is still in voting or not approved");
require(allProposals[msg.sender].value >= _valueInWei ,"this amount is not approved");
allProposals[msg.sender].executed = true;
uint newvalue = allProposals[msg.sender].value -_valueInWei;
allProposals[msg.sender].value =newvalue;
msg.sender.call.value(_valueInWei);
WithdrawPerformed(msg.sender, _valueInWei);
}
function approve(address _beneficiary) external {
if(isAccepting){
revert();
}
require(isSigner[msg.sender],"need signer to approve");
//should not be already voted
require(allProposals[_beneficiary].voted[msg.sender]==false,"already voted") ;
require(allProposals[_beneficiary].executed==false,"already have maximim vote");
allProposals[_beneficiary].approved.push(msg.sender);
//check if all has given votes
if((allProposals[_beneficiary].approved.length + allProposals[_beneficiary].rejected.length)>=2){
if(allProposals[_beneficiary].approved.length>allProposals[_beneficiary].rejected.length){
allProposals[_beneficiary].executed = true;
}
if(allProposals[_beneficiary].approved.length<allProposals[_beneficiary].rejected.length){
allProposals[_beneficiary].executed = false;
}
}
emit ProposalApproved(msg.sender, _beneficiary, allProposals[_beneficiary].value);
}
function reject(address _beneficiary) external {
if(isAccepting){
revert();
}
require(isSigner[msg.sender]);
require(allProposals[_beneficiary].voted[msg.sender]==false,'already voted') ;
require(allProposals[_beneficiary].executed==false,"already got maximum votes");
allProposals[_beneficiary].rejected.push(msg.sender);
if((allProposals[_beneficiary].approved.length + allProposals[_beneficiary].rejected.length)>=2){
if(allProposals[_beneficiary].approved.length>allProposals[_beneficiary].rejected.length){
allProposals[_beneficiary].executed = true;
}
if(allProposals[_beneficiary].approved.length<allProposals[_beneficiary].rejected.length){
allProposals[_beneficiary].executed = false;
}
}
emit ProposalRejected(msg.sender, _beneficiary, allProposals[_beneficiary].value);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment