Created
July 29, 2024 14:10
-
-
Save phunguyen19/472f6868d7c2a6240ae0b389040f4d8f to your computer and use it in GitHub Desktop.
Example Ethereum Smart Contract Unexpected Ether vulnerability
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
contract EtherGame { | |
uint public payoutMileStone1 = 3 ether; | |
uint public mileStone1Reward = 2 ether; | |
uint public payoutMileStone2 = 5 ether; | |
uint public mileStone2Reward = 3 ether; | |
uint public finalMileStone = 10 ether; | |
uint public finalReward = 5 ether; | |
mapping(address => uint) redeemableEther; | |
// Users pay 0.5 ether. At specific milestones, credit their accounts. | |
function play() external payable { | |
require(msg.value == 0.5 ether); // each play is 0.5 ether | |
uint currentBalance = this.balance + msg.value; | |
// ensure no players after the game has finished | |
require(currentBalance <= finalMileStone); | |
// if at a milestone, credit the player's account | |
if (currentBalance == payoutMileStone1) { | |
redeemableEther[msg.sender] += mileStone1Reward; | |
} | |
else if (currentBalance == payoutMileStone2) { | |
redeemableEther[msg.sender] += mileStone2Reward; | |
} | |
else if (currentBalance == finalMileStone ) { | |
redeemableEther[msg.sender] += finalReward; | |
} | |
return; | |
} | |
function claimReward() public { | |
// ensure the game is complete | |
require(this.balance == finalMileStone); | |
// ensure there is a reward to give | |
require(redeemableEther[msg.sender] > 0); | |
uint transferValue = redeemableEther[msg.sender]; | |
redeemableEther[msg.sender] = 0; | |
msg.sender.transfer(transferValue); | |
} | |
} |
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
contract EtherGame { | |
uint public payoutMileStone1 = 3 ether; | |
uint public mileStone1Reward = 2 ether; | |
uint public payoutMileStone2 = 5 ether; | |
uint public mileStone2Reward = 3 ether; | |
uint public finalMileStone = 10 ether; | |
uint public finalReward = 5 ether; | |
uint public depositedWei; | |
mapping (address => uint) redeemableEther; | |
function play() external payable { | |
require(msg.value == 0.5 ether); | |
uint currentBalance = depositedWei + msg.value; | |
// ensure no players after the game has finished | |
require(currentBalance <= finalMileStone); | |
if (currentBalance == payoutMileStone1) { | |
redeemableEther[msg.sender] += mileStone1Reward; | |
} | |
else if (currentBalance == payoutMileStone2) { | |
redeemableEther[msg.sender] += mileStone2Reward; | |
} | |
else if (currentBalance == finalMileStone ) { | |
redeemableEther[msg.sender] += finalReward; | |
} | |
depositedWei += msg.value; | |
return; | |
} | |
function claimReward() public { | |
// ensure the game is complete | |
require(depositedWei == finalMileStone); | |
// ensure there is a reward to give | |
require(redeemableEther[msg.sender] > 0); | |
uint transferValue = redeemableEther[msg.sender]; | |
redeemableEther[msg.sender] = 0; | |
msg.sender.transfer(transferValue); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment