Ownable is not implemented in Wizard. TL;DR the core features like "transfer" require access control by default.
See original GitHub issueHi,
Just a quick observation from my experience with the Wizard (which is awesome by the way).
If a user selects the Ownable radio button in the Access Control section, the smart contract source code does not actually implement any ownable functionality. For example, the following code is generated.
Example 1
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract MyToken is ERC20 {
    constructor() ERC20("MyToken", "MTK") {}
}
Instead, the code should look more like the following.
Example 2
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MyToken is ERC20, Ownable {
    constructor() ERC20("MyToken", "MTK") {}
}
If the code from example 1 is deployed anyone can send tokens to anyone and so forth. There is not concept of ownership implemented.
This can be tested by deploying the code from example 1 and then instantiating an ERC20 contract instance using:
- the contract address from example 1’s deployment
- the ABI from example 2’s compile
Querying the owner will return a zero address 0x0...00 and any functions where the onlyOwner modifier should be implemented i.e. transfer will be callable by anyone and still succeed.
Hope this makes sense 😃 Thanks
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)

 Top Related Medium Post
Top Related Medium Post Top Related StackOverflow Question
Top Related StackOverflow Question
Hi @frangio You are 100% correct. A thousand apologies.
I’ll tell you exactly what happened. When I refreshed my remix session, in my browser, the environment defaulted to “JavaScript VM (London)”, with out me noticing. I intended to have the environment connected to Ropsten via MetaMask at all times.
I seemed to be able to transfer ERC20 tokens on the contract I deployed; even when changing between external accounts in MetaMask. This seemed very odd to me and I was concerned that there was some underlying issue. Now I understand that remix was not even acknowledging MetaMask and I was transacting as the same single account in the JavaScript VM (London) environment. Again, a thousand apologies and sorry for taking up your valuable time.
As you say the transfer function is fundamentally only able to transfer tokens if the msg.sender actually has tokens to transfer.
I have to own, both, my correctness and my blunders, right? 😃 Thanks again for your time. Kind regards Tim
I don’t think there are any more actionables in this issue.