-
-
Save ssghost/335da05ae04d33657453b5be901fca18 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: MIT | |
pragma solidity 0.8.20; | |
contract Winner is ReentrancyGuard, Pausable { | |
address public owner; | |
address public currentleader; | |
uint256 public lastDepositedAmount; | |
uint256 public currentLeaderReward; | |
uint256 public nextLeaderReward; | |
bool public rewardClaimed; | |
uint256 public immutable challengeEnd; | |
uint256 public challengeEndBlock; | |
mapping(address => uint256) public rewards; | |
mapping(address => uint256) public refunds; | |
event NewLeader(address indexed leader, uint256 amount); | |
event RewardClaimed(address indexed winner, uint256 amount); | |
constructor(uint256 _challengeBlocks) payable { | |
require(msg.value == 10 ether, "Require an initial 10 Ethers reward"); | |
require(msg.value == _initialReward, "Incorrect initial reward"); | |
require(_challengeBlocks > 0, "Challenge block must be greater than 0"); | |
owner = msg.sender; | |
currentleader = address(0); | |
lastDepositedAmount = msg.value; | |
currentLeaderReward = 0; | |
nextLeaderReward = msg.value; | |
rewardClaimed = false; | |
challengeEndBlock = block.number + _challengeBlocks; | |
biddingEnd = challengeEnd - 1 hours; | |
} | |
function pause() external { | |
require(msg.sender == owner, "Not owner"); | |
_pause(); | |
} | |
function unpause() external { | |
require(msg.sender == owner, "Not owner"); | |
_unpause(); | |
} | |
function claimLeader() external payable noReentrant whenNotPaused { | |
require(block.timestamp < biddingEnd, "Bidding period has ended"); | |
require(block.timestamp < challengeEnd, "Challenge is finished"); | |
require(msg.sender != currentleader, "You are the current leader"); | |
require(msg.value > lastDepositedAmount, "You must pay more than the current leader"); | |
require(msg.value >= 1 ether, "Deposit must be at least 1 Ether"); | |
if (currentleader == address(0)) { | |
currentleader = msg.sender; | |
lastDepositedAmount = msg.value; | |
currentLeaderReward = nextLeaderReward; | |
nextLeaderReward += lastDepositedAmount / 10; | |
} | |
else { | |
uint256 refundAmount = lastDepositedAmount * 9 / 10; | |
address prevLeader = currentleader; | |
refunds[prevLeader] += refundAmount; | |
currentleader = msg.sender; | |
lastDepositedAmount = msg.value; | |
currentLeaderReward = nextLeaderReward; | |
nextLeaderReward += lastDepositedAmount / 10; | |
} | |
emit NewLeader(currentleader, lastDepositedAmount); | |
} | |
function withdrawRefund() external { | |
uint256 amount = refunds[msg.sender]; | |
require(amount > 0, "No refund available"); | |
refunds[msg.sender] = 0; | |
(bool success, ) = msg.sender.call{value: amount}(""); | |
require(success, "Failed to send Ether"); | |
} | |
function claimPrincipalAndReward() external noReentrant { | |
require(block.timestamp >= challengeEnd, "Challenge is not finished yet"); | |
require(msg.sender == currentleader, "You are not the winner"); | |
require(!rewardClaimed, "Reward was claimed"); | |
rewardClaimed = true; | |
uint256 amount = lastDepositedAmount + currentLeaderReward; | |
rewards[currentleader] += amount; | |
emit RewardClaimed(msg.sender, amount); | |
} | |
function withdrawReward() external { | |
uint256 amount = rewards[msg.sender]; | |
require(amount > 0, "No reward available"); | |
rewards[msg.sender] = 0; | |
(bool success, ) = msg.sender.call{value: amount}(""); | |
require(success, "Failed to send Ether"); | |
} | |
function getEtherBalance() external view returns (uint256) { | |
return address(this).balance; | |
} | |
function isChallengeEnd() external view returns (bool) { | |
return block.number >= challengeEndBlock; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment