Created
September 20, 2021 11:35
-
-
Save artyomLisovskij/c9cadff22538c3cfd785a294a7038312 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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