Git Product home page Git Product logo

erc404's People

Contributors

0xacme avatar caldereth avatar mathdroid avatar wozhendeai avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erc404's Issues

High ID Numbers Encoded

Hello,

I've just tested the new version and it's working very well. However, I have a question regarding the ID encoding system.

I've noticed that the ID encoding system generates quite high numbers. I understand there might be technical reasons behind this decision, but I'd like to know if it's absolutely necessary to keep these values so high.

Would it be possible to configure or edit the encoding system to start the ID sequence from a lower number, such as 1, to have IDs like 1, 2, 3, 4, etc.? This would make management and tracking much easier for my specific use case.

Thank you for your attention, and I look forward to your response.

Ditch whitelist in favor of opt-in

Opportunity

Maintaining a whitelist amidst an unpredictable sea of DEXs and DEX aggregators seems untenable. It certainly isn't "decentralized" and also ties the contract creator to a responsibility they could do without in their lives.

Solution

Instead, why not allow or indeed require wallets to opt-in to NFT mint/burning aspect of 404's? This could be done prior to any engagement with the 404 contract or after-the-fact, minting as many NFTs as their current balance permits.

If opting in is a one-way process — not able to be reversed — then all other functionality and tokenomics are retained for all users.

Efficiency

There is a gas cost in having the contract maintain this list of opt-ins, which will in most cases be considerably larger in size than the existing whitelist scheme. (You could have both, I suppose, with opt-ins overriding the whitelist for security/trust reasons.) The extra SSTOR cost might be optimized by packing groups of 256 accounts into single bit binary boolean's — 256 opt-ins stored in a single storage slot — based on your now deterministic NFT token IDs — though that implies that a holder must have at least NFT to be opted in. Just a thought.

Conclusion

You're welcome. :p

gruv0r

No `Transfer` event emitted in new ERC404 implementation / unresolved ERC20 <> ERC721 spec collision

The Transfer event was emitted in the legacy version ==> https://github.com/Pandora-Labs-Org/erc404-legacy/blob/master/src/ERC404.sol#L80-L84

But it is not emitted in the latest version

This event is an ERC-20 and ERC-721 standard event so it is likely to cause issues with platforms like OpenSea and Etherscan that expect this event to fire on transfer

You can see this issue manifesting on Etherscan here ==> https://etherscan.io/tx/0xb7e3fbc0f77cc31fe0536e2456dea7cc6ee0c5cf2db46276b6e98457ac7d5311
image


Closely related to this is that there is a collision between ERC20 and ERC721 in the Transfer event because they both are supposed to emit it

The solution that Pandora seems to have come to in its deployed version is that only transfers that trigger an ERC721 transfer emit the Transfer event e.g. ==> https://etherscan.io/tx/0xc1c0bdd6169338d02b8ab393620f5b62bc2dc0419bb53e81b75c41d6225dc5ad

In other words, Transfer events are only emitted for ERC-721

This means for example for this holder, etherscan can "see" the ERC-721 transfers: https://etherscan.io/address/0x8febbf7c0b133f746f9303deff1191334d1a0ae5#nfttransfers

But it can't "see" the ERC-20 transfers: https://etherscan.io/address/0x8febbf7c0b133f746f9303deff1191334d1a0ae5#tokentxns

transferFrom is not working (for NFT transfer)

Using transferFrom for the NFT transfer is reverting due to the shl modification.

await contract.write.transferFrom([walletA.account.address, walletB.account.address, 12n], { account: walletA.account.address })

The shl fix made, is not working.

function _getOwnedIndex(
    uint256 id_
  ) internal view virtual returns (uint256 ownedIndex_) {
    uint256 data = _ownedData[id_];

    assembly {
      ownedIndex_ := shl(data, 160)
    }
  }

  function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
    uint256 data = _ownedData[id_];

    if (index_ > _BITMASK_OWNED_INDEX >> 160) {
      revert OwnedIndexOverflow();
    }

    assembly {
      data := add(
        and(data, _BITMASK_ADDRESS),
        and(shl(index_, 160), _BITMASK_OWNED_INDEX)
      )
    }

    _ownedData[id_] = data;
  }

With my example i got (before the shl fix):

Before transfer:
WalletA [
11n, 12n, 13n, 14n,
15n, 16n, 17n, 18n,
19n, 20n
]
WalletB []

After transfer:
WalletA [
20n, 12n, 13n,
14n, 15n, 16n,
17n, 18n, 19n
] 
WalletB[ 12n ] 

