It's been recommended that we should avoid using tx.origin.
However, there're some cases it's really needed, like the following case.
Assume we have two smart contracts: Sc1 and Sc2, both of which are created by the same owner. It first deployes Sc1 that maintains a token balance. Then, the owner creates another smart contract Sc2, deploys it and allows users to interact with Sc2, and transfer some of their tokens from Sc1 to Sc2 (so assume some users have tokens in Sc1). But only the token owners should be able to do that not anybody else (not even the contracts owner).
As you can see below I have to use tx.origin. I'm aware that if the contracts owner creates another invalid contract and make the user (token owners) call it then it will be able to decrement their token_bsalance in Sc1. Below is the code for the above case (the attack is excluded).
contract Sc1{
mapping (address => uint) token_balance;
mapping (address => bool) valid_caller_contracts;// keeps track
//of those contract that can call this contract
address owner;
function Sc1(){
owner = msg.sender;
}
// only owner must be able to register.
function register_valid_contract() external {
require(tx.origin==owner);
valid_caller_contracts[msg.sender] = true;
}
function decrement_token(uint val) external{
require(token_balance[tx.origin] >= val);
token_balance[tx.origin] -=val;
}
}
contract Sc2{
mapping (address => uint) token_balance2;
address owner;
function SC2(){
owner = msg.sender;
}
function register() external{
Sc1 c1=Sc1(0x22);//Let's assum the address of Sc1 after it's
//deployed is 0x22
c1.register_valid_contract();
}
// only those who have tokens in Sc1 must be able to tranfer
//tokens to Sc2.
function fetch_tokens(uint val) external{
Sc1 c1=Sc1(0x22);//Let's assum the address of Sc1 after it's
//deployed is 0x22
c1.decrement_token(val);
token_balance2[msg.sender] += val;
}
}
Question: In the above case, can we avoid using tx.origin?