Git Product home page Git Product logo

dn404's Introduction

DN404 πŸ₯œ

NPM CI

DN404 is an implementation of a co-joined ERC20 and ERC721 pair.

To learn more about these dual nature token pairs, you can read the full ERC-7631 spec.

  • Full compliance with the ERC20 and ERC721 specifications.
  • Transfers on one side will be reflected on the other side.
  • Pretty optimized.

Installation

To install with Foundry:

forge install vectorized/dn404

To install with Hardhat:

npm install dn404

Contracts

The Solidity smart contracts are located in the src directory.

src
β”œβ”€ DN404 β€” "ERC20 contract for DN404"
β”œβ”€ DN404Mirror β€” "ERC721 contract for DN404"
β”œβ”€ DN420 β€” "Single-contract ERC20 ERC1155 chimera"
└─ example
   β”œβ”€ SimpleDN404 β€” "Simple DN404 example as ERC20"
   └─ NFTMintDN404 β€” "Simple DN404 example as ERC721"

Contributing

Feel free to make a pull request.

Guidelines same as Solady's.

Safety

This is experimental software and is provided on an "as is" and "as available" basis.

We do not give any warranties and will not be liable for any loss incurred through any use of this codebase.

While DN404 has been heavily tested, there may be parts that exhibit unexpected emergent behavior when used with other code, or break in future Solidity versions.

Please always include your own thorough tests when using DN404 to make sure it works correctly with your code.

Upgradability

Most contracts in DN404 are compatible with both upgradeable and non-upgradeable (i.e. regular) contracts.

Please call any required internal initialization methods accordingly.

Acknowledgments

This repository is inspired by various sources:

dn404's People

Contributors

vectorized avatar cygaar avatar 0xth0mas avatar quitcrypto avatar amadimichael avatar pop-punk avatar guardianaudits avatar hexzerodev avatar eltociear avatar whatl3y avatar rookmate avatar sivarampg avatar hooki avatar

Stargazers

Patrick avatar Lyn2024 avatar  avatar  avatar  avatar Vladyslav Kotsiuba avatar Fabien Allanic avatar Xian avatar Yufeng Hu avatar  avatar Jonas Sebera avatar  avatar Nick Ochiel avatar Pub avatar juancito avatar Lee Won Jun avatar Nuke πŸŒ„ avatar guzus avatar yuk6ra avatar  avatar Ceejay X. avatar Kaede avatar ZKillua avatar  avatar ndx.eth avatar AlwaysDumpling avatar Frank avatar Zach avatar  avatar quizford avatar JT-ITSTATION avatar Hammad Ahmed Ghazi avatar  avatar ttang avatar  avatar Igor Walter avatar Aliver avatar Italo A. G. avatar David Leng avatar CryptoLisboa avatar  avatar Bertrand Juglas avatar afrideva avatar Vatunyoo Suwannapisit avatar Yong Kang Chia avatar Andy avatar Julie1982 avatar Francis Kim avatar 0xCLARITY avatar Zero Ekkusu avatar Fly avatar Balaj Marius avatar Sennett Lau avatar kuwabatake avatar A5 Pickle avatar Daniel Esteban BeltrΓ‘n Varas avatar Junghoon Ban avatar Andrew avatar webstar avatar Gabriel Rosa avatar sawyer0x110 avatar  avatar Christopher Powroznik avatar Lemuel Okoli avatar Başar avatar Peita Lin avatar tuotuotuoyu avatar  avatar Paco avatar  avatar Serhan avatar web3genie avatar Web3 Intern avatar Jade avatar qhsailing.eth avatar MrPreet avatar Michael Demarais avatar Arseniy Ivanov avatar  avatar  avatar Alvatar avatar David Dacruz avatar  avatar Dexplorer avatar  avatar  avatar Hayatti avatar LyghtCode avatar  avatar Anne Thorpe avatar  avatar  avatar  avatar crush0x avatar geoffhorwitz.eth  avatar Pierre Cashon avatar prady avatar nftchinahk avatar B avatar  avatar

Watchers

