Discover more of Etherscan's tools and services in one place.
Sponsored
Contract Source Code:
File 1 of 1 : ETHCMiningPool
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.26; abstract contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); constructor(address owner_) { _transferOwnership(owner_); } modifier onlyOwner() { _checkOwner(); _; } function owner() public view virtual returns (address) { return _owner; } function _checkOwner() internal view virtual { require(owner() == msg.sender, "Ownable: caller is not the owner"); } function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } interface IETHC { struct Block { address[] miners; address selectedMiner; uint256 miningReward; } function mine(uint256 mineCount) external payable; function futureMine(uint256 mineCount, uint256 blockCounts) external payable; function revealSelectedMiner(uint256 targetBlock) external; function selectedMinerOfBlock(uint256 _blockNumber) external view returns (address); function minersOfBlockCount(uint256 _blockNumber) external view returns (uint256); function blockNumber() external view returns (uint256); function mineCost() external view returns (uint256); function blocks(uint256 blockNumber) external view returns (Block memory); function transfer(address to, uint value) external returns (bool); function balanceOf(address owner) external view returns (uint); } contract ETHCMiningPool is Ownable { IETHC public ETHC; uint256 contributionDenominator; mapping(uint256 => uint256) public totalBlockContribution; mapping(address => mapping(uint256 => uint256)) public minerContributionPerBlock; mapping(uint256 => uint8) public successfullyMined; mapping(uint256 => uint256) public miningReward; uint256 feesPayable; address feeCollector; // Fees set to 2% to start uint256 feeNumerator = 20; uint256 feeDenominator = 1000; bool _locked; modifier Lock { require(!_locked); _locked = true; _; _locked = false; } constructor( address tokenAddress, address feeCollector_ ) Ownable(msg.sender) { ETHC = IETHC(tokenAddress); feeCollector = feeCollector_; } function mine(uint256 mineCount) public payable Lock { uint256 blockNumber = ETHC.blockNumber(); minerContributionPerBlock[msg.sender][blockNumber] += mineCount; totalBlockContribution[blockNumber] += mineCount; ETHC.mine{value: msg.value}(mineCount); } function futureMine(uint256 mineCount, uint256 blockCounts) external payable Lock { uint256 blockNumber = ETHC.blockNumber(); for (uint256 i=0; i<blockCounts; i++) { blockNumber += 1; minerContributionPerBlock[msg.sender][blockNumber] += mineCount; totalBlockContribution[blockNumber] += mineCount; } ETHC.futureMine{value: msg.value}(mineCount, blockCounts); } function resolveBlocks(uint256[] memory blockNumbers) external Lock { for (uint256 i=0; i<blockNumbers.length; i++) { uint256 blockNumber = blockNumbers[i]; if (successfullyMined[blockNumber] != 0) { continue; } address selectedMiner = ETHC.selectedMinerOfBlock(blockNumber); if (selectedMiner == address(0)) { continue; } else if (selectedMiner == address(this)) { successfullyMined[blockNumber] = 1; IETHC.Block memory blockData = ETHC.blocks(blockNumber); uint256 fees = blockData.miningReward * feeNumerator / feeDenominator; feesPayable += fees; miningReward[blockNumber] = blockData.miningReward - fees; } else { successfullyMined[blockNumber] = 2; } } } function collectBlocksRewards(uint256[] memory blockNumbers) external Lock { uint256 rewards = 0; for (uint256 i=0; i<blockNumbers.length; i++) { uint256 blockNumber = blockNumbers[i]; // Case: succesfully mined unset if (successfullyMined[blockNumber] == 0) { address selectedMiner = ETHC.selectedMinerOfBlock(blockNumber); // Case: Still not mined if (selectedMiner == address(0)) { continue; // Case: mined and the pool was selected } else if (selectedMiner == address(this)) { successfullyMined[blockNumber] = 1; IETHC.Block memory blockData = ETHC.blocks(blockNumber); uint256 fees = blockData.miningReward * feeNumerator / feeDenominator; feesPayable += fees; miningReward[blockNumber] = blockData.miningReward - fees; // Case: mined and the pool was not selected } else { successfullyMined[blockNumber] = 2; continue; } // Case: we have already determined the pool was not selected } else if (successfullyMined[blockNumber] == 2) { continue; } rewards += miningReward[blockNumber] * minerContributionPerBlock[msg.sender][blockNumber] / totalBlockContribution[blockNumber]; totalBlockContribution[blockNumber] -= minerContributionPerBlock[msg.sender][blockNumber]; delete minerContributionPerBlock[msg.sender][blockNumber]; } if (rewards > 0) { ETHC.transfer(msg.sender, rewards); } } function checkRewardsForBlocks(uint256[] memory blockNumbersToCheck) external view returns (uint256 totalRewards) { for (uint256 i; i<blockNumbersToCheck.length; i++) { uint256 blockNumber = blockNumbersToCheck[i]; uint256 blockReward = 0; // Case: succesfully mined unset if (successfullyMined[blockNumber] == 0) { address selectedMiner = ETHC.selectedMinerOfBlock(blockNumber); // Case: Still not mined if (selectedMiner == address(0)) { continue; // Case: mined and the pool was selected } else if (selectedMiner == address(this)) { IETHC.Block memory blockData = ETHC.blocks(blockNumber); uint256 fees = blockData.miningReward * feeNumerator / feeDenominator; blockReward = blockData.miningReward - fees; // Case: mined and the pool was not selected } else { continue; } // Case: we have already determined the pool was not selected } else if (successfullyMined[blockNumber] == 2) { continue; } totalRewards += blockReward * minerContributionPerBlock[msg.sender][blockNumber] / totalBlockContribution[blockNumber]; } } function collectFee(uint256 amount) external onlyOwner { require(amount <= feesPayable); if (feesPayable > 0 && feeCollector != address(0)) { ETHC.transfer(feeCollector, amount == 0 ? feesPayable : amount); } } function setFeeCollector(address newFeeCollector) external onlyOwner { feeCollector = newFeeCollector; } function setFeeNumerator(uint256 newFeeNumerator) external onlyOwner { require(newFeeNumerator < feeNumerator); feeNumerator = newFeeNumerator; } function rescueRewards(uint256 amount) external onlyOwner { ETHC.transfer(msg.sender, amount); } receive() external payable Lock { uint256 mineCost = ETHC.mineCost(); uint256 mineCount = msg.value / mineCost; uint256 totalCost = mineCost * mineCount; if (totalCost < address(this).balance) { msg.sender.call{value: address(this).balance - totalCost}(""); } if (mineCount > 0) { mine(mineCount); } } }
Please enter a contract address above to load the contract details and source code.
Please DO NOT store any passwords or private keys here. A private note (up to 100 characters) can be saved and is useful for transaction tracking.
My Name Tag:
Private Note:
This website uses cookies to improve your experience. By continuing to use this website, you agree to its Terms and Privacy Policy.