I have just followed this OpenZeppelin tutorial for creating an upgradeable contract.
The only difference I made is that rather than use Box.sol contract (see tutorial), I wrote an ERC-20 token logic along with an access control mechanism. The code of my token appears below.
I have deployed the contract to Rinkeby.
Proxy: 0x9d85447F7616Ee1FD720cDc844Ead7C12F786457
Logic: 0x19fFeaB0141AF5765216a3b19958F68565ca6d4e
My concern is that Etherscan, when looking at the proxy's 'Read Contract' says: "Sorry, there are no available Contract ABI methods to read. Unable to read contract info". I noticed that some of the 'Write Contract' methods should be classified as reads.
I can still programmatically interact with the proxy as I normally do, but would prefer to implement the contract so that Etherscan properly recognizes which methods are 'reads' and which are 'writes'. How can I do this?
Code to reproduce
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
contract SimpleToken is Initializable, ERC20Upgradeable, AccessControlUpgradeable {
bytes32 public constant USER_ROLE = keccak256("USER_ROLE");
function initialize() public initializer {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
__ERC20_init("SimpleToken","SMT");
_mint(address(0xeF008d5228cEFD52d806876586aFf7d0371Eb91B), 32 * 10 ** decimals());
}
function mint(address to, uint256 amount) public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Must be ADMIN.");
require(hasRole(USER_ROLE, to), "Recipient must be USER.");
_mint(to, amount);
}
function burn(address from, uint256 amount) public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Must be ADMIN.");
_burn(from, amount);
}
function transfer(address to, uint256 value) public override returns (bool) {
require(hasRole(USER_ROLE, to), "Recipient must be USER.");
return super.transfer(to, value);
}
function transferFrom(address from, address to, uint256 value) public override returns (bool) {
require(hasRole(USER_ROLE, to), "Recipient must be USER.");
require(hasRole(USER_ROLE, msg.sender), "You must hold USER status to send tokens.");
return super.transferFrom(from, to, value);
}
}