question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Change default owner/admin accounts to `tx.origin` rather than `msg.sender`

See original GitHub issue

🧐 Motivation Some background: I’m the author of the Hardhat plugin xdeployer that helps to deploy smart contracts across multiple EVM chains with the same deterministic address (keyword CREATE2 opcode). Since opcodes can only be called via smart contracts, the default owner of a deployed contract with CREATE2 (and my plugin) will be a contract address (using your default npm package as dependency) which is obviously not good. How about setting the default owner to tx.origin and make everything more agnostic? Like that it can be ensured that the original EOA user will always be the owner. The same applies to the default roles in your OpenZeppelin Wizard for DEFAULT_ADMIN_ROLE, PAUSER_ROLE, MINTER_ROLE:

    constructor() ERC20("MyToken", "MTK") {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(PAUSER_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
    }

I’m fully aware of the security considerations re tx.origin (https://docs.soliditylang.org/en/v0.8.11/security-considerations.html?highlight=tx.origin#tx-origin), however, in this case, we would not touch the authorization but rather “only” the constructor argument.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
Amxxcommented, Dec 22, 2021

We already had some request to change the Ownable constructor to

constructor(address admin) {
        _transferOwnership(admin);
}

IMO this would be much better then using tx.origin, yet we rejected this proposition because it would be a breaking change. We are VERY careful about any breaking change, which you proposal would be. Also we are, like most of the community, against using tx.origin. This has been the source of a lot of bugs.

If you really want to set tx.origin has the original owner (I would advice against it) you always have the possibility to do.

contract YourContract is Ownable {
    constructor() {
        transferOwnership(tx.origin);
    }
}
1reaction
frangiocommented, Dec 22, 2021

We disagree that it’s okay to use tx.origin in the constructor, at least in general. What you really want for the scenario you describe is to use the address of the caller to the factory contract, but this is not the same as tx.origin, because the caller to the factory contract may be another smart contract that should become the owner of the newly created contract.

This is always going to be a problem with factories and the factory created contract needs to be aware of that and/or offer a way to initialize it to the right values. For example, with an Ownable contract you can initialize the contract with a call to transferOwnership.

This is a proposal for a more general solution for the Wizard:

Read more comments on GitHub >

github_iconTop Results From Across the Web

`msg.sender` instead of `tx.origin` - Ethereum Stack Exchange
i.e. the EOA that initiated the chain of transactions. msg.sender doesn't stay the same and, in this case would change to the attack ......
Read more >
tx.origin vs msg.sender - David Kathoh - Medium
As you may notice, both account address and smart contract address can be msg.sender but tx.origin will always be the account/wallet address ......
Read more >
`msg.sender` preferred over `tx.origin` in Solidity
I am new to solidity but I have read at many times that tx.origin should be avoided & msg.sender should be used ....
Read more >
Juicebox V2 contest — Code 423n4 - Code4rena
When the owner calls the changeTokenOf function of the JBController contract, the token corresponding to the current project will be changed, which will...
Read more >
Address 0x232d0620fe7f5f383740cf2880782d80b22e3b0a
totalClaimed[msg.sender] += amount; } function _mint(address to, uint tokenId, ... "Must request more than 0"); require(msg.sender == tx.origin, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found