As we can see, there is a duplicate 12n and the 11n is removed

Making ERC404 `_storedERC721Ids` internal

What:
By making _storedERC721Ids in ERC404 internal instead of private, it allows access of the dequeue by 404 extensions without having to edit the core ERC404.sol, and by developers without having to load the state manually. Currently, ERC404 only exposes the length of the dequeue in erc721TokensBankedInQueue().

Why + Example:
An example of an extension that would benefit from this change is a ERC404Viewable.sol. This would expose the queue on the contract api level, lowering the bar for developers who want to access that state. This would make arbitrage of specific 721 ids from the dequeue more accessible for defi power users / devs in general to participate

centralize validValueOrId check

          just an idea, not needed for this version: this logic could be a function since we reuse it everywhere, it's critical, and when we want to support burning it will need to be changed in many places.

Originally posted by @caldereth in #17 (comment)

Consider ERC1155?

Has anyone considered this would be better with ERC1155, as it has batchTransfers, different function signatures it would be way better for blending ERC20, afterall, ERC1155 is designed for multiple tokens. I wrote my own version of "ERC404" using ERC1155, feel free to check it out or use it: https://github.com/TechnicallyWeb3/TW3404

zsh: parse error near `}'

I am a new learner here. I am trying to do a Quickstart in your latest tutorial and everything works fine installing forge etc. when I get to the step that runs the example code I get an error at the end zsh: parse error near `}':

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC404} from "erc404/ERC404.sol";

contract ExampleERC404 is Ownable, ERC404 {
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_,
uint256 maxTotalSupplyERC721_,
address initialOwner_
) ERC404(name_, symbol_, decimals_) Ownable(initialOwner_) {
setERC721TransferExempt(initialOwner, true);
mintERC20(initialOwner, maxTotalSupplyERC721_ * units, false);
}

function tokenURI(uint256 id_) public pure override returns (string memory) {
return string.concat("https://example.com/token/", Strings.toString(id_));
}

function setERC721TransferExempt(address account_, bool value_) external onlyOwner {
setERC721TransferExempt(account, value_);
}
}

