alephao / solidity-benchmarks Goto Github PK
View Code? Open in Web Editor NEWBenchmarks of popular contract implementations in solidity
Benchmarks of popular contract implementations in solidity
There is a tool I want to build on top of this. Writing this down before I forget.
For that tool I need a more structured data source, I think a simple JSON file would work well.
I want to be able to:
My initial thought of the JSON structure:
{
"ERC20": {
"v0.8.10": {
"deployment": {
"Open Zeppelin": "568857",
"Open Zeppelin Permit": "926489",
"Solmate": "656844",
"Maple": "672309"
},
"transfer": {
"Open Zeppelin": "20917",
"Open Zeppelin Permit": "20873",
"Solmate": "20590",
"Maple": "20657"
},
"approve": {
"Open Zeppelin": "32649",
"Open Zeppelin Permit": "32672",
"Solmate": "32547",
"Maple": "32598"
}
},
"v0.8.11": {
"deployment": {
"Open Zeppelin": "568857",
"Open Zeppelin Permit": "926489",
"Solmate": "656844",
"Maple": "672309"
},
"transfer": {
"Open Zeppelin": "20917",
"Open Zeppelin Permit": "20873",
"Solmate": "20590",
"Maple": "20657"
},
"approve": {
"Open Zeppelin": "32649",
"Open Zeppelin Permit": "32672",
"Solmate": "32547",
"Maple": "32598"
}
}
},
"ERC721": {
"v0.8.10": {
"deployment": {
"Open Zeppelin": "568857",
"Open Zeppelin Permit": "926489",
"Solmate": "656844",
"Maple": "672309"
},
"mint": {
"Open Zeppelin": "20917",
"Open Zeppelin Permit": "20873",
"Solmate": "20590",
"Maple": "20657"
}
},
"v0.8.11": {
"deployment": {
"Open Zeppelin": "1111",
"Solmate": "3333",
"ERC721A": "4444"
},
"mint": {
"1": {
"Open Zeppelin": "1111",
"Open Zeppelin Enumerable": "2222",
"Solmate": "3333",
"ERC721A": "4444",
"ERC721B": "5555",
"ERC721K": "6666"
},
"2": {
"Open Zeppelin": "1111",
"Open Zeppelin Enumerable": "2222",
"Solmate": "3333",
"ERC721A": "4444",
"ERC721B": "5555",
"ERC721K": "6666"
},
"3": {
"Open Zeppelin": "1111",
"Open Zeppelin Enumerable": "2222",
"Solmate": "3333",
"ERC721A": "4444",
"ERC721B": "5555",
"ERC721K": "6666"
}
}
}
}
}
Many of the contracts here have some extra functionality, for example if we look at the ERC20s, Solmate and Maple implements ERC-2612 permits, while the basic OZ's ERC20 doesn't.
Comparing Solmate vs Maple is fair, but OZ vs Solmate is not.
I think it might be a good idea to categorize them somehow, current idea is:
On READMES
Provide a table with features. Example for ERC20:
Contract/Features | ERC2612 | Another Feature |
---|---|---|
Solmate | ✅ | ✅ |
Maple | ✅ | ❌ |
OZ | ❌ | ✅ |
OZ with Permit | ✅ | ✅ |
On JSON
ERC20
Solmate
features: [ERC2612]
Maple
features: [ERC2612]
OZ:
features: []
ERC721
OZ:
features: []
A
features: [Enumerable]
OZEnumerable
features: [Enumerable]
(sorry for being lazy and not writing json by hand, but you got the idea)
Use-case: Some contracts may not support all tests, for instance ERC721B currently doesn't support burning. This may be the case for other contracts/tests in the future.
I've recently updated both OpenZeppelin contracts (#12), ERC721A (#13), and both now support a consecutive minting according to ERC2309. However, the current way of adding a new variation and test its implementation is not compatible with this test case.
The reason behind this is that when the ConsecutiveTransfer
event is emitted outside of the constructor, the contract is not ERC721 compatible anymore as stated in the ERC721A comments and also restricted on OpenZeppelin Contracts.
I think both ERC2309 implementations are worth reviewing and benchmarking. I can take care by myself and send a PR, however, I'd love some feedback before moving forward.
I tried following the README steps in order to add a new variant, this is an example of what I was thinking for an ERC721_OZConsecutive
:
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.4;
import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import {ERC721Consecutive} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Consecutive.sol";
contract ERC721_OZConsecutive is ERC721Consecutive {
uint256 currentSupply;
constructor() ERC721("Name", "Sy") {}
function mint(address to, uint96 amount) external payable {
uint256 startingIndex;
unchecked {
startingIndex = currentSupply + 1;
currentSupply += amount;
}
_mintConsecutive(to, amount);
}
...
}
However, it fails because the _mintConsecutive(to, amount)
is called outside the constructor, and I don't see an easy workaround.
Right now my best approach is to add an alternative test_deploy
with the consecutive minting for ERC2309-compliant tokens, but I wanted to open a discussion before sending the PR.
I'd love feedback @alephao
What is GYB: https://nshipster.com/swift-gyb/
Source code: https://github.com/apple/swift/blob/main/utils/gyb.py
Why?
What to do?
Lines 5 to 10 in 2a5d94e
solidity-benchmarks/scripts/main.py
Lines 104 to 109 in 2a5d94e
make readme
and make json
Mostly implemented on my fork based on transferFrom logic. N/A for ERC721B.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.