/* * @source: https://consensys.github.io/smart-contract-best-practices/known_attacks/ * @author: consensys * @vulnerable_at_lines: 28 */ pragma solidity ^0.4.0; contract Reentrancy_bonus{ // INSECURE mapping (address => uint) private userBalances; mapping (address => bool) private claimedBonus; mapping (address => uint) private rewardsForA; function withdrawReward(address recipient) public { uint amountToWithdraw = rewardsForA[recipient]; rewardsForA[recipient] = 0; (bool success, ) = recipient.call.value(amountToWithdraw)(""); require(success); } function getFirstWithdrawalBonus(address recipient) public { require(!claimedBonus[recipient]); // Each recipient should only be able to claim the bonus once rewardsForA[recipient] += 100; // REENTRANCY withdrawReward(recipient); // At this point, the caller will be able to execute getFirstWithdrawalBonus again. claimedBonus[recipient] = true; } }