π―
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
/* Bad */ | |
int totalValue = 275000; | |
int percentage = 2; | |
for (uint i = 0; i < 30; i++) { | |
totalValue += totalValue * percentage / 100; | |
} | |
/* | |
Exact value: 498124.436 | |
Result: 498108 | |
*/ |
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
/* Bad */ | |
pragma solidity =0.4.11; | |
contract Bad { | |
mapping(address => uint256) balances; | |
function badWithdraw(uint256 amounts) public { | |
require(amounts <= balances[msg.sender]); | |
balances[msg.sender] -= amounts; | |
(bool success, bytes memory data) = msg.sender.call{value: amounts}(""); | |
require(success); | |
} |
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
/* Bad */ | |
contract TimedCrowdsale { | |
event Finished(); | |
event notFinished(); | |
// Sale should finish exactly at January 1, 2019 | |
function isSaleFinished() private returns (bool) { | |
return block.timestamp >= 1546300800; | |
} |
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
/* Bad */ | |
function getRandomNum() public view returns(uint256 randomNum_) { | |
randomNum_ = uint256(keccak256(block.blockhash(block.number - 1), now)) | |
} | |
/* Better */ | |
// Using VRF by Chainlink | |
// https://docs.chain.link/docs/vrf/v2/examples/get-a-random-number/ |
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
/* Bad */ | |
string private password; | |
/* Better */ | |
// string private password | |
// shouldn't store the password on blockchain |
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
/* Bad */ | |
function badWithdraw(uint amounts) public { | |
require(amounts <= balances[msg.sender]); // 1.πππππ | |
// there is no risk of reentrancy because transfer is 2300 gas | |
msg.sender.transfer(amounts) // 3.ππ‘π§ππ₯πππ§ππ’π‘ | |
balances[msg.sender] - amounts; // 2.ππππππ§π¦ | |
} | |
/* Better */ | |
function goodWithdraw(uint amounts) public { |
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 Guarded { | |
... | |
bool locked = false; | |
function withdraw() external { | |
require(!locked, "Reentrant call detected!"); | |
locked = true; | |
... | |
locked = false; |
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
address token; | |
mapping(address => uint) canBorrowAmount; | |
/* Bad */ | |
function badBorrow(uint amounts) public { | |
require(amounts <= canBorrowAmount[msg.sender]); // 1.πππππ | |
IERC777(token).transfer(msg.sender, amounts) // 3.ππ‘π§ππ₯πππ§ππ’π‘ | |
canBorrowAmount[msg.sender] - amounts; // 2.ππππππ§π¦ | |
} | |
/* Better */ |
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
/* Bad */ | |
function badWithdraw(uint amounts) public { | |
require(amounts <= balances[msg.sender]); // 1.πππππ | |
(bool success, bytes memory data) | |
= msg.sender.call{value: amounts}(""); // 3.ππ‘π§ππ₯πππ§ππ’π‘ | |
require(success); | |
balances[msg.sender] - amounts; // 2.ππππππ§π¦ | |
} | |
/* Better */ |
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
/* Bad */ | |
contract Bad { | |
function badDelegate(address _yourContract, bytes calldata _data) payable public returns (bytes memory) { | |
(bool success, bytes memory data) = _yourContract.delegatecall(_data); | |
require(success); | |
return data; | |
} | |
} | |
/* Vulnerability | |
Anyone can destroy the Bad contract using by βselfdestructβ |