I am new to solidity but I have read at many times that tx.origin
should be avoided & msg.sender
should be used .
There is a given demo on this in solidity page. It says like :-
Never use tx.origin for authorization. Let’s say you have a wallet contract like this:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
// THIS CONTRACT CONTAINS A BUG - DO NOT USE
contract TxUserWallet {
address owner;
constructor() {
owner = msg.sender;
}
function transferTo(address payable dest, uint amount) public {
// THE BUG IS RIGHT HERE, you must use msg.sender instead of tx.origin
require(tx.origin == owner);
dest.transfer(amount); // .transfer is a global variable
}
}
Now someone tricks you into sending Ether to the address of this attack wallet:
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
interface TxUserWallet {
function transferTo(address payable dest, uint amount) external;
}
contract TxAttackWallet {
address payable owner;
constructor() {
owner = payable(msg.sender);
}
receive() external payable {
TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance); // **LINE 1**
}
}
Now , I want to know that how line 1 will drain entire funds from TxUserWallet
. I think transfer()
is a global variable which will just transfer the amount to address in dest
which is of attack wallet. How .transfer()
will trigger receive()
function of contract TxAttackWallet
.
Secondly , In line TxUserWallet(msg.sender).transferTo(owner, msg.sender.balance);
, why are we writing it as TxUserWallet(msg.sender)
, like why are we adding (msg.sender) after contract name
and also what values is being passed by writing msg.sender.balance
?