zsh: parse error near `}'

How do I get around this problem? I have tried reinstalling zsh with homebrew. still the same. sorry if this is basic stuff but I searched the internet everywhere and can't find a straight answer.

What happens if allowance goes negative?

From the transferFrom method, the line 235

if (allowed != type(uint256).max) {
        allowance[from_][msg.sender] = allowed - value;
      }

Should there be a check to ensure value < allowed, and revert if so?

An error in erc20TransferFrom() function

If the 'from_' is the msg.sender, it don't need to check the allowance of the 'from_'. Otherwise it will throw a revert error.

function erc20TransferFrom(
    address from_,
    address to_,
    uint256 value_
  ) public virtual returns (bool) {
    // Prevent minting tokens from 0x0.
    if (from_ == address(0)) {
      revert InvalidSender();
    }

    // Prevent burning tokens to 0x0.
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    uint256 allowed = allowance[from_][msg.sender];

    // Check that the operator has sufficient allowance.
    if (allowed != type(uint256).max) {
      allowance[from_][msg.sender] = allowed - value_;
    }

    // Transferring ERC-20s directly requires the _transferERC20WithERC721 function.
    // Handles ERC-721 exemptions internally.
    return _transferERC20WithERC721(from_, to_, value_);
  }

I have modified the following code

  function erc20TransferFrom(
    address from_,
    address to_,
    uint256 value_
  ) public virtual returns (bool) {
    // Prevent minting tokens from 0x0.
    if (from_ == address(0)) {
      revert InvalidSender();
    }

    // Prevent burning tokens to 0x0.
    if (to_ == address(0)) {
      revert InvalidRecipient();
    }

    if (from_ != msg.sender) {
      uint256 allowed = allowance[from_][msg.sender];

      // Check that the operator has sufficient allowance.
      if (allowed != type(uint256).max) {
        allowance[from_][msg.sender] = allowed - value_;
      }
    }

    // Transferring ERC-20s directly requires the _transferERC20WithERC721 function.
    // Handles ERC-721 exemptions internally.
    return _transferERC20WithERC721(from_, to_, value_);
  }

enhance {_setOwnedIndex} to reduce the gas consumption

Issue

There is a useless assembly operation in the data packing of internal function {_setOwnedIndex}:

function _setOwnedIndex(uint256 id_, uint256 index_) internal virtual {
   ...

    assembly {
      data := add(
        and(data, _BITMASK_ADDRESS),
        // shl(160, index_) makes sure all 0 in the low 160 bits so that `and(xxx, _BITMASK_OWNED_INDEX)` is needless
        and(shl(160, index_), _BITMASK_OWNED_INDEX)
      )
    }

    _ownedData[id_] = data;
  }

I have run the test with my modification and it actually reduces the gas:
·-------------------------------------------------|----------------------------|-------------|-----------------------------·
| Solc version: 0.8.20 · Optimizer enabled: false · Runs: 200 · Block limit: 30000000 gas │
··················································|····························|·············|······························
| Methods │
··················|·······························|·············|··············|·············|···············|··············
| Contract · Method · Min · Max · Avg · # calls · usd (avg) │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setApprovalForAll · 24773 · 46685 · 40424 · 7 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setERC721TransferExempt · 29287 · 204448 · 94214 · 5 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · setSelfERC721TransferExempt · 27026 · 46333 · 36680 · 2 · - │
··················|·······························|·············|··············|·············|···············|··············
| ERC404Example · transfer · 32509 · 5034556 · 385571 · 21 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · approve · 27039 · 51490 · 46518 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · mintERC20 · 43161 · 5058633 · 1717416 · 17 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · permit · 76946 · 77318 · 77132 · 4 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · safeTransferFrom · 130010 · 132655 · 131773 · 3 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · setApprovalForAll · 46584 · 46596 · 46590 · 2 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · setERC721TransferExempt · 49209 · 3205288 · 1451911 · 9 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · transfer · 59231 · 261414 · 120135 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| MinimalERC404 · transferFrom · 58908 · 129681 · 103574 · 13 · - │
··················|·······························|·············|··············|·············|···············|··············
| Deployments · · % of limit · │
··················································|·············|··············|·············|···············|··············
| ERC404Example · - · - · 4135940 · 13.8 % · - │
··················································|·············|··············|·············|···············|··············
| ERC404ExampleUniswapV2 · - · - · 4205985 · 14 % · - │
··················································|·············|··············|·············|···············|··············
| ERC404ExampleUniswapV3 · - · - · 4334783 · 14.4 % · - │
··················································|·············|··············|·············|···············|··············
| MinimalERC404 · - · - · 4038373 · 13.5 % · - │
··················································|·············|··············|·············|···············|··············
| MockInvalidERC721Receiver · - · - · 198533 · 0.7 % · - │
··················································|·············|··············|·············|···············|··············
| MockValidERC721Receiver · - · - · 193569 · 0.6 % · - │
·-------------------------------------------------|-------------|--------------|-------------|---------------|-------------·

transferFrom potential vulnerability?

Seems like a bit of an oversight, or perhaps I’m not seeing the protection mechanisms. I’m noticing the transferFrom function uses “amountOrId” as an input. Could NFTs theoretically be stolen from liquidity providers? A DEX using the approve and transferFrom function to perform swaps means if a user buys a low enough amount of token they could theoretically trigger an ERC721 transfer instead of an ERC20 transfer. In fact anyone using the approve method for any ERC20 amount is susceptible to this type of attack.

For example if I buy 1000 wei (0.000000000000001 ERC20) I could theoretically steal NFT #1000 if it’s being provided by a liquidity provider on a DEX using approve and transferFrom. Not sure which, if any, DEXes use this method for swaps. It’s just the matter of finding out who provides liquidity, which token IDs they own and buying exactly those amounts of ERC20 wei. I did notice a whitelist but I assume that will only work if the white listed exchange or contract holds the token instead of facilitating the swap.

Thoughts?

This is purely a technical question and in no way am I encouraging to attempt this on live projects. I’ll be writing some hardhat tests to share later testing my assumptions on a VM.

DRAFT: Fail to retrieve from bank when transferring fractional to self

Traces:

Traces:
  [3813425] Erc404MinimalTest::test_erc721Storage_retrieveFromBank(76, 0xd38171555580273cEa88FA0cD3622F9bb94a236B, 0xd38171555580273cEa88FA0cD3622F9bb94a236B) 
    ├─ [0] VM::assume(true) [staticcall]
    │   └─ ← ()
    ├─ [0] VM::assume(true) [staticcall]
    │   └─ ← ()
    ├─ [0] VM::assume(true) [staticcall]
    │   └─ ← ()
    ├─ [2587] MinimalERC404::whitelist(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
    │   └─ ← false
    ├─ [587] MinimalERC404::whitelist(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
    │   └─ ← false
    ├─ [0] VM::assume(true) [staticcall]
    │   └─ ← ()
    ├─ [0] VM::prank(0x0000000000000000000000000000000000000001) 
    │   └─ ← ()
    ├─ [3771449] MinimalERC404::mintERC20(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 76000000000000000000 [7.6e19], true) 
    │   ├─ emit ERC20Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 76000000000000000000 [7.6e19])
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 1)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 2)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 3)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 4)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 5)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 6)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 7)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 8)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 9)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 10)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 11)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 12)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 13)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 14)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 15)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 16)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 17)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 18)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 19)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 20)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 21)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 22)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 23)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 24)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 25)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 26)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 27)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 28)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 29)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 30)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 31)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 32)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 33)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 34)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 35)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 36)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 37)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 38)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 39)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 40)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 41)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 42)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 43)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 44)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 45)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 46)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 47)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 48)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 49)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 50)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 51)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 52)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 53)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 54)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 55)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 56)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 57)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 58)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 59)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 60)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 61)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 62)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 63)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 64)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 65)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 66)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 67)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 68)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 69)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 70)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 71)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 72)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 73)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 74)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 75)
    │   ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 76)
    │   └─ ← ()
    ├─ [0] VM::prank(0xd38171555580273cEa88FA0cD3622F9bb94a236B) 
    │   └─ ← ()
    ├─ [42702] MinimalERC404::transfer(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 100000000000000000 [1e17]) 
    │   ├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
    │   ├─ emit ERC721Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0x0000000000000000000000000000000000000000, id: 76)
    │   └─ ← true
    ├─ [2608] MinimalERC404::balanceOf(MinimalERC404: [0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f]) [staticcall]
    │   └─ ← 0
    ├─ [463] MinimalERC404::erc721TokensBankedInQueue() [staticcall]
    │   └─ ← 1
    ├─ [0] VM::expectEmit(false, false, false, false) 
    │   └─ ← ()
    ├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
    ├─ [0] VM::expectEmit(false, false, false, false) 
    │   └─ ← ()
    ├─ emit ERC721Transfer(from: 0x0000000000000000000000000000000000000000, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, id: 76)
    ├─ [0] VM::prank(0xd38171555580273cEa88FA0cD3622F9bb94a236B) 
    │   └─ ← ()
    ├─ [26782] MinimalERC404::transfer(0xd38171555580273cEa88FA0cD3622F9bb94a236B, 100000000000000000 [1e17]) 
    │   ├─ emit ERC20Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, amount: 100000000000000000 [1e17])
    │   ├─ emit ERC721Transfer(from: 0xd38171555580273cEa88FA0cD3622F9bb94a236B, to: 0x0000000000000000000000000000000000000000, id: 75)
    │   └─ ← true
    ├─ [606] MinimalERC404::erc20BalanceOf(0xd38171555580273cEa88FA0cD3622F9bb94a236B) [staticcall]
    │   └─ ← 76000000000000000000 [7.6e19]
    ├─ [715] MinimalERC404::ownerOf(76) [staticcall]
    │   └─ ← "NotFound()"
    └─ ← "NotFound()"
    ```

Upgradable Proxy for ERC404

Hi, ERC404 Folks,
I think it is necessary to make new Upgradable Proxy for ERC404, and time is up because it's enough to be famous in ever-evolving developing filed.
Beginning from basic Upgradable Proxy(TUDP) or forking UDP/Diamond, whatever we approach, it's time to make suitable proxy contract for ERC404 to make more usable.

Any plan to submit this 404 standard to the EIPs repo?

I'm curious whether Pandora team plans to submit this hybrid ERC20+ERC721 standard to the EIPs repository. Currently, there's some confusion about the final function interfaces and events, as well as the rationale behind them (some of which have changed from the legacy implementation). Without an official standard, it becomes particularly challenging for other projects to, for instance, implement their own 404 smart contracts with different performance tradeoffs while ensuring consistency with the specification. Also difficult for wallets, indexers and exchanges to know what data to read.

In the current codebase, the event Transfer(...) and event Approval(...) have been completely removed. Do we expect Etherscan, wallets, and other indexers to track the new ERC20Transfer, ERC20Approval, ERC721Transfer, etc., events? Otherwise I don't think token balances won't show on Web3 wallets / and contract won't be recognized as token on Etherscan.

I'm willing to assist with the draft if there are plans to proceed. Any information would be greatly appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.