Contract Name:
TxFeeDistributor
Contract Source Code:
File 1 of 1 : TxFeeDistributor
// SPDX-License-Identifier: MIT
//TX Fee distributor contract
pragma solidity ^0.8.17;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address public owner;
address public voter;
event OwnershipRenounced(address indexed previousOwner);
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the sender
* account.
*/
constructor() {
owner = msg.sender;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
modifier onlyVoter() {
require(msg.sender == voter);
_;
}
/**
* @dev Allows the current owner to relinquish control of the contract.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipRenounced(owner);
owner = address(0);
}
/**
* @dev Allows the current owner to transfer control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function transferOwnership(address _newOwner) public onlyOwner {
_transferOwnership(_newOwner);
}
/**
* @dev Transfers control of the contract to a newOwner.
* @param _newOwner The address to transfer ownership to.
*/
function _transferOwnership(address _newOwner) internal {
require(_newOwner != address(0));
emit OwnershipTransferred(owner, _newOwner);
owner = _newOwner;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function decimals() external returns (uint8);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
contract TxFeeDistributor is Ownable{
address[] public shareholders;
mapping(address => uint256) public shares; // Shares for each shareholder
mapping(address => bool) public isShareholder;
mapping(address => bool) public whitelisted;
uint256 public totalShares;
uint256 public totalAmount;
event FeeDistributed(address indexed recipient, uint256 amount);
event SharesUpdated(address indexed shareholder, uint256 oldShares, uint256 newShares);
event ShareholderAdded(address indexed shareholder);
event ShareholderRemoved(address indexed shareholder);
constructor() {
owner = msg.sender;
}
// Function to set shares for a shareholder
function setShares(address _shareHolder, uint256 _share) public onlyOwner {
require(_shareHolder != address(0), "Invalid address");
require(_share >= 0 && _share <= 10000, "Invalid share percentage");
if (isShareholder[_shareHolder]) {
totalShares = totalShares - shares[_shareHolder] + _share;
shares[_shareHolder] = _share;
if (_share == 0) {
removeShareholder(_shareHolder);
}
} else {
require(_share > 0, "Share must be greater than 0 to add shareholder");
addShareholder(_shareHolder);
shares[_shareHolder] = _share;
totalShares += _share;
}
emit SharesUpdated(_shareHolder, shares[_shareHolder], _share);
}
// Function to edit shares for an existing shareholder
function editShares(address shareholder, uint256 newShare) public onlyOwner {
require(shareholder != address(0), "Invalid address");
require(newShare >= 0 && newShare <= 10000, "Invalid share percentage");
require(isShareholder[shareholder], "Address is not a shareholder");
uint256 currentShare = shares[shareholder];
if (newShare == 0) {
// If the new share is zero, remove the shareholder
removeShareholder(shareholder);
} else if (currentShare == 0 && newShare > 0) {
// If currently no shares and new shares are added, add as shareholder
addShareholder(shareholder);
}
// Update total shares and shareholder's shares
totalShares = totalShares - currentShare + newShare;
shares[shareholder] = newShare;
emit SharesUpdated(shareholder, currentShare, newShare);
}
// Function to distribute fees among shareholders based on their shares
function distributeFees() public {
require(whitelisted[msg.sender],"not whitelisted");
uint256 totalReceived = address(this).balance;
for (uint i = 0; i < shareholders.length; i++) {
uint256 payment = totalReceived * shares[shareholders[i]] / totalShares;
(bool distributionSuccess,) = payable(shareholders[i]).call{value:payment}("");
emit FeeDistributed(shareholders[i], payment);
}
}
// Helper functions to manage shareholders
function addShareholder(address shareholder) internal {
isShareholder[shareholder] = true;
shareholders.push(shareholder);
emit ShareholderAdded(shareholder);
}
function removeShareholder(address shareholder) internal {
isShareholder[shareholder] = false;
for (uint i = 0; i < shareholders.length; i++) {
if (shareholders[i] == shareholder) {
shareholders[i] = shareholders[shareholders.length - 1];
shareholders.pop();
break;
}
}
emit ShareholderRemoved(shareholder);
}
function disableHolder(address _holder) public onlyOwner{
require(isShareholder[_holder], "not a holder");
isShareholder[_holder] = false;
}
function enableHolder(address _holder) public onlyOwner{
require(!isShareholder[_holder], "already a holder");
isShareholder[_holder] = true;
}
// Emergency withdrawal by owner
function emergencyWithdraw() public onlyOwner returns(bool) {
uint256 balance = address(this).balance;
(bool withdrawSuccess,) = payable(owner).call{value: balance}("");
return withdrawSuccess;
}
// Emergency withdrawal by owner
function emergencyWithdrawTokens(address _token, uint256 _amount) public onlyOwner {
IERC20(_token).transfer(owner,_amount);
}
// View the balance of the contract
function getBalance() public view returns (uint256) {
return address(this).balance;
}
function addWhitelist(address _addWhitelistAddress) public onlyOwner {
require(!whitelisted[_addWhitelistAddress],"already whitelist addrs");
whitelisted[_addWhitelistAddress] = true;
}
function removeWhitelist(address _removeWhitelistAddress) public onlyOwner {
require(whitelisted[_removeWhitelistAddress],"not whitelist addrs");
whitelisted[_removeWhitelistAddress] = false;
}
receive() external payable {
totalAmount = totalAmount + msg.value;
}
}