Michael Demarais avatar  avatar Pete avatar 0xCLARITY avatar  avatar Eric Huang avatar  avatar William Struve avatar R avatar myst4 avatar 0xdeva avatar gval avatar  avatar  avatar

dn404's Issues

Example Subgraph

Would be great if we have one, since DN404 emits two different type of Transfer events

I've completely rebuilt ERC404 to fix all issues(?)

I decided to take a look at ERC404 and thought I could do it better. I completely rewrote ERC404 to be completely compliant with ERC1155 and ERC20 standards. I chose to mix these two instead of ERC721/ERC20 for several reasons:

  1. ERC1155 and ERC20 have no function conflicts whereas there are function signature conflicts when mixing ERC721 and ERC20
  2. ERC1155 is already a widely adopted standard meaning any platform which supports ERC1155 will also support ERC404 fully
  3. All I need to do now is create a few standardized error messages for the potential errors while synchronizing ERC1155 and ERC20
  4. No new functions are needed
  5. Batch transfers possible in ERC1155 meaning users can batch specific NFTs with their token transfers.
  6. No ownership required, ownership can be added into the implementation contract allowing for developers to choose how centralized/decentralized their projects are (no previous token standard has onlyOwner functions)
  7. Token ID space can be opened back up from 1 - uint256.max, only preventing tokenId 0 since id 0 is where we store the ERC20 data.

