Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use uint packing instead of structs #272

Merged
merged 12 commits into from
May 17, 2022

Conversation

Vectorized
Copy link
Collaborator

@Vectorized Vectorized commented May 9, 2022

This PR is made in preparation for #267.

This is a breaking change, as the internal _ownerships mapping is renamed to _packedOwnerships.

Using uints allow us to write most of the packing logic in Solidity instead of assembly. This allows us to keep the code compatible with the diamonds transpiler we are planning to use in the near future. Also, it is easier to read, and surprisingly more performant.

This PR is inspired by and includes #270. I’ve tried the idea with structs: it added quite a bit of overhead because of the many values that are often needlessly unpacked by the compiler. Manual unpacking allows us to achieve a much lower overhead.

Additional tests have been added to ensure that the startTimestamps are packed / unpacked properly.

Before:

·---------------------------------------------------------------|---------------------------|-------------|
|                     Solc version: 0.8.11                      ·  Optimizer enabled: true  ·  Runs: 800  ·
································································|···························|·············|
|  Methods                                                                                                 
··········································|·····················|·············|·············|·············|
|  Contract                               ·  Method             ·  Min        ·  Max        ·  Avg        ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  approve            ·      30777  ·      50917  ·      40847  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  burn               ·      46142  ·     112535  ·      92768  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  safeMint           ·          -  ·          -  ·     111106  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  setApprovalForAll  ·      26277  ·      46189  ·      36233  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  transferFrom       ·      84577  ·      90863  ·      87720  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  mintOne            ·      56358  ·      90558  ·      57042  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  mintTen            ·      73985  ·     108185  ·      75629  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  safeMintOne        ·      59094  ·      93294  ·      59778  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  safeMintTen        ·      76699  ·     110899  ·      77383  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  transferFrom       ·      47175  ·      86955  ·      49164  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  approve            ·          -  ·          -  ·      50849  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  burn               ·          -  ·          -  ·      63346  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  mint               ·      90667  ·      98499  ·      96413  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  safeMint           ·      78306  ·     123064  ·      87877  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  safeTransferFrom   ·      91614  ·      91626  ·      91623  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  setApprovalForAll  ·      46195  ·      46219  ·      46216  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  setAux             ·      27144  ·      44328  ·      32872  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  transferFrom       ·      84575  ·      84599  ·      84594  ·
··········································|·····················|·············|·············|·············|
|  Deployments                                                  ·                                         ·
································································|·············|·············|·············|
|  ERC721ABurnableMock                                          ·          -  ·          -  ·    1300089  ·
································································|·············|·············|·············|
|  ERC721AGasReporterMock                                       ·          -  ·          -  ·    1213358  ·
································································|·············|·············|·············|
|  ERC721AMock                                                  ·          -  ·          -  ·    1464231  ·
·---------------------------------------------------------------|-------------|-------------|-------------|

After:

·---------------------------------------------------------------|---------------------------|-------------|
|                     Solc version: 0.8.11                      ·  Optimizer enabled: true  ·  Runs: 800  ·
································································|···························|·············|
|  Methods                                                                                                 
··········································|·····················|·············|·············|·············|
|  Contract                               ·  Method             ·  Min        ·  Max        ·  Avg        ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  approve            ·      30453  ·      50593  ·      40523  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  burn               ·      43393  ·     111032  ·      91192  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  safeMint           ·          -  ·          -  ·     110959  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  setApprovalForAll  ·      26277  ·      46189  ·      36233  ·
··········································|·····················|·············|·············|·············|
|  ERC721ABurnableMock                    ·  transferFrom       ·      83946  ·      89685  ·      86816  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  mintOne            ·      56217  ·      90417  ·      56901  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  mintTen            ·      73844  ·     108044  ·      75488  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  safeMintOne        ·      58947  ·      93147  ·      59631  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  safeMintTen        ·      76552  ·     110752  ·      77236  ·
··········································|·····················|·············|·············|·············|
|  ERC721AGasReporterMock                 ·  transferFrom       ·      44489  ·      86180  ·      46574  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  approve            ·          -  ·          -  ·      50547  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  burn               ·          -  ·          -  ·      60597  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  mint               ·      90526  ·      98358  ·      96272  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  safeMint           ·      78159  ·     122917  ·      87730  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  safeTransferFrom   ·      91008  ·      91020  ·      91017  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  setApprovalForAll  ·      46195  ·      46219  ·      46216  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  setAux             ·      27145  ·      44329  ·      32873  ·
··········································|·····················|·············|·············|·············|
|  ERC721AMock                            ·  transferFrom       ·      83966  ·      83990  ·      83985  ·
··········································|·····················|·············|·············|·············|
|  Deployments                                                  ·                                         ·
································································|·············|·············|·············|
|  ERC721ABurnableMock                                          ·          -  ·          -  ·    1213610  ·
································································|·············|·············|·············|
|  ERC721AGasReporterMock                                       ·          -  ·          -  ·    1116449  ·
································································|·············|·············|·············|
|  ERC721AMock                                                  ·          -  ·          -  ·    1329475  ·
·---------------------------------------------------------------|-------------|-------------|-------------|

@Vectorized Vectorized requested a review from cygaar May 9, 2022 02:08
@Vectorized Vectorized mentioned this pull request May 9, 2022
@cygaar cygaar changed the title Convert structs to uint256s Use uint packing instead of structs May 9, 2022
This was linked to issues May 9, 2022
@Vectorized Vectorized force-pushed the feature/bitwise branch 2 times, most recently from 3597937 to 67979b0 Compare May 9, 2022 08:48
@0xPhaze
Copy link

0xPhaze commented May 9, 2022

~ just an idea:
Accessing and writing to the packed ownership could be handled by a library to make things more readable.
I had done something like that here in this repo: https://github.com/0xPhaze/ERC721M/blob/master/src/ERC721MMC.sol
I even explored (but never implemented, because it was a lot of wrap/unwrap) using custom types for a packed uint256 to further guide access to its packed storage. This could be interesting for ERC721A.

@Vectorized
Copy link
Collaborator Author

I think it's still okay to directly write the bitwise ops inline to have a little more control.

contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
contracts/ERC721A.sol Outdated Show resolved Hide resolved
test/ERC721A.test.js Outdated Show resolved Hide resolved
test/GasUsage.test.js Outdated Show resolved Hide resolved
@cygaar
Copy link
Collaborator

cygaar commented May 15, 2022

Let's do one more poll to see how people feel about this

@Vectorized Vectorized mentioned this pull request May 16, 2022
@Vectorized Vectorized merged commit 3783cc4 into chiru-labs:main May 17, 2022
@Vectorized Vectorized deleted the feature/bitwise branch June 7, 2022 21:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Incorrect token burner being tracked Golfing ERC721A
3 participants