GithubHelp home page GithubHelp logo

dixel-contract's Introduction

Dixel

A single NFT canvas where users overwrite the previous edition with price-compounded pixels.

  1. There is an universal art canvas with 16x16 pixels that anyone can overwrite
  2. Whenever a user overwrites a pixel, the price of the pixel increases by 0.1% (Initial pixel price: 0.001 DIXEL)
  3. A new NFT edition with the current canvas state will be minted to the updater (image data is encoded as SVG, 100% on-chain)
  4. Total cost that user paid to overwrite pixels goes to:
    • 10% -> all contributors proportional to their contribution count (total pixel count a user has updated so far)
    • 90% -> reserve for refund when the NFT gets burned
  5. If a user burn a NFT they own, reserve amount (DIXEL tokens) gets refunded to the user (90% of total minting cost)

Run Tests

npx hardhat test

Contracts

BSC Production

BSC Testnet

  • Test token: 0x62c01AF8F8Ab997Acec06C3a71DC18594726ba24
  • TestTokenFaucet: 0x0d5B2E37FB21A784FE26fD8d89Ea3Ce8F8BDc54d
  • DixelClub: 0x3b7bd4FCcc630f025584f1F7e4874adB1f324AcE
  • DixelArt NFT: 0x46cc5a12A3F58A837475C9BFe52C0C02274C0C0c
  • DixelAirdrop: 0x7Fcb48b7AF75E47af89B328f99B681aCa93A7d10
  • DixelTip: 0x37F6692763d388902f7413Fd560A15491927Fe0D

Deploy

npx hardhat compile

HARDHAT_NETWORK=bscmain node scripts/deploy.js

# Verify source code on Etherscan
npx hardhat verify --network bscmain {contract address} "parameter 1" "parameter 2"

Gas Consumption

·----------------------------------------------------|---------------------------|--------------|-----------------------------·
|                Solc version: 0.8.10                ·  Optimizer enabled: true  ·  Runs: 1500  ·  Block limit: 60000000 gas  │
·····················································|···························|··············|······························
|  Methods                                           ·                1 gwei/gas                ·       2607.30 usd/eth       │
····························|························|·············|·············|··············|···············|··············
|  Contract                 ·  Method                ·  Min        ·  Max        ·  Avg         ·  # calls      ·  usd (avg)  │
····························|························|·············|·············|··············|···············|··············
|  DixelAirdrop             ·  claim                 ·          -  ·          -  ·       69988  ·            8  ·       0.18  │
····························|························|·············|·············|··············|···············|··············
|  DixelAirdrop             ·  closeAirdrop          ·          -  ·          -  ·       78915  ·            3  ·       0.21  │
····························|························|·············|·············|··············|···············|··············
|  DixelAirdrop             ·  whitelist             ·          -  ·          -  ·       95119  ·           22  ·       0.25  │
····························|························|·············|·············|··············|···············|··············
|  DixelArt                 ·  approve               ·          -  ·          -  ·       48721  ·            5  ·       0.13  │
····························|························|·············|·············|··············|···············|··············
|  DixelArt                 ·  burn                  ·          -  ·          -  ·       68181  ·            7  ·       0.18  │
····························|························|·············|·············|··············|···············|··············
|  DixelArt                 ·  transferOwnership     ·      28630  ·      28642  ·       28641  ·          102  ·       0.07  │
····························|························|·············|·············|··············|···············|··············
|  DixelMock                ·  claimReward           ·      55953  ·      73053  ·       57268  ·           52  ·       0.15  │
····························|························|·············|·············|··············|···············|··············
|  DixelMock                ·  updatePixels          ·    1157496  ·    1292627  ·     1243279  ·          214  ·       3.24  │
····························|························|·············|·············|··············|···············|··············
|  DixelMock                ·  updatePixelsNoChecks  ·          -  ·          -  ·     3008326  ·            1  ·       7.84  │
····························|························|·············|·············|··············|···············|··············
|  DixelMock                ·  updatePixelsOriginal  ·          -  ·          -  ·     3258586  ·            1  ·       8.50  │
····························|························|·············|·············|··············|···············|··············
|  DixelTip                 ·  burnAndRefundTips     ·          -  ·          -  ·       91497  ·            4  ·       0.24  │
····························|························|·············|·············|··············|···············|··············
|  DixelTip                 ·  tip                   ·          -  ·          -  ·       98370  ·            9  ·       0.26  │
····························|························|·············|·············|··············|···············|··············
|  ERC20PresetMinterPauser  ·  approve               ·      46608  ·      46620  ·       46619  ·          203  ·       0.12  │
····························|························|·············|·············|··············|···············|··············
|  ERC20PresetMinterPauser  ·  mint                  ·      55830  ·      72954  ·       62554  ·          316  ·       0.16  │
····························|························|·············|·············|··············|···············|··············
|  Deployments                                       ·                                          ·  % of limit   ·             │
·····················································|·············|·············|··············|···············|··············
|  ColorUtilsMock                                    ·          -  ·          -  ·      298677  ·        0.5 %  ·       0.78  │
·····················································|·············|·············|··············|···············|··············
|  DixelAirdrop                                      ·     794659  ·     794671  ·      794670  ·        1.3 %  ·       2.07  │
·····················································|·············|·············|··············|···············|··············
|  DixelArt                                          ·    2927148  ·    2927172  ·     2927171  ·        4.9 %  ·       7.63  │
·····················································|·············|·············|··············|···············|··············
|  DixelMock                                         ·    8076080  ·    8096016  ·     8076295  ·       13.5 %  ·      21.06  │
·····················································|·············|·············|··············|···············|··············
|  DixelTip                                          ·     823384  ·     823396  ·      823395  ·        1.4 %  ·       2.15  │
·····················································|·············|·············|··············|···············|··············
|  ERC20PresetMinterPauser                           ·          -  ·          -  ·     1951544  ·        3.3 %  ·       5.09  │
·----------------------------------------------------|-------------|-------------|--------------|---------------|-------------·

dixel-contract's People

Contributors

assafom avatar cryptocorgie avatar dependabot[bot] avatar inmarelibero avatar jinmo avatar junorouse avatar nipol avatar sydneyitguy avatar

Stargazers

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

Watchers

 avatar  avatar  avatar

dixel-contract's Issues

Consider removing usage of _msgSender()

OpenZeppelin's Context.sol and _msgSender() are needed only if you plan to use meta-transactions, in which you'll pay for the user's gas fees. (reference)

Since most projects don't do that, I'm guessing that you won't do it either.

If that is so, you can consider removing Context.sol and replace all _msgSender()s with msg.sender. This will save a tiny bit of gas and perhaps be more clean.

Reward distribution for community audits 💸

Overall, we had 6 devs who participated in our community driven audit event.

@Nipol @junomonster @Jinmo @cryptocorgie @inmarelibero @assafom

I really appreciate everyone who participated in reviewing the code, and we successfully improved our contract in many ways:

  • 1 critical issue on reward calculation
  • 2 medium level issues on parameter edge cases
  • 2 minor issues on edge cases
  • optimizations on gas consumption

We discussed about the fair reward distribution for the contributions considering the importance of the contribution and amount of work put into the reviewing process.

I hope you guys are okay with this distribution table below:
image

If you have any concerns or opinion on the distribution, please comment down here so we can discuss together.
I will distribute the reward (total $10,000 USDT) to the wallet address by the end of tomorrow if there are no issues brought up.

We were very satisfied with the result of this event, and we may have other bounty programs later on.
Let's keep in touch and hope to see you guys again soon! ❤️

playerWallets can contain duplicate values

address[] public playerWallets; in https://github.com/Steemhunt/dixel-contract/blob/main/contracts/Dixel.sol#L69 can accept multiple times the same wallet, because of use of playerWallets.push

if so, require(playerWallets.length < 0xffffffff, "MAX_USER_REACHED"); in https://github.com/Steemhunt/dixel-contract/blob/main/contracts/Dixel.sol#L95 behaves incorrectly, because playerWallets.length would reach the limit also if it would contain 0xffffffff times the same address

why don't use https://docs.openzeppelin.com/contracts/3.x/api/utils#EnumerableMap for address[] public playerWallets?

Prevent updating pixel with the same color

It causes a minting of a new edition of exactly the same pixels with the previous edition

  • Add checks on updatePixels if it has the same color data with the previous pixel
  • Check gas consumption increase by this check

gas saving

not really an issue, opening just for discussion because I made a review on a closed PR and I wasn't sure it got viewed: #2 (review)

Reward calculation error - lost rewards

Consider the following scenario:

  • Alice updates 2 pixels and sends reward to Dixel: rewrad amount X
  • Bob updates 2 pixels and sends reward to Dixel: reward amount Y
  • Alice updates 2 pixels and sends reward to Dixel: reward amount Z

Now let's say Alice and Bob claim their rewards.
Per my understanding, amount X will be lost in the contract (per design), but all of amounts Y+Z should get sent to Alice and Bob, as they are the only ones who minted so far.

However, when testing this scenario - after Alice and Bob claim their rewards - I see that there are more tokens in Dixel than amount X. These are tokens that are unclaimable as Alice and Bob, the only players, have already claimed their rewards, and they should have gotten all the rewards.

So this leads me to think that there is a fundamental error in the reward calculation, unless I'm missing something.
Here is a test file that will simulate this scenario and print Dixel's baseToken balance, so you can see there are more rewards than should be there.

Tomorrow I will try looking at this further and understand what's the root cause.

Prevent duplicated pixel params

#3 ensures updating pixel parameters are sorted ([0][0], [0][1], [0][2], [0][3] ... [15][15]) so it can prevent updating the same pixel multiple times in one transaction.

Let's check how much gas fee is added by this check when a user update all 256 pixels, and decide whether we allow this by design or not.

  • Add test case updating all 256 pixels and compare the gas consumption between dup-checks and non dup-checks

If we're going to add duplication checking,

  • Front-end should sort pixel updating params

Running all tests not working any more

Looks like running npx hardhat test doesn't run all the tests anymore, but just one -

Contract: DixelArt
    generate NFT
      ✓ should revert tokenURI in JSON format generation if tokenId has not been minted yet

Dunno if I'm missing something. Running Dixel.test.js manually is working, but running DixelArt.test.js manually or just general hardhat test just runs that one test. So far I haven't found the cause for the problem.

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.