Skip to content

Instantly share code, notes, and snippets.

@artyomLisovskij
Created September 20, 2021 11:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save artyomLisovskij/c9cadff22538c3cfd785a294a7038312 to your computer and use it in GitHub Desktop.
Save artyomLisovskij/c9cadff22538c3cfd785a294a7038312 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.7;
contract Multisig {
mapping (uint256 => address) private votersIds;
mapping (address => bool) private voters;
uint256 private _votersCounter;
uint256 private _activeVoters;
struct VoterRequest{
bool status;
address candidate;
bool include;
}
mapping (uint256 => VoterRequest) private _voterRequests;
mapping (uint256 => mapping(address=>bool)) private _voterRequsestsSignatures;
uint256 private _voterRequestCounter;
constructor() {
_setVoter(msg.sender);
}
modifier onlyVoter {
require(voters[msg.sender], "not voter");
_;
}
function getVoterById(uint _id) internal view returns (address) {
return votersIds[_id];
}
function getVoterStatusByAddress(address _address) internal view returns (bool) {
return voters[_address];
}
function getActiveVoters() internal view returns (uint) {
return _activeVoters;
}
function getVotersCounter() internal view returns (uint) {
return _votersCounter;
}
// good news, new voter
function _setVoter(address _newVoter) internal {
require(_newVoter != address(0), "zero address");
require(!voters[_newVoter], "already voter");
voters[_newVoter] = true;
_activeVoters++;
}
function _unsetVoter(address _oldVoter) internal {
require(_oldVoter != address(0), "zero address");
require(voters[_oldVoter], "not voter");
voters[_oldVoter] = false;
_activeVoters--;
}
function newVotersRequest(address[] memory _newVoters) external onlyVoter {
for (uint i=0; i<_newVoters.length; i++) {
require(!voters[_newVoters[i]], "already voter");
// create request to be voter
_voterRequests[_voterRequestCounter++] = VoterRequest({
status: false,
candidate: _newVoters[i],
include: true
});
// sign
_voterRequsestsSignatures[_voterRequestCounter][msg.sender] = true;
}
}
function checkVotersRequest(uint256 _id) external {
require(!_voterRequests[_id].status, "already approved");
uint256 consensus = _activeVoters / 2 + 1;
uint256 trueVotesCount;
for (uint i=0; i<_votersCounter; i++) {
// signed and he voter now
if (_voterRequsestsSignatures[_id][votersIds[i]] && voters[votersIds[i]]) {
trueVotesCount++;
}
}
if (trueVotesCount > consensus) {
if (_voterRequests[_id].include) {
_setVoter(_voterRequests[_id].candidate);
} else {
_unsetVoter(_voterRequests[_id].candidate);
}
_voterRequests[_id].status = true;
}
}
}
mapping (uint256 => TransferRequest) private _transferRequests;
mapping (uint256 => mapping(address=>bool)) private _transferRequestsSignatures;
uint256 private _transferRequestCounter;
function withdrawalAdminRequest(address recipient, uint256 amount)
public
onlyVoter returns (uint)
{
_transferRequests[_transferRequestCounter++] = TransferRequest({
recepient: recipient,
value: amount,
status: false
});
// sign
_transferRequestsSignatures[_transferRequestCounter][msg.sender] = true;
return _transferRequestCounter;
}
function checkTransferRequest(uint256 _id) external {
require(!_transferRequests[_id].status, "already approved");
uint256 consensus = getActiveVoters() / 2 + 1;
uint256 trueVotesCount;
for (uint i=0; i<getVotersCounter(); i++) {
// signed and he voter now
if (_transferRequestsSignatures[_id][getVoterById(i)] && getVoterStatusByAddress(getVoterById(i))) {
trueVotesCount++;
}
}
if (trueVotesCount > consensus) {
require(_transferRequests[_id].value <= usdt.balanceOf(address(this)) - reserved, "not enough reserve");
require(usdt.transfer(_transferRequests[_id].recepient, _transferRequests[_id].value), "not transfered");
emit WithdrawnAdmin(_transferRequests[_id].recepient, _transferRequests[_id].value);
_transferRequests[_id].status = true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment