Skip to content

Commit

Permalink
Merge pull request #1 from hoanhan101/0xth0mas-gas-optimizations
Browse files Browse the repository at this point in the history
Add gas optimizations by 0xth0mas
  • Loading branch information
hoanhan101 authored Aug 10, 2023
2 parents 3882ee5 + e04d1f8 commit 7a66600
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 54 deletions.
103 changes: 76 additions & 27 deletions contracts/LeetBrian.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// SPDX-License-Identifier: MIT
// 1337 Based Brians
// by hoanh.eth
// gas optimizations by 0xth0mas.eth
//
pragma solidity ^0.8.17;
pragma solidity ^0.8.20;

import "@0xsequence/sstore2/contracts/SSTORE2.sol";
import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";
Expand All @@ -15,8 +16,8 @@ import {ERC721AQueryable} from "erc721a/contracts/extensions/ERC721AQueryable.so
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";

struct Trait {
string name;
address image;
string name;
}

struct Payload {
Expand All @@ -41,10 +42,11 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
bytes32 private _merkleRoot;
bytes32 private _raritiesHash;

Trait[][6] private _traits;
mapping(uint256 => uint256) private _traitCounts;
mapping(uint256 => mapping(uint256 => Trait)) private _traits;

mapping(bytes32 => bool) private _combo;
mapping(uint256 => Brian) private _registry;
mapping(uint256 => uint256) private _combo;
mapping(uint256 => uint256) private _registry;
mapping(address => bool) _minted;

error MintClose();
Expand Down Expand Up @@ -80,7 +82,7 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
bytes32[] calldata merkleProof
) public view returns (bool) {
return
MerkleProof.verify(
MerkleProof.verifyCalldata(
merkleProof,
_merkleRoot,
keccak256(abi.encodePacked(addr))
Expand All @@ -101,16 +103,19 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
uint8 layer,
Payload[] calldata payload
) public onlyOwner {
uint256 i = 0;
Trait memory trait;
do {
trait.name = payload[i].name;
uint256 traitIndex = _traitCounts[layer];
unchecked { _traitCounts[layer] += payload.length; }

for(uint256 i;i < payload.length;) {
Trait storage trait = _traits[layer][traitIndex];
trait.image = SSTORE2.write(payload[i].image);
_traits[layer].push(trait);
trait.name = payload[i].name;

unchecked {
++i;
++traitIndex;
}
} while (i < payload.length);
}
}

/**
Expand Down Expand Up @@ -161,7 +166,7 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
{
if (!_exists(tokenID)) revert InvalidToken();

Brian memory brian = _registry[tokenID];
Brian memory brian = _getTraits(tokenID);
bytes memory json = abi.encodePacked(
'{"name": "1337 Based Brian #',
LibString.toString(tokenID),
Expand Down Expand Up @@ -288,24 +293,30 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
) private {
uint256 seed = uint256(
keccak256(
abi.encodePacked(block.difficulty, tokenID, address(this))
abi.encodePacked(block.prevrandao, tokenID, address(this))
)
);

uint256 current = tokenID;
bytes32 combination;
Brian memory brian;
uint256 combination;
uint256[] calldata backgroundRarities = rarities[0];
uint256[] calldata bodyRarities = rarities[1];
uint256[] calldata underRarities = rarities[2];
uint256[] calldata eyesRarities = rarities[3];
uint256[] calldata overRarities = rarities[4];
uint256[] calldata specialRarities = rarities[5];

while (true) {
brian.background = _getRandomTraitIndex(rarities[0], seed);
brian.body = _getRandomTraitIndex(rarities[1], seed >> 8);
brian.under = _getRandomTraitIndex(rarities[2], seed >> 16);
brian.eyes = _getRandomTraitIndex(rarities[3], seed >> 32);
brian.over = _getRandomTraitIndex(rarities[4], seed >> 40);
brian.special = _getRandomTraitIndex(rarities[5], seed >> 48);

combination = keccak256(abi.encode(brian));
if (!_combo[combination]) {
_combo[combination] = true;
_registry[current] = brian;
combination = _getRandomTraitIndex(backgroundRarities, seed);
combination |= (_getRandomTraitIndex(bodyRarities, seed >> 16) << 8);
combination |= (_getRandomTraitIndex(underRarities, seed >> 32) << 16);
combination |= (_getRandomTraitIndex(eyesRarities, seed >> 48) << 24);
combination |= (_getRandomTraitIndex(overRarities, seed >> 64) << 32);
combination |= (_getRandomTraitIndex(specialRarities, seed >> 80) << 40);

if (_combo[combination] == 0) {
_combo[combination] = 1;
_storeTraits(current, combination);

unchecked {
++current;
Expand Down Expand Up @@ -344,4 +355,42 @@ contract LeetBrian is ERC721A, ERC721AQueryable, Ownable {
}
revert();
}

function _storeTraits(uint256 tokenId, uint256 traitCombination) internal {
uint256 tokenTraitBucket = tokenId / 4;
uint256 tokenTraitSlot = tokenId % 4;
uint256 traitMask = not(0xFFFFFFFFFFFFFFFF << (64 * tokenTraitSlot));
_registry[tokenTraitBucket] =
(_registry[tokenTraitBucket] & traitMask) |
(traitCombination << (64 * tokenTraitSlot));
}

function _getTraits(
uint256 tokenId
) internal view returns (Brian memory brian) {
uint256 tokenTraitBucket = tokenId / 4;
uint256 tokenTraitSlot = tokenId % 4;
uint256 traitMask = 0xFFFFFFFFFFFFFFFF << (64 * tokenTraitSlot);
uint256 traitCombination = (_registry[tokenTraitBucket] &
traitMask) >> (64 * tokenTraitSlot);
traitMask = 0xFF;

brian.background = traitCombination & traitMask;
traitCombination >>= 8;
brian.body = traitCombination & traitMask;
traitCombination >>= 8;
brian.under = traitCombination & traitMask;
traitCombination >>= 8;
brian.eyes = traitCombination & traitMask;
traitCombination >>= 8;
brian.over = traitCombination & traitMask;
traitCombination >>= 8;
brian.special = traitCombination;
}

function not(uint256 val) internal pure returns (uint256 notval) {
assembly ("memory-safe") {
notval := not(val)
}
}
}
30 changes: 3 additions & 27 deletions hardhat.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,47 +4,23 @@ require("dotenv").config();

module.exports = {
solidity: {
version: "0.8.17",
version: "0.8.20",
settings: {
optimizer: {
enabled: true,
runs: 1337,
},
// viaIR: true,
evmVersion: "paris",
viaIR: true,
},
},
networks: {
hardhat: {
blockGasLimit: 60000000,
},
mainnet: {
url: process.env.ETHEREUM_PROVIDER || "http://127.0.0.1:8555",
accounts: [process.env.ETHEREUM_PRIVATE_KEY],
blockGasLimit: 60000000,
},
goerli: {
url: process.env.GOERLI_PROVIDER || "http://127.0.0.1:8555",
accounts: [process.env.GOERLI_PRIVATE_KEY],
blockGasLimit: 60000000,
},
"base-goerli": {
url: "https://goerli.base.org",
accounts: [process.env.GOERLI_PRIVATE_KEY],
gasPrice: 1000000000,
blockGasLimit: 60000000,
},
"base-mainnet": {
url: "https://mainnet.base.org",
accounts: [process.env.GOERLI_PRIVATE_KEY],
gasPrice: 1000000000,
blockGasLimit: 60000000,
},
},
etherscan: {
apiKey: {
goerli: process.env.ETHERSCAN_APIKEY,
mainnet: process.env.ETHERSCAN_APIKEY,
"base-goerli": process.env.BASESCAN_APIKEY,
},
customChains: [
{
Expand Down

0 comments on commit 7a66600

Please sign in to comment.