If anyone is interested in trying my rendition of ERC404 as an ERC1155 in action I have it [https://sepolia.etherscan.io/address/0xde39999e3e500e4b4842f6a87fa1e6a4c95d0010#code](deployed to sepolia) or on [https://github.com/TechnicallyWeb3/TW3404](my repo).

SafeDN404

Would be great if we have one, for example restrict NFT transfers for some contracts or only enforce NFT transfers by checking onERC721Received function call, etc.

Enhancing Liquidity for Existing NFTs: Implementing Lock-up Mechanism to Return DN404 Tokens with Matching Token IDs

Hello DN404 community and developers,

I'm reaching out to propose an enhancement aimed at increasing the liquidity of already minted NFTs through the DN404 protocol. Specifically, I believe there is a significant opportunity to extend the utility and accessibility of our existing NFT assets by implementing a mechanism that allows for the locking up of an NFT in exchange for DN404 tokens that carry the identical token ID as the original NFT.

The current scope of DN404, which primarily focuses on tokens minted after 2024, seems to target a rather narrow market and community. By broadening this approach to encompass existing NFTs, we could significantly expand our reach and impact within the broader NFT ecosystem.

However, as I attempt to draft a contract to realize this functionality, I've encountered challenges in devising a robust logic that accurately matches the token IDs of the locked-up ERC721 tokens with the DN404 tokens returned to the user. This issue is crucial for ensuring that users can reclaim their original NFTs upon returning the DN404 tokens, thereby maintaining a seamless and secure exchange process.

I'm opening this issue to solicit feedback, suggestions, and potential collaborations from the DN404 community and developers. Our goal is to refine this concept further and explore viable implementations that could bring this idea to fruition. I believe that by working together, we can overcome the technical hurdles and create a more fluid and dynamic NFT market that benefits all stakeholders involved.

I don't know if this idea has already been addressed or if it's impossible, but I'll raise an issue. Thanks.

Set log handlers as internal virtual instead of private

image

These helpers are very useful and would be great to be able to inherit and optionally override instead of having to rewrite in derived contracts. That contract size limit can sneak up on you.

Unless there's a reason these are set to private instead of internal virtual πŸ€”

DN404 identification

Currently, it would be possible to use staticcall for mirrorERC721 in order to detect if the contract is DN404 however this could also cause an issue with abi.decode since it doesn't catch decoding errors effectively

ethereum/solidity#10381

Therefore, the cleanest method would be supporting an arbitrary value for supportsInterface function

#68

NFT Metadata

I have only 5 images like Pandora. These images were distributed randomly in the original Pandora contract, but in this contract, I have not yet understood how to add my metadata file. I'm not exactly a developer so please excuse my ignorance. I don't know what kind of metadata file I should add to the setBaseURI section. Is it possible for you to add a sample metadata file, please? Also, if I do everything right, will the 5 images I have be distributed randomly?

EIP-2612 support

Since ERC20 of solady supports EIP-2612 I think it would make sense if DN404 also supports EIP-2612 as well.

Or, for the meantime I should be using the ERC20Permit extension from openzeppelin?

cc @Vectorized

Inquiry on Potential Gas or Security Issues for Large Supply Collections

Hello,
I'm considering creating a collection with a supply of 100,000 items and wanted to consult on whether this could potentially lead to any issues regarding gas fees or security within the collection. Specifically, I'm concerned about whether such a large supply might cause transactions to become excessively expensive or if there are any security vulnerabilities that could arise from managing a collection of this size. Additionally, is there a risk of the collection's transactions getting stuck or failing due to the high number of items?

Could you please advise on any best practices or considerations I should be aware of to avoid potential issues with gas costs, security, or transaction reliability for a collection of this magnitude?

Thank you for your assistance.

Get the NFT inventory of the wallet.

How can I retrieve the list of NFTs from a wallet similar to the OpenZeppelin's ERC721Enumerable utility with functions like tokenOfOwnerByIndex and tokenByIndex? I've tried using _getDN404Storage().owned[wallet].map[index] but couldn't make it work. @Vectorized

Inconsistency in NFT ID Handling

Hello guys,

I am currently testing the DN404 protocol, and I've encountered inconsistencies regarding NFT IDs.
Here is the scenario:

User A and User B are participating in the protocol.
User A purchases 4 NFTs with the IDs 1, 2, 3, and 4.
User B purchases 1 NFT with the ID 5.
User A sells the NFTs with the IDs 3 and 4 as tokens on a DEX. These two IDs are burned.
User A returns to purchase another entire unit token (1 NFT) on a DEX. The new NFT is minted with the ID 6, resulting in a loss of reference to the IDs 3 and 4.

This process raises concerns about consistency in NFT ID. Shouldn't there be a mechanism in place to maintain consistency and ensure that IDs are not lost?
If I'm not mistaken, The ERC404 protocol addresses this by adding a queue for burned IDs to be minted again later, ensuring consistency with the NFT IDs

Thanks for advance

✨When transferring ERC20 tokens, also consider transferring NFTs.

  1. Instead of burning and minting, transferring NFTs when transferring FT tokens
  2. ERC721 transfer event should be emitted
  3. Due to the issue of fragment quantity during the transfer, it may be necessary to additionally burn and mint an NFT
  4. For burning, add the free NFTs tracking(tokenId and total Amount) with a tmp address (ie. address(0))
  5. For minting, get NFTs from the tmp address

Thanks for your reading! Not sure it makes sense.

✨ Add support for custom base unit for DN404 tokens.

User story

As a developer creating new DN404 token with custom base unit, I want to have built in compatibility to set base unit (WAD) value for my project rather than using the default WAD=10**18 value.

Why

I was building a DN404 token and I realized that my requires base unit to be set as 10**24 instead of the default value.

Status Quo

Currently, I cannot override the value of _WAD as it is a constant value used in multiple functions

Potential Solution

Instead of using _WAD as a constant variable, create a view function that can be overwritten by developers.

Note: The choice for view function over pure is to allow community to create factory contracts for DN404 where the base unit can be set as a state variable which is then used inside _WAD internal function.

Batch Minting like 721A's

In our project, we need the batch mint function so that we can perform a certain amount of multiple mints in advance for Airdrops.
I prepared an ownerMint function before, but this causes NFTs to be minted with more than one transaction. I need a feature where I can mint multiple NFTs with a single transaction, like in ERC721A. I would be very happy if you could help me.
Since I am not very experienced in this field, I may make mistakes.

DoS Vector: Transfering relatively large amounts of DN404 always `oog`s

This shouldn't be a surprise, but if you create a DN404 with higher than 2.7k supply (in units, aka 18dec) and attempt to transfer ~2.7k tokens to another address, the gas consumption to mint the NFTs is over 30m reverting with oog on mainnet.

There's probably no workaround for this, but it's at least worth documenting somewhere.

Fairly easy to verify:

contract RevertTest is SoladyTest {
    SimpleDN404 dn;

    function setUp() public {
        dn = new SimpleDN404("DN404", "DN", 2700 * 10 ** 18, address(this));
    }

    function testTransfer() public { // gas: 30715623
        dn.transfer(address(1), 2_700 * 10 ** 18);
    }
}

✨ Zero Indexed optionality

Try to make it zero-cost abstraction.

If _useOneIndexed() is overriden to return false, the tokens will range from 0...(n-1) instead of 1...n.

pls guide

how to quick start? i need deploy sample404 and setdatauri with metadata?
i deploy
forge create --rpc-url
--constructor-args "arodnaP" "ARODNAP" "100000000000000000000000" "0x4EE84e71803773EcBF0f312d9FE9752097B2190A"
--private-key
--etherscan-api-key
--verify
src/example/SimpleDN404.sol:SimpleDN404
https://sepolia.etherscan.io/address/0x56a3F935Eb1485A25082CadAd7db5Cfb7693DE5d
pls check

and where whitelist func? when i create pool i need add wl pool address?

Problem for configuration setbaseuri tokenuri

Dear, when i put an ipfs on setbaseuri on remix, i have a problem that i don't understand.
MΓ©tadonnΓ©es json work fine but image don't appaer on opensea.
Please i need understand this problem.
Thanks

✨ Ownership detection for ERC721 side

For marketplaces like Opensea

  • Upon initialization handshake, the mirror will try to get the owner from the base contract. If there is an owner, the owner will be updated to that owner, and a OwnershipTransferred(address indexed oldOwner, address indexed newOwner) event will be emitted. Store the current owner in the deployer slot.

  • Upon logging a batch NFT mint / burn, try to get the owner from the base contract. If the owner is different from that of the deployer slot, a OwnershipTransferred(address indexed oldOwner, address indexed newOwner) will be emitted, and the owner in the deployer slot will be updated.

Not sure if this will work, someone help me try.

🐞 At example contract **NFTMintDN404** the minting checking allows to mint only once.

At mint function in NFTMintDN404:

the function allows to mint an "amount" of NFTs to the wallet of the caller, simulating a collection initial public sale.
it marks with "true" the wallets that minted whatever amount as long as the amount is "valid"
it increases the "numMinted" variable by one (1), instead of taking into consideration the "amount",
then, mints the "amount" to the wallet, offsetting the minted amount from the "recorded minted amount"

"numMinted" is used in isValidMint as part of the check for MAX_SUPPLY overflow. This issue will make that check not work properly.

Also, is confusing and not coherent. Because it allows to mint up to an amount and then, never again.
Lets say the maximum amount to mint per tx is 10,
If an user mints 2, and later changes his mind and tries to mint again, the function will revert, as the wallet has been already marked.

function mint(uint256 amount) public payable isValidMint(publicPrice, amount) {

        // if the user has already minted ANY number of tokens, this will revert, not allowing further mints

        if (minted[msg.sender]) revert InvalidMint();
            minted[msg.sender] = true;

        // numMinted only increases by one, not taking into account the **amount**
        // this will make isValidMint() not catch the minting overflow for collection

        unchecked {
            ++numMinted;
        }

        _mint(msg.sender, amount * _WAD);
    }

Additionally, maxMint should be called maxMintsPerTx or something like that. As it is a constructor param, it suggests that the name is referring to the max supply, or max mintable NFTs.

Transfer on/off

Is there a method we know of that locks token and NFT transfer during the Mint transaction? It would be nice if there was a way we could turn the transfer on and off.

πŸ“’ Audit fixes incoming

ETA: 10 May 2024.

Don't use _mintNext with an active burned pool for now (until the fixes are out).

Default settings are safe.

The best and safest way to deploy a DN404 is to mint out the entire supply in the initializer and distribute the ERC20s via a LP. Use a separate minting contract if needed.

If you have deployed a DN404, and it is searchable on codeslaw, and we haven't contacted you, you should be safe.

All PRs are closed until audit fixes are out.

Dosn't work with SafeTransferLib ?

One of my inner contracts is using safeTransferFrom from https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol , for DN404.sol part.
Based on my debugging that doesn't seem to trigger the associated 721 minting/transferring

Am I correct or missing here something?

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.