Skip to content

Instantly share code, notes, and snippets.

@sagaratalatti
Last active June 8, 2022 10:46
Show Gist options
  • Save sagaratalatti/9d2b9503798ae97c57f3dc51d64cc81a to your computer and use it in GitHub Desktop.
Save sagaratalatti/9d2b9503798ae97c57f3dc51d64cc81a to your computer and use it in GitHub Desktop.
Partnership Smartcontract
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract Partnership is Pausable, Ownable, ReentrancyGuard {
using SafeMath for uint256;
event PayeeAdded(address account, uint256 shares);
event PayeeRemoved(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
uint256 private _totalShares;
uint256 private _totalReleased;
uint256 private _totalPartners;
uint256 private _totalVoters;
mapping(address => uint256) private _released;
bool public closePartnership;
bool public consensus;
struct Partner {
uint weight;
bool voted;
uint vote;
uint shares;
bool isPartner;
}
struct ManagementProposal {
string title;
string proposal;
uint voteCount;
address createdBy;
address addressedTo;
bool shareChange;
bool voting;
}
struct Proposal {
string title;
string proposal;
uint voteCount;
address createdBy;
}
mapping(address => Partner) public partners;
mapping(uint => ManagementProposal) public mProposals;
mapping(uint256 => Proposal) public proposals;
constructor(address[] memory _partners, uint256[] memory _shares) public payable {
require(_partners.length > 0, "PaymentSplitter: no payees");
for(uint256 i = 0; i < _partners.length; i++) {
partners[_partners[i]].isPartner = true;
partners[_partners[i]].shares = _shares[i];
partners[_partners[i]].vote = 1;
}
}
receive() external payable virtual {
emit PaymentReceived(_msgSender(), msg.value);
}
function totalShares() public view returns (uint256) {
return _totalShares;
}
function totalReleased() public view returns (uint256) {
return _totalReleased;
}
function shares(address account) public view returns (uint256) {
return partners[account].shares;
}
function released(address account) public view returns(uint256) {
return _released[account];
}
function release(address payable account) public virtual nonReentrant whenNotPaused {
require(partners[account].shares > 0, 'PaymentSplitter: account has no shares');
uint256 totalReceived = address(this).balance.add(_totalReleased);
uint256 payment = totalReceived.mul(partners[account].shares).div(_totalShares).sub(_released[account]);
require(payment != 0, 'PaymentSplitter: account is not due payment');
_released[account] = _released[account].add(payment);
_totalReleased = _totalReleased.add(payment);
account.transfer(payment);
emit PaymentReleased(account, payment);
}
function _removePayee(address account, uint256 shares_) internal onlyOwner whenNotPaused {
require(account != address(0), 'PaymentSplitter: account is the zero address');
require(shares_ < 0, 'PaymentSplitter: account already has shares');
partners[account].shares = 0;
_totalShares = _totalShares.sub(shares_);
emit PayeeRemoved(account, partners[account].shares);
}
function pause() public onlyOwner {
_pause();
}
function unpause() public onlyOwner {
_unpause();
}
modifier onlyPartners(address partner) {
require(partners[partner].weight == 1, 'You are not a partner!');
_;
}
function makeProposal(string memory _title, string memory _proposal, uint256 _proposalNumber) public onlyPartners(msg.sender) {
proposals[_proposalNumber].title = _title;
proposals[_proposalNumber].proposal = _proposal;
proposals[_proposalNumber].voteCount = 0;
proposals[_proposalNumber].createdBy = msg.sender;
}
function propForRightToVote(address partner, uint256 _proposalNumber, string memory _title, string memory _proposal) external onlyPartners(msg.sender) whenNotPaused{
mProposals[_proposalNumber].title = _title;
mProposals[_proposalNumber].proposal = _proposal;
mProposals[_proposalNumber].voteCount = 0;
mProposals[_proposalNumber].createdBy = msg.sender;
mProposals[_proposalNumber].addressedTo = partner;
mProposals[_proposalNumber].shareChange = false;
mProposals[_proposalNumber].voting = true;
}
function propRightToVoteConsensus(uint _proposalNumber) public onlyOwner {
require(mProposals[_proposalNumber].voting == true, 'Proposal not for right to vote');
require(mProposals[_proposalNumber].voteCount > _totalVoters.div(2), 'No majority votes');
giveRightToVote(mProposals[_proposalNumber].addressedTo);
}
function giveRightToVote(address partner) internal onlyOwner {
require(!partners[partner].voted, 'You have already voted.');
require(partners[partner].weight == 0, 'You are already allowed to vote');
partners[partner].weight = 1;
_totalVoters.add(1);
}
function propForRemoveVoting(address partner, uint256 _proposalNumber, string memory _title, string memory _proposal) external onlyPartners(msg.sender) whenNotPaused {
mProposals[_proposalNumber].title = _title;
mProposals[_proposalNumber].proposal = _proposal;
mProposals[_proposalNumber].voteCount = 0;
mProposals[_proposalNumber].createdBy = msg.sender;
mProposals[_proposalNumber].addressedTo = partner;
mProposals[_proposalNumber].shareChange = false;
mProposals[_proposalNumber].voting = false;
}
function removeVoteConsensus(uint _proposalNumber) external onlyOwner whenNotPaused {
require(mProposals[_proposalNumber].voting == false, 'Proposal not for right to vote');
require(mProposals[_proposalNumber].voteCount > _totalVoters.div(2), 'No majority votes');
renounceRightToVote(mProposals[_proposalNumber].addressedTo);
}
function renounceRightToVote(address partner) internal onlyOwner {
require(partners[partner].voted, 'You have not voted.');
require(partners[partner].weight == 1, 'You are not allowed to vote');
partners[partner].weight = 0;
_totalVoters.sub(1);
}
function voteForApproval(string memory _title, address partner, string memory _proposal, uint256 _proposalNumber) external onlyOwner {
mProposals[_proposalNumber].title = _title;
mProposals[_proposalNumber].proposal = _proposal;
mProposals[_proposalNumber].voteCount = 0;
mProposals[_proposalNumber].createdBy = msg.sender;
mProposals[_proposalNumber].addressedTo = partner;
}
function approveOnConsensus(uint256 _proposalNumber, uint share) public onlyOwner {
require(mProposals[_proposalNumber].voteCount > _totalVoters.div(2), 'Proposal does not have majority votes');
addPartner(mProposals[_proposalNumber].addressedTo, share);
}
function addPartner(address partner, uint shares_) internal onlyOwner {
require(partner != address(0), 'PaymentSplitter: account is the zero address');
require(shares_ > 0, 'PaymentSplitter: account already has shares');
partners[partner].shares = shares_;
_totalShares = _totalShares.add(shares_);
emit PayeeAdded(partner, shares_);
partners[partner].isPartner = true;
}
function voteForRemoval(string memory _title, address partner, string memory _proposal, uint256 _proposalNumber) external onlyPartners(msg.sender){
require(partners[partner].isPartner == true, 'Recipient is not a partner');
mProposals[_proposalNumber].title = _title;
mProposals[_proposalNumber].proposal = _proposal;
mProposals[_proposalNumber].voteCount = 0;
mProposals[_proposalNumber].createdBy = msg.sender;
mProposals[_proposalNumber].addressedTo = partner;
}
function removeOnConsensus(uint256 _proposalNumber) public onlyOwner {
require(mProposals[_proposalNumber].voteCount > _totalVoters.div(2), 'Proposal does not have majority votes');
removePartner(mProposals[_proposalNumber].addressedTo);
}
function removePartner(address partner) internal onlyOwner {
delete partners[partner];
}
function vote(uint proposal) external onlyPartners(msg.sender) whenNotPaused nonReentrant {
Partner storage partner = partners[msg.sender];
require(partner.weight != 0, 'You have no right to vote');
require(!partner.voted, 'You have already voted');
partner.voted = true;
partner.vote = proposal;
proposals[proposal].voteCount += partner.weight;
}
function readProposal(uint _proposalNumber) public onlyPartners(msg.sender) view returns (string memory _title, string memory _proposal, uint _voteCount, address _createdBy) {
return (proposals[_proposalNumber].title,
proposals[_proposalNumber].proposal,
proposals[_proposalNumber].voteCount,
proposals[_proposalNumber].createdBy);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment