Current situation on mainnet
Etherscan
Both of these issues can be solved by ERC-20 event being emitted.
Blockscout
Here holders list works.
Background
The underlying cause of these issues is atypical implementation of token contract. It tries to implement both ERC-721 and ERC-20 with the end result that neither is implemented fully, because these standards have overlapping methods. I present rationale for this below.
This is similar to how cash works. Every dollar bill is actually unique (non-fungible), yet we typically treat them as fungible. There’s nothing preventing us from treating them as non-fungible (taking into account the serial number for example). So you have one currency with two different ways of looking at it (like two interfaces).
I think it sometimes makes perfect sense to have a single token with both fungible and non-fungible token interfaces. Respect token is one such example. From non-fungible interface you get information about who attended what meeting (proof-of-attendance), and how much Respect they earned in that meeting (could record more things in the future). From fungible interface you can get a total amount of Respect over series of meetings. So each Respect NTT has a value field. To get someone’s fungible balance you sum values of all NTTs they earned.
It still might have been a better decision to use ERC-1155 standard and to implement these parts as separate tokens (or to implement these interfaces as separate tokens). But at the time when creating Respect contract it seemed to me that ERC-1155 (or at least its OpenZeppelin implementation) was an inefficient way of implementing what I described above. Now I’m reconsidering that in light of the issues with block explorers.
Current Respect interface: https://github.com/Optimystics/op-fractal-sc/blob/main/contracts/IRespect.sol
Solution 1
The main issue here is that only ERC721 transfer event is emitted and not ERC20 one. Etherscan detects holders from ERC20 transfer events. These two events have exactly the same signatures, and differ only in that last argument in ERC20 version specifies amount and in ERC721 token id. So I did not see a way to emit both of these events in solidity, when creating the first version of a contract.
Now I found a way to do that using assembly: https://github.com/Optimystics/op-fractal-sc/commit/a4296ecdff14fbf8b80d2fbfc356556cb475892a Deployed and tested this on Optimism Sepolia and Optimism Goerli. Results:
- On Etherscan:
- Holders list now works but as was to be expected, only holders for which the transfer event was emitted are displayed (so accounts which received Respect before contract upgrade are not displayed).
- In Respect distribution transaction you can now see both ERC-721 and ERC-20 events (which is nice because people can see who earned how much in the meeting): https://sepolia-optimism.etherscan.io/tx/0xef89e0f54c9c11edf3fc1f9d748370116f6a743a79488019722f46e87808d5b4
- On Blockscout
- Blockscout does not recognize ERC-20 transfer events as ERC-20 transfer events and thinks it’s another ERC-721 event: https://optimism-sepolia.blockscout.com/tx/0xef89e0f54c9c11edf3fc1f9d748370116f6a743a79488019722f46e87808d5b4
So remaining issues: