diff --git a/contracts/OpenEditionERC721.sol b/contracts/OpenEditionERC721.sol
index 9619fc602..48d93408c 100644
--- a/contracts/OpenEditionERC721.sol
+++ b/contracts/OpenEditionERC721.sol
@@ -17,7 +17,7 @@ pragma solidity ^0.8.11;
import "@openzeppelin/contracts-upgradeable/utils/StringsUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol";
-import "./eip/ERC721AVirtualApproveUpgradeable.sol";
+import "./eip/queryable/ERC721AQueryableUpgradeable.sol";
// ========== Internal imports ==========
@@ -28,7 +28,6 @@ import "./lib/CurrencyTransferLib.sol";
import "./extension/Multicall.sol";
import "./extension/ContractMetadata.sol";
-import "./extension/PlatformFee.sol";
import "./extension/Royalty.sol";
import "./extension/PrimarySale.sol";
import "./extension/Ownable.sol";
@@ -42,7 +41,6 @@ import "./extension/DefaultOperatorFiltererUpgradeable.sol";
contract OpenEditionERC721 is
Initializable,
ContractMetadata,
- PlatformFee,
Royalty,
PrimarySale,
Ownable,
@@ -52,7 +50,7 @@ contract OpenEditionERC721 is
ERC2771ContextUpgradeable,
Multicall,
DefaultOperatorFiltererUpgradeable,
- ERC721AUpgradeable
+ ERC721AQueryableUpgradeable
{
using StringsUpgradeable for uint256;
@@ -83,10 +81,8 @@ contract OpenEditionERC721 is
address[] memory _trustedForwarders,
address _saleRecipient,
address _royaltyRecipient,
- uint128 _royaltyBps,
- uint128 _platformFeeBps,
- address _platformFeeRecipient
- ) external initializer {
+ uint128 _royaltyBps
+ ) external initializerERC721A initializer {
bytes32 _transferRole = keccak256("TRANSFER_ROLE");
bytes32 _minterRole = keccak256("MINTER_ROLE");
@@ -104,7 +100,6 @@ contract OpenEditionERC721 is
_setupRole(_transferRole, _defaultAdmin);
_setupRole(_transferRole, address(0));
- _setupPlatformFeeInfo(_platformFeeRecipient, _platformFeeBps);
_setupDefaultRoyaltyInfo(_royaltyRecipient, _royaltyBps);
_setupPrimarySaleRecipient(_saleRecipient);
@@ -117,7 +112,13 @@ contract OpenEditionERC721 is
//////////////////////////////////////////////////////////////*/
/// @dev Returns the URI for a given tokenId.
- function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) {
+ function tokenURI(uint256 _tokenId)
+ public
+ view
+ virtual
+ override(ERC721AUpgradeable, IERC721AUpgradeable)
+ returns (string memory)
+ {
if (!_exists(_tokenId)) {
revert("!ID");
}
@@ -130,7 +131,7 @@ contract OpenEditionERC721 is
public
view
virtual
- override(ERC721AUpgradeable, IERC165)
+ override(ERC721AUpgradeable, IERC165, IERC721AUpgradeable)
returns (bool)
{
return super.supportsInterface(interfaceId) || type(IERC2981Upgradeable).interfaceId == interfaceId;
@@ -172,22 +173,7 @@ contract OpenEditionERC721 is
address saleRecipient = _primarySaleRecipient == address(0) ? primarySaleRecipient() : _primarySaleRecipient;
- uint256 fees;
- address feeRecipient;
-
- PlatformFeeType feeType = getPlatformFeeType();
- if (feeType == PlatformFeeType.Flat) {
- (feeRecipient, fees) = getFlatPlatformFeeInfo();
- } else {
- uint16 platformFeeBps;
- (feeRecipient, platformFeeBps) = getPlatformFeeInfo();
- fees = (totalPrice * platformFeeBps) / MAX_BPS;
- }
-
- require(totalPrice >= fees, "!F");
-
- CurrencyTransferLib.transferCurrency(_currency, _msgSender(), feeRecipient, fees);
- CurrencyTransferLib.transferCurrency(_currency, _msgSender(), saleRecipient, totalPrice - fees);
+ CurrencyTransferLib.transferCurrency(_currency, _msgSender(), saleRecipient, totalPrice);
}
/// @dev Transfers the NFTs being claimed.
@@ -196,15 +182,10 @@ contract OpenEditionERC721 is
override
returns (uint256 startTokenId_)
{
- startTokenId_ = _currentIndex;
+ startTokenId_ = _nextTokenId();
_safeMint(_to, _quantityBeingClaimed);
}
- /// @dev Checks whether platform fee info can be set in the given execution context.
- function _canSetPlatformFeeInfo() internal view override returns (bool) {
- return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
- }
-
/// @dev Checks whether primary sale recipient can be set in the given execution context.
function _canSetPrimarySaleRecipient() internal view override returns (bool) {
return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
@@ -249,18 +230,18 @@ contract OpenEditionERC721 is
*/
function totalMinted() external view returns (uint256) {
unchecked {
- return _currentIndex - _startTokenId();
+ return _nextTokenId() - _startTokenId();
}
}
/// @dev The tokenId of the next NFT that will be minted / lazy minted.
function nextTokenIdToMint() external view returns (uint256) {
- return _currentIndex;
+ return _nextTokenId();
}
/// @dev The next token ID of the NFT that can be claimed.
function nextTokenIdToClaim() external view returns (uint256) {
- return _currentIndex;
+ return _nextTokenId();
}
/// @dev Burns `tokenId`. See {ERC721-_burn}.
@@ -287,12 +268,21 @@ contract OpenEditionERC721 is
}
/// @dev See {ERC721-setApprovalForAll}.
- function setApprovalForAll(address operator, bool approved) public override onlyAllowedOperatorApproval(operator) {
+ function setApprovalForAll(address operator, bool approved)
+ public
+ override(IERC721AUpgradeable, ERC721AUpgradeable)
+ onlyAllowedOperatorApproval(operator)
+ {
super.setApprovalForAll(operator, approved);
}
/// @dev See {ERC721-approve}.
- function approve(address operator, uint256 tokenId) public override onlyAllowedOperatorApproval(operator) {
+ function approve(address operator, uint256 tokenId)
+ public
+ payable
+ override(ERC721AUpgradeable, IERC721AUpgradeable)
+ onlyAllowedOperatorApproval(operator)
+ {
super.approve(operator, tokenId);
}
@@ -301,7 +291,7 @@ contract OpenEditionERC721 is
address from,
address to,
uint256 tokenId
- ) public override(ERC721AUpgradeable) onlyAllowedOperator(from) {
+ ) public payable override(ERC721AUpgradeable, IERC721AUpgradeable) onlyAllowedOperator(from) {
super.transferFrom(from, to, tokenId);
}
@@ -310,7 +300,7 @@ contract OpenEditionERC721 is
address from,
address to,
uint256 tokenId
- ) public override(ERC721AUpgradeable) onlyAllowedOperator(from) {
+ ) public payable override(ERC721AUpgradeable, IERC721AUpgradeable) onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId);
}
@@ -320,7 +310,7 @@ contract OpenEditionERC721 is
address to,
uint256 tokenId,
bytes memory data
- ) public override(ERC721AUpgradeable) onlyAllowedOperator(from) {
+ ) public payable override(ERC721AUpgradeable, IERC721AUpgradeable) onlyAllowedOperator(from) {
super.safeTransferFrom(from, to, tokenId, data);
}
@@ -328,23 +318,15 @@ contract OpenEditionERC721 is
return _msgSender();
}
- function _msgSender()
- internal
- view
- virtual
- override(ContextUpgradeable, ERC2771ContextUpgradeable)
- returns (address sender)
- {
+ function _msgSenderERC721A() internal view virtual override returns (address) {
+ return _msgSender();
+ }
+
+ function _msgSender() internal view virtual override(ERC2771ContextUpgradeable) returns (address sender) {
return ERC2771ContextUpgradeable._msgSender();
}
- function _msgData()
- internal
- view
- virtual
- override(ContextUpgradeable, ERC2771ContextUpgradeable)
- returns (bytes calldata)
- {
+ function _msgData() internal view virtual override(ERC2771ContextUpgradeable) returns (bytes calldata) {
return ERC2771ContextUpgradeable._msgData();
}
}
diff --git a/contracts/base/Staking1155Base.sol b/contracts/base/Staking1155Base.sol
index 5d6c558eb..be9a1979c 100644
--- a/contracts/base/Staking1155Base.sol
+++ b/contracts/base/Staking1155Base.sol
@@ -55,8 +55,8 @@ contract Staking1155Base is ContractMetadata, Multicall, Ownable, Staking1155, E
uint256 private rewardTokenBalance;
constructor(
+ uint80 _defaultTimeUnit,
address _defaultAdmin,
- uint256 _defaultTimeUnit,
uint256 _defaultRewardsPerUnitTime,
address _stakingToken,
address _rewardToken,
diff --git a/contracts/base/Staking20Base.sol b/contracts/base/Staking20Base.sol
index 720e3ab1a..917699afc 100644
--- a/contracts/base/Staking20Base.sol
+++ b/contracts/base/Staking20Base.sol
@@ -51,8 +51,8 @@ contract Staking20Base is ContractMetadata, Multicall, Ownable, Staking20 {
uint256 private rewardTokenBalance;
constructor(
+ uint80 _timeUnit,
address _defaultAdmin,
- uint256 _timeUnit,
uint256 _rewardRatioNumerator,
uint256 _rewardRatioDenominator,
address _stakingToken,
diff --git a/contracts/eip/queryable/ERC721AQueryableUpgradeable.sol b/contracts/eip/queryable/ERC721AQueryableUpgradeable.sol
new file mode 100644
index 000000000..2018c8bc5
--- /dev/null
+++ b/contracts/eip/queryable/ERC721AQueryableUpgradeable.sol
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: MIT
+// ERC721A Contracts v4.2.3
+// Creator: Chiru Labs
+
+pragma solidity ^0.8.4;
+
+import "./IERC721AQueryableUpgradeable.sol";
+import "./ERC721AUpgradeable.sol";
+import "./ERC721A__Initializable.sol";
+
+/**
+ * @title ERC721AQueryable.
+ *
+ * @dev ERC721A subclass with convenience query functions.
+ */
+abstract contract ERC721AQueryableUpgradeable is
+ ERC721A__Initializable,
+ ERC721AUpgradeable,
+ IERC721AQueryableUpgradeable
+{
+ function __ERC721AQueryable_init() internal onlyInitializingERC721A {
+ __ERC721AQueryable_init_unchained();
+ }
+
+ function __ERC721AQueryable_init_unchained() internal onlyInitializingERC721A {}
+
+ /**
+ * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
+ *
+ * If the `tokenId` is out of bounds:
+ *
+ * - `addr = address(0)`
+ * - `startTimestamp = 0`
+ * - `burned = false`
+ * - `extraData = 0`
+ *
+ * If the `tokenId` is burned:
+ *
+ * - `addr =
`
+ * - `startTimestamp = `
+ * - `burned = true`
+ * - `extraData = `
+ *
+ * Otherwise:
+ *
+ * - `addr = `
+ * - `startTimestamp = `
+ * - `burned = false`
+ * - `extraData = `
+ */
+ function explicitOwnershipOf(uint256 tokenId)
+ public
+ view
+ virtual
+ override
+ returns (TokenOwnership memory ownership)
+ {
+ unchecked {
+ if (tokenId >= _startTokenId()) {
+ if (tokenId < _nextTokenId()) {
+ // If the `tokenId` is within bounds,
+ // scan backwards for the initialized ownership slot.
+ while (!_ownershipIsInitialized(tokenId)) --tokenId;
+ return _ownershipAt(tokenId);
+ }
+ }
+ }
+ }
+
+ /**
+ * @dev Returns an array of token IDs owned by `owner`,
+ * in the range [`start`, `stop`)
+ * (i.e. `start <= tokenId < stop`).
+ *
+ * This function allows for tokens to be queried if the collection
+ * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
+ *
+ * Requirements:
+ *
+ * - `start < stop`
+ */
+ function tokensOfOwnerIn(
+ address owner,
+ uint256 start,
+ uint256 stop
+ ) external view virtual override returns (uint256[] memory) {
+ return _tokensOfOwnerIn(owner, start, stop);
+ }
+
+ /**
+ * @dev Returns an array of token IDs owned by `owner`.
+ *
+ * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
+ * It is meant to be called off-chain.
+ *
+ * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
+ * multiple smaller scans if the collection is large enough to cause
+ * an out-of-gas error (10K collections should be fine).
+ */
+ function tokensOfOwner(address owner) external view virtual override returns (uint256[] memory) {
+ uint256 start = _startTokenId();
+ uint256 stop = _nextTokenId();
+ uint256[] memory tokenIds;
+ if (start != stop) tokenIds = _tokensOfOwnerIn(owner, start, stop);
+ return tokenIds;
+ }
+
+ /**
+ * @dev Helper function for returning an array of token IDs owned by `owner`.
+ *
+ * Note that this function is optimized for smaller bytecode size over runtime gas,
+ * since it is meant to be called off-chain.
+ */
+ function _tokensOfOwnerIn(
+ address owner,
+ uint256 start,
+ uint256 stop
+ ) private view returns (uint256[] memory) {
+ unchecked {
+ if (start >= stop) _revert(InvalidQueryRange.selector);
+ // Set `start = max(start, _startTokenId())`.
+ if (start < _startTokenId()) {
+ start = _startTokenId();
+ }
+ uint256 stopLimit = _nextTokenId();
+ // Set `stop = min(stop, stopLimit)`.
+ if (stop >= stopLimit) {
+ stop = stopLimit;
+ }
+ uint256[] memory tokenIds;
+ uint256 tokenIdsMaxLength = balanceOf(owner);
+ bool startLtStop = start < stop;
+ assembly {
+ // Set `tokenIdsMaxLength` to zero if `start` is less than `stop`.
+ tokenIdsMaxLength := mul(tokenIdsMaxLength, startLtStop)
+ }
+ if (tokenIdsMaxLength != 0) {
+ // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
+ // to cater for cases where `balanceOf(owner)` is too big.
+ if (stop - start <= tokenIdsMaxLength) {
+ tokenIdsMaxLength = stop - start;
+ }
+ assembly {
+ // Grab the free memory pointer.
+ tokenIds := mload(0x40)
+ // Allocate one word for the length, and `tokenIdsMaxLength` words
+ // for the data. `shl(5, x)` is equivalent to `mul(32, x)`.
+ mstore(0x40, add(tokenIds, shl(5, add(tokenIdsMaxLength, 1))))
+ }
+ // We need to call `explicitOwnershipOf(start)`,
+ // because the slot at `start` may not be initialized.
+ TokenOwnership memory ownership = explicitOwnershipOf(start);
+ address currOwnershipAddr;
+ // If the starting slot exists (i.e. not burned),
+ // initialize `currOwnershipAddr`.
+ // `ownership.address` will not be zero,
+ // as `start` is clamped to the valid token ID range.
+ if (!ownership.burned) {
+ currOwnershipAddr = ownership.addr;
+ }
+ uint256 tokenIdsIdx;
+ // Use a do-while, which is slightly more efficient for this case,
+ // as the array will at least contain one element.
+ do {
+ ownership = _ownershipAt(start);
+ assembly {
+ switch mload(add(ownership, 0x40))
+ // if `ownership.burned == false`.
+ case 0 {
+ // if `ownership.addr != address(0)`.
+ // The `addr` already has it's upper 96 bits clearned,
+ // since it is written to memory with regular Solidity.
+ if mload(ownership) {
+ currOwnershipAddr := mload(ownership)
+ }
+ // if `currOwnershipAddr == owner`.
+ // The `shl(96, x)` is to make the comparison agnostic to any
+ // dirty upper 96 bits in `owner`.
+ if iszero(shl(96, xor(currOwnershipAddr, owner))) {
+ tokenIdsIdx := add(tokenIdsIdx, 1)
+ mstore(add(tokenIds, shl(5, tokenIdsIdx)), start)
+ }
+ }
+ // Otherwise, reset `currOwnershipAddr`.
+ // This handles the case of batch burned tokens
+ // (burned bit of first slot set, remaining slots left uninitialized).
+ default {
+ currOwnershipAddr := 0
+ }
+ start := add(start, 1)
+ }
+ } while (!(start == stop || tokenIdsIdx == tokenIdsMaxLength));
+ // Store the length of the array.
+ assembly {
+ mstore(tokenIds, tokenIdsIdx)
+ }
+ }
+ return tokenIds;
+ }
+ }
+}
diff --git a/contracts/eip/queryable/ERC721AStorage.sol b/contracts/eip/queryable/ERC721AStorage.sol
new file mode 100644
index 000000000..d9f5c12cd
--- /dev/null
+++ b/contracts/eip/queryable/ERC721AStorage.sol
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+library ERC721AStorage {
+ // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
+ struct TokenApprovalRef {
+ address value;
+ }
+
+ struct Layout {
+ // =============================================================
+ // STORAGE
+ // =============================================================
+
+ // The next token ID to be minted.
+ uint256 _currentIndex;
+ // The number of tokens burned.
+ uint256 _burnCounter;
+ // Token name
+ string _name;
+ // Token symbol
+ string _symbol;
+ // Mapping from token ID to ownership details
+ // An empty struct value does not necessarily mean the token is unowned.
+ // See {_packedOwnershipOf} implementation for details.
+ //
+ // Bits Layout:
+ // - [0..159] `addr`
+ // - [160..223] `startTimestamp`
+ // - [224] `burned`
+ // - [225] `nextInitialized`
+ // - [232..255] `extraData`
+ mapping(uint256 => uint256) _packedOwnerships;
+ // Mapping owner address to address data.
+ //
+ // Bits Layout:
+ // - [0..63] `balance`
+ // - [64..127] `numberMinted`
+ // - [128..191] `numberBurned`
+ // - [192..255] `aux`
+ mapping(address => uint256) _packedAddressData;
+ // Mapping from token ID to approved address.
+ mapping(uint256 => ERC721AStorage.TokenApprovalRef) _tokenApprovals;
+ // Mapping from owner to operator approvals
+ mapping(address => mapping(address => bool)) _operatorApprovals;
+ }
+
+ bytes32 internal constant STORAGE_SLOT = keccak256("ERC721A.contracts.storage.ERC721A");
+
+ function layout() internal pure returns (Layout storage l) {
+ bytes32 slot = STORAGE_SLOT;
+ assembly {
+ l.slot := slot
+ }
+ }
+}
diff --git a/contracts/eip/queryable/ERC721AUpgradeable.sol b/contracts/eip/queryable/ERC721AUpgradeable.sol
new file mode 100644
index 000000000..0e0bf0b75
--- /dev/null
+++ b/contracts/eip/queryable/ERC721AUpgradeable.sol
@@ -0,0 +1,1111 @@
+// SPDX-License-Identifier: MIT
+// ERC721A Contracts v4.2.3
+// Creator: Chiru Labs
+
+pragma solidity ^0.8.4;
+
+import "./IERC721AUpgradeable.sol";
+import { ERC721AStorage } from "./ERC721AStorage.sol";
+import "./ERC721A__Initializable.sol";
+
+/**
+ * @dev Interface of ERC721 token receiver.
+ */
+interface ERC721A__IERC721ReceiverUpgradeable {
+ function onERC721Received(
+ address operator,
+ address from,
+ uint256 tokenId,
+ bytes calldata data
+ ) external returns (bytes4);
+}
+
+/**
+ * @title ERC721A
+ *
+ * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
+ * Non-Fungible Token Standard, including the Metadata extension.
+ * Optimized for lower gas during batch mints.
+ *
+ * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
+ * starting from `_startTokenId()`.
+ *
+ * Assumptions:
+ *
+ * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
+ * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
+ */
+contract ERC721AUpgradeable is ERC721A__Initializable, IERC721AUpgradeable {
+ using ERC721AStorage for ERC721AStorage.Layout;
+
+ // =============================================================
+ // CONSTANTS
+ // =============================================================
+
+ // Mask of an entry in packed address data.
+ uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;
+
+ // The bit position of `numberMinted` in packed address data.
+ uint256 private constant _BITPOS_NUMBER_MINTED = 64;
+
+ // The bit position of `numberBurned` in packed address data.
+ uint256 private constant _BITPOS_NUMBER_BURNED = 128;
+
+ // The bit position of `aux` in packed address data.
+ uint256 private constant _BITPOS_AUX = 192;
+
+ // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
+ uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;
+
+ // The bit position of `startTimestamp` in packed ownership.
+ uint256 private constant _BITPOS_START_TIMESTAMP = 160;
+
+ // The bit mask of the `burned` bit in packed ownership.
+ uint256 private constant _BITMASK_BURNED = 1 << 224;
+
+ // The bit position of the `nextInitialized` bit in packed ownership.
+ uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;
+
+ // The bit mask of the `nextInitialized` bit in packed ownership.
+ uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;
+
+ // The bit position of `extraData` in packed ownership.
+ uint256 private constant _BITPOS_EXTRA_DATA = 232;
+
+ // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
+ uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;
+
+ // The mask of the lower 160 bits for addresses.
+ uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;
+
+ // The maximum `quantity` that can be minted with {_mintERC2309}.
+ // This limit is to prevent overflows on the address data entries.
+ // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
+ // is required to cause an overflow, which is unrealistic.
+ uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;
+
+ // The `Transfer` event signature is given by:
+ // `keccak256(bytes("Transfer(address,address,uint256)"))`.
+ bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
+ 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
+
+ // =============================================================
+ // CONSTRUCTOR
+ // =============================================================
+
+ function __ERC721A_init(string memory name_, string memory symbol_) internal onlyInitializingERC721A {
+ __ERC721A_init_unchained(name_, symbol_);
+ }
+
+ function __ERC721A_init_unchained(string memory name_, string memory symbol_) internal onlyInitializingERC721A {
+ ERC721AStorage.layout()._name = name_;
+ ERC721AStorage.layout()._symbol = symbol_;
+ ERC721AStorage.layout()._currentIndex = _startTokenId();
+ }
+
+ // =============================================================
+ // TOKEN COUNTING OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Returns the starting token ID.
+ * To change the starting token ID, please override this function.
+ */
+ function _startTokenId() internal view virtual returns (uint256) {
+ return 0;
+ }
+
+ /**
+ * @dev Returns the next token ID to be minted.
+ */
+ function _nextTokenId() internal view virtual returns (uint256) {
+ return ERC721AStorage.layout()._currentIndex;
+ }
+
+ /**
+ * @dev Returns the total number of tokens in existence.
+ * Burned tokens will reduce the count.
+ * To get the total number of tokens minted, please see {_totalMinted}.
+ */
+ function totalSupply() public view virtual override returns (uint256) {
+ // Counter underflow is impossible as _burnCounter cannot be incremented
+ // more than `_currentIndex - _startTokenId()` times.
+ unchecked {
+ return ERC721AStorage.layout()._currentIndex - ERC721AStorage.layout()._burnCounter - _startTokenId();
+ }
+ }
+
+ /**
+ * @dev Returns the total amount of tokens minted in the contract.
+ */
+ function _totalMinted() internal view virtual returns (uint256) {
+ // Counter underflow is impossible as `_currentIndex` does not decrement,
+ // and it is initialized to `_startTokenId()`.
+ unchecked {
+ return ERC721AStorage.layout()._currentIndex - _startTokenId();
+ }
+ }
+
+ /**
+ * @dev Returns the total number of tokens burned.
+ */
+ function _totalBurned() internal view virtual returns (uint256) {
+ return ERC721AStorage.layout()._burnCounter;
+ }
+
+ // =============================================================
+ // ADDRESS DATA OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Returns the number of tokens in `owner`'s account.
+ */
+ function balanceOf(address owner) public view virtual override returns (uint256) {
+ if (owner == address(0)) _revert(BalanceQueryForZeroAddress.selector);
+ return ERC721AStorage.layout()._packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
+ }
+
+ /**
+ * Returns the number of tokens minted by `owner`.
+ */
+ function _numberMinted(address owner) internal view returns (uint256) {
+ return
+ (ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
+ }
+
+ /**
+ * Returns the number of tokens burned by or on behalf of `owner`.
+ */
+ function _numberBurned(address owner) internal view returns (uint256) {
+ return
+ (ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
+ }
+
+ /**
+ * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
+ */
+ function _getAux(address owner) internal view returns (uint64) {
+ return uint64(ERC721AStorage.layout()._packedAddressData[owner] >> _BITPOS_AUX);
+ }
+
+ /**
+ * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
+ * If there are multiple variables, please pack them into a uint64.
+ */
+ function _setAux(address owner, uint64 aux) internal virtual {
+ uint256 packed = ERC721AStorage.layout()._packedAddressData[owner];
+ uint256 auxCasted;
+ // Cast `aux` with assembly to avoid redundant masking.
+ assembly {
+ auxCasted := aux
+ }
+ packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
+ ERC721AStorage.layout()._packedAddressData[owner] = packed;
+ }
+
+ // =============================================================
+ // IERC165
+ // =============================================================
+
+ /**
+ * @dev Returns true if this contract implements the interface defined by
+ * `interfaceId`. See the corresponding
+ * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
+ * to learn more about how these ids are created.
+ *
+ * This function call must use less than 30000 gas.
+ */
+ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
+ // The interface IDs are constants representing the first 4 bytes
+ // of the XOR of all function selectors in the interface.
+ // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
+ // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
+ return
+ interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
+ interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
+ interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
+ }
+
+ // =============================================================
+ // IERC721Metadata
+ // =============================================================
+
+ /**
+ * @dev Returns the token collection name.
+ */
+ function name() public view virtual override returns (string memory) {
+ return ERC721AStorage.layout()._name;
+ }
+
+ /**
+ * @dev Returns the token collection symbol.
+ */
+ function symbol() public view virtual override returns (string memory) {
+ return ERC721AStorage.layout()._symbol;
+ }
+
+ /**
+ * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
+ */
+ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
+ if (!_exists(tokenId)) _revert(URIQueryForNonexistentToken.selector);
+
+ string memory baseURI = _baseURI();
+ return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : "";
+ }
+
+ /**
+ * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
+ * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
+ * by default, it can be overridden in child contracts.
+ */
+ function _baseURI() internal view virtual returns (string memory) {
+ return "";
+ }
+
+ // =============================================================
+ // OWNERSHIPS OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Returns the owner of the `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function ownerOf(uint256 tokenId) public view virtual override returns (address) {
+ return address(uint160(_packedOwnershipOf(tokenId)));
+ }
+
+ /**
+ * @dev Gas spent here starts off proportional to the maximum mint batch size.
+ * It gradually moves to O(1) as tokens get transferred around over time.
+ */
+ function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
+ return _unpackedOwnership(_packedOwnershipOf(tokenId));
+ }
+
+ /**
+ * @dev Returns the unpacked `TokenOwnership` struct at `index`.
+ */
+ function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
+ return _unpackedOwnership(ERC721AStorage.layout()._packedOwnerships[index]);
+ }
+
+ /**
+ * @dev Returns whether the ownership slot at `index` is initialized.
+ * An uninitialized slot does not necessarily mean that the slot has no owner.
+ */
+ function _ownershipIsInitialized(uint256 index) internal view virtual returns (bool) {
+ return ERC721AStorage.layout()._packedOwnerships[index] != 0;
+ }
+
+ /**
+ * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
+ */
+ function _initializeOwnershipAt(uint256 index) internal virtual {
+ if (ERC721AStorage.layout()._packedOwnerships[index] == 0) {
+ ERC721AStorage.layout()._packedOwnerships[index] = _packedOwnershipOf(index);
+ }
+ }
+
+ /**
+ * Returns the packed ownership data of `tokenId`.
+ */
+ function _packedOwnershipOf(uint256 tokenId) private view returns (uint256 packed) {
+ if (_startTokenId() <= tokenId) {
+ packed = ERC721AStorage.layout()._packedOwnerships[tokenId];
+ // If the data at the starting slot does not exist, start the scan.
+ if (packed == 0) {
+ if (tokenId >= ERC721AStorage.layout()._currentIndex) _revert(OwnerQueryForNonexistentToken.selector);
+ // Invariant:
+ // There will always be an initialized ownership slot
+ // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
+ // before an unintialized ownership slot
+ // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
+ // Hence, `tokenId` will not underflow.
+ //
+ // We can directly compare the packed value.
+ // If the address is zero, packed will be zero.
+ for (;;) {
+ unchecked {
+ packed = ERC721AStorage.layout()._packedOwnerships[--tokenId];
+ }
+ if (packed == 0) continue;
+ if (packed & _BITMASK_BURNED == 0) return packed;
+ // Otherwise, the token is burned, and we must revert.
+ // This handles the case of batch burned tokens, where only the burned bit
+ // of the starting slot is set, and remaining slots are left uninitialized.
+ _revert(OwnerQueryForNonexistentToken.selector);
+ }
+ }
+ // Otherwise, the data exists and we can skip the scan.
+ // This is possible because we have already achieved the target condition.
+ // This saves 2143 gas on transfers of initialized tokens.
+ // If the token is not burned, return `packed`. Otherwise, revert.
+ if (packed & _BITMASK_BURNED == 0) return packed;
+ }
+ _revert(OwnerQueryForNonexistentToken.selector);
+ }
+
+ /**
+ * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
+ */
+ function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
+ ownership.addr = address(uint160(packed));
+ ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
+ ownership.burned = packed & _BITMASK_BURNED != 0;
+ ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
+ }
+
+ /**
+ * @dev Packs ownership data into a single uint256.
+ */
+ function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
+ assembly {
+ // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ owner := and(owner, _BITMASK_ADDRESS)
+ // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
+ result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
+ }
+ }
+
+ /**
+ * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
+ */
+ function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
+ // For branchless setting of the `nextInitialized` flag.
+ assembly {
+ // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
+ result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
+ }
+ }
+
+ // =============================================================
+ // APPROVAL OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}.
+ *
+ * Requirements:
+ *
+ * - The caller must own the token or be an approved operator.
+ */
+ function approve(address to, uint256 tokenId) public payable virtual override {
+ _approve(to, tokenId, true);
+ }
+
+ /**
+ * @dev Returns the account approved for `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function getApproved(uint256 tokenId) public view virtual override returns (address) {
+ if (!_exists(tokenId)) _revert(ApprovalQueryForNonexistentToken.selector);
+
+ return ERC721AStorage.layout()._tokenApprovals[tokenId].value;
+ }
+
+ /**
+ * @dev Approve or remove `operator` as an operator for the caller.
+ * Operators can call {transferFrom} or {safeTransferFrom}
+ * for any token owned by the caller.
+ *
+ * Requirements:
+ *
+ * - The `operator` cannot be the caller.
+ *
+ * Emits an {ApprovalForAll} event.
+ */
+ function setApprovalForAll(address operator, bool approved) public virtual override {
+ ERC721AStorage.layout()._operatorApprovals[_msgSenderERC721A()][operator] = approved;
+ emit ApprovalForAll(_msgSenderERC721A(), operator, approved);
+ }
+
+ /**
+ * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
+ *
+ * See {setApprovalForAll}.
+ */
+ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
+ return ERC721AStorage.layout()._operatorApprovals[owner][operator];
+ }
+
+ /**
+ * @dev Returns whether `tokenId` exists.
+ *
+ * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
+ *
+ * Tokens start existing when they are minted. See {_mint}.
+ */
+ function _exists(uint256 tokenId) internal view virtual returns (bool result) {
+ if (_startTokenId() <= tokenId) {
+ if (tokenId < ERC721AStorage.layout()._currentIndex) {
+ uint256 packed;
+ while ((packed = ERC721AStorage.layout()._packedOwnerships[tokenId]) == 0) --tokenId;
+ result = packed & _BITMASK_BURNED == 0;
+ }
+ }
+ }
+
+ /**
+ * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
+ */
+ function _isSenderApprovedOrOwner(
+ address approvedAddress,
+ address owner,
+ address msgSender
+ ) private pure returns (bool result) {
+ assembly {
+ // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ owner := and(owner, _BITMASK_ADDRESS)
+ // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ msgSender := and(msgSender, _BITMASK_ADDRESS)
+ // `msgSender == owner || msgSender == approvedAddress`.
+ result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
+ }
+ }
+
+ /**
+ * @dev Returns the storage slot and value for the approved address of `tokenId`.
+ */
+ function _getApprovedSlotAndAddress(uint256 tokenId)
+ private
+ view
+ returns (uint256 approvedAddressSlot, address approvedAddress)
+ {
+ ERC721AStorage.TokenApprovalRef storage tokenApproval = ERC721AStorage.layout()._tokenApprovals[tokenId];
+ // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
+ assembly {
+ approvedAddressSlot := tokenApproval.slot
+ approvedAddress := sload(approvedAddressSlot)
+ }
+ }
+
+ // =============================================================
+ // TRANSFER OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Transfers `tokenId` from `from` to `to`.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must be owned by `from`.
+ * - If the caller is not `from`, it must be approved to move this token
+ * by either {approve} or {setApprovalForAll}.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(
+ address from,
+ address to,
+ uint256 tokenId
+ ) public payable virtual override {
+ uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
+
+ // Mask `from` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ from = address(uint160(uint256(uint160(from)) & _BITMASK_ADDRESS));
+
+ if (address(uint160(prevOwnershipPacked)) != from) _revert(TransferFromIncorrectOwner.selector);
+
+ (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
+
+ // The nested ifs save around 20+ gas over a compound boolean condition.
+ if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
+ if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector);
+
+ _beforeTokenTransfers(from, to, tokenId, 1);
+
+ // Clear approvals from the previous owner.
+ assembly {
+ if approvedAddress {
+ // This is equivalent to `delete _tokenApprovals[tokenId]`.
+ sstore(approvedAddressSlot, 0)
+ }
+ }
+
+ // Underflow of the sender's balance is impossible because we check for
+ // ownership above and the recipient's balance can't realistically overflow.
+ // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
+ unchecked {
+ // We can directly increment and decrement the balances.
+ --ERC721AStorage.layout()._packedAddressData[from]; // Updates: `balance -= 1`.
+ ++ERC721AStorage.layout()._packedAddressData[to]; // Updates: `balance += 1`.
+
+ // Updates:
+ // - `address` to the next owner.
+ // - `startTimestamp` to the timestamp of transfering.
+ // - `burned` to `false`.
+ // - `nextInitialized` to `true`.
+ ERC721AStorage.layout()._packedOwnerships[tokenId] = _packOwnershipData(
+ to,
+ _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
+ );
+
+ // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
+ if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
+ uint256 nextTokenId = tokenId + 1;
+ // If the next slot's address is zero and not burned (i.e. packed value is zero).
+ if (ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0) {
+ // If the next slot is within bounds.
+ if (nextTokenId != ERC721AStorage.layout()._currentIndex) {
+ // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
+ ERC721AStorage.layout()._packedOwnerships[nextTokenId] = prevOwnershipPacked;
+ }
+ }
+ }
+ }
+
+ // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
+ assembly {
+ // Emit the `Transfer` event.
+ log4(
+ 0, // Start of data (0, since no data).
+ 0, // End of data (0, since no data).
+ _TRANSFER_EVENT_SIGNATURE, // Signature.
+ from, // `from`.
+ toMasked, // `to`.
+ tokenId // `tokenId`.
+ )
+ }
+ if (toMasked == 0) _revert(TransferToZeroAddress.selector);
+
+ _afterTokenTransfers(from, to, tokenId, 1);
+ }
+
+ /**
+ * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 tokenId
+ ) public payable virtual override {
+ safeTransferFrom(from, to, tokenId, "");
+ }
+
+ /**
+ * @dev Safely transfers `tokenId` token from `from` to `to`.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must exist and be owned by `from`.
+ * - If the caller is not `from`, it must be approved to move this token
+ * by either {approve} or {setApprovalForAll}.
+ * - If `to` refers to a smart contract, it must implement
+ * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 tokenId,
+ bytes memory _data
+ ) public payable virtual override {
+ transferFrom(from, to, tokenId);
+ if (to.code.length != 0)
+ if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
+ _revert(TransferToNonERC721ReceiverImplementer.selector);
+ }
+ }
+
+ /**
+ * @dev Hook that is called before a set of serially-ordered token IDs
+ * are about to be transferred. This includes minting.
+ * And also called before burning one token.
+ *
+ * `startTokenId` - the first token ID to be transferred.
+ * `quantity` - the amount to be transferred.
+ *
+ * Calling conditions:
+ *
+ * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
+ * transferred to `to`.
+ * - When `from` is zero, `tokenId` will be minted for `to`.
+ * - When `to` is zero, `tokenId` will be burned by `from`.
+ * - `from` and `to` are never both zero.
+ */
+ function _beforeTokenTransfers(
+ address from,
+ address to,
+ uint256 startTokenId,
+ uint256 quantity
+ ) internal virtual {}
+
+ /**
+ * @dev Hook that is called after a set of serially-ordered token IDs
+ * have been transferred. This includes minting.
+ * And also called after one token has been burned.
+ *
+ * `startTokenId` - the first token ID to be transferred.
+ * `quantity` - the amount to be transferred.
+ *
+ * Calling conditions:
+ *
+ * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
+ * transferred to `to`.
+ * - When `from` is zero, `tokenId` has been minted for `to`.
+ * - When `to` is zero, `tokenId` has been burned by `from`.
+ * - `from` and `to` are never both zero.
+ */
+ function _afterTokenTransfers(
+ address from,
+ address to,
+ uint256 startTokenId,
+ uint256 quantity
+ ) internal virtual {}
+
+ /**
+ * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
+ *
+ * `from` - Previous owner of the given token ID.
+ * `to` - Target address that will receive the token.
+ * `tokenId` - Token ID to be transferred.
+ * `_data` - Optional data to send along with the call.
+ *
+ * Returns whether the call correctly returned the expected magic value.
+ */
+ function _checkContractOnERC721Received(
+ address from,
+ address to,
+ uint256 tokenId,
+ bytes memory _data
+ ) private returns (bool) {
+ try
+ ERC721A__IERC721ReceiverUpgradeable(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data)
+ returns (bytes4 retval) {
+ return retval == ERC721A__IERC721ReceiverUpgradeable(to).onERC721Received.selector;
+ } catch (bytes memory reason) {
+ if (reason.length == 0) {
+ _revert(TransferToNonERC721ReceiverImplementer.selector);
+ }
+ assembly {
+ revert(add(32, reason), mload(reason))
+ }
+ }
+ }
+
+ // =============================================================
+ // MINT OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Mints `quantity` tokens and transfers them to `to`.
+ *
+ * Requirements:
+ *
+ * - `to` cannot be the zero address.
+ * - `quantity` must be greater than 0.
+ *
+ * Emits a {Transfer} event for each mint.
+ */
+ function _mint(address to, uint256 quantity) internal virtual {
+ uint256 startTokenId = ERC721AStorage.layout()._currentIndex;
+ if (quantity == 0) _revert(MintZeroQuantity.selector);
+
+ _beforeTokenTransfers(address(0), to, startTokenId, quantity);
+
+ // Overflows are incredibly unrealistic.
+ // `balance` and `numberMinted` have a maximum limit of 2**64.
+ // `tokenId` has a maximum limit of 2**256.
+ unchecked {
+ // Updates:
+ // - `address` to the owner.
+ // - `startTimestamp` to the timestamp of minting.
+ // - `burned` to `false`.
+ // - `nextInitialized` to `quantity == 1`.
+ ERC721AStorage.layout()._packedOwnerships[startTokenId] = _packOwnershipData(
+ to,
+ _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
+ );
+
+ // Updates:
+ // - `balance += quantity`.
+ // - `numberMinted += quantity`.
+ //
+ // We can directly add to the `balance` and `numberMinted`.
+ ERC721AStorage.layout()._packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
+
+ // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
+ uint256 toMasked = uint256(uint160(to)) & _BITMASK_ADDRESS;
+
+ if (toMasked == 0) _revert(MintToZeroAddress.selector);
+
+ uint256 end = startTokenId + quantity;
+ uint256 tokenId = startTokenId;
+
+ do {
+ assembly {
+ // Emit the `Transfer` event.
+ log4(
+ 0, // Start of data (0, since no data).
+ 0, // End of data (0, since no data).
+ _TRANSFER_EVENT_SIGNATURE, // Signature.
+ 0, // `address(0)`.
+ toMasked, // `to`.
+ tokenId // `tokenId`.
+ )
+ }
+ // The `!=` check ensures that large values of `quantity`
+ // that overflows uint256 will make the loop run out of gas.
+ } while (++tokenId != end);
+
+ ERC721AStorage.layout()._currentIndex = end;
+ }
+ _afterTokenTransfers(address(0), to, startTokenId, quantity);
+ }
+
+ /**
+ * @dev Mints `quantity` tokens and transfers them to `to`.
+ *
+ * This function is intended for efficient minting only during contract creation.
+ *
+ * It emits only one {ConsecutiveTransfer} as defined in
+ * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
+ * instead of a sequence of {Transfer} event(s).
+ *
+ * Calling this function outside of contract creation WILL make your contract
+ * non-compliant with the ERC721 standard.
+ * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
+ * {ConsecutiveTransfer} event is only permissible during contract creation.
+ *
+ * Requirements:
+ *
+ * - `to` cannot be the zero address.
+ * - `quantity` must be greater than 0.
+ *
+ * Emits a {ConsecutiveTransfer} event.
+ */
+ function _mintERC2309(address to, uint256 quantity) internal virtual {
+ uint256 startTokenId = ERC721AStorage.layout()._currentIndex;
+ if (to == address(0)) _revert(MintToZeroAddress.selector);
+ if (quantity == 0) _revert(MintZeroQuantity.selector);
+ if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) _revert(MintERC2309QuantityExceedsLimit.selector);
+
+ _beforeTokenTransfers(address(0), to, startTokenId, quantity);
+
+ // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
+ unchecked {
+ // Updates:
+ // - `balance += quantity`.
+ // - `numberMinted += quantity`.
+ //
+ // We can directly add to the `balance` and `numberMinted`.
+ ERC721AStorage.layout()._packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);
+
+ // Updates:
+ // - `address` to the owner.
+ // - `startTimestamp` to the timestamp of minting.
+ // - `burned` to `false`.
+ // - `nextInitialized` to `quantity == 1`.
+ ERC721AStorage.layout()._packedOwnerships[startTokenId] = _packOwnershipData(
+ to,
+ _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
+ );
+
+ emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);
+
+ ERC721AStorage.layout()._currentIndex = startTokenId + quantity;
+ }
+ _afterTokenTransfers(address(0), to, startTokenId, quantity);
+ }
+
+ /**
+ * @dev Safely mints `quantity` tokens and transfers them to `to`.
+ *
+ * Requirements:
+ *
+ * - If `to` refers to a smart contract, it must implement
+ * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
+ * - `quantity` must be greater than 0.
+ *
+ * See {_mint}.
+ *
+ * Emits a {Transfer} event for each mint.
+ */
+ function _safeMint(
+ address to,
+ uint256 quantity,
+ bytes memory _data
+ ) internal virtual {
+ _mint(to, quantity);
+
+ unchecked {
+ if (to.code.length != 0) {
+ uint256 end = ERC721AStorage.layout()._currentIndex;
+ uint256 index = end - quantity;
+ do {
+ if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
+ _revert(TransferToNonERC721ReceiverImplementer.selector);
+ }
+ } while (index < end);
+ // Reentrancy protection.
+ if (ERC721AStorage.layout()._currentIndex != end) _revert(bytes4(0));
+ }
+ }
+ }
+
+ /**
+ * @dev Equivalent to `_safeMint(to, quantity, '')`.
+ */
+ function _safeMint(address to, uint256 quantity) internal virtual {
+ _safeMint(to, quantity, "");
+ }
+
+ // =============================================================
+ // APPROVAL OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Equivalent to `_approve(to, tokenId, false)`.
+ */
+ function _approve(address to, uint256 tokenId) internal virtual {
+ _approve(to, tokenId, false);
+ }
+
+ /**
+ * @dev Gives permission to `to` to transfer `tokenId` token to another account.
+ * The approval is cleared when the token is transferred.
+ *
+ * Only a single account can be approved at a time, so approving the
+ * zero address clears previous approvals.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ *
+ * Emits an {Approval} event.
+ */
+ function _approve(
+ address to,
+ uint256 tokenId,
+ bool approvalCheck
+ ) internal virtual {
+ address owner = ownerOf(tokenId);
+
+ if (approvalCheck && _msgSenderERC721A() != owner)
+ if (!isApprovedForAll(owner, _msgSenderERC721A())) {
+ _revert(ApprovalCallerNotOwnerNorApproved.selector);
+ }
+
+ ERC721AStorage.layout()._tokenApprovals[tokenId].value = to;
+ emit Approval(owner, to, tokenId);
+ }
+
+ // =============================================================
+ // BURN OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Equivalent to `_burn(tokenId, false)`.
+ */
+ function _burn(uint256 tokenId) internal virtual {
+ _burn(tokenId, false);
+ }
+
+ /**
+ * @dev Destroys `tokenId`.
+ * The approval is cleared when the token is burned.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ *
+ * Emits a {Transfer} event.
+ */
+ function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
+ uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);
+
+ address from = address(uint160(prevOwnershipPacked));
+
+ (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);
+
+ if (approvalCheck) {
+ // The nested ifs save around 20+ gas over a compound boolean condition.
+ if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
+ if (!isApprovedForAll(from, _msgSenderERC721A())) _revert(TransferCallerNotOwnerNorApproved.selector);
+ }
+
+ _beforeTokenTransfers(from, address(0), tokenId, 1);
+
+ // Clear approvals from the previous owner.
+ assembly {
+ if approvedAddress {
+ // This is equivalent to `delete _tokenApprovals[tokenId]`.
+ sstore(approvedAddressSlot, 0)
+ }
+ }
+
+ // Underflow of the sender's balance is impossible because we check for
+ // ownership above and the recipient's balance can't realistically overflow.
+ // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
+ unchecked {
+ // Updates:
+ // - `balance -= 1`.
+ // - `numberBurned += 1`.
+ //
+ // We can directly decrement the balance, and increment the number burned.
+ // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
+ ERC721AStorage.layout()._packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;
+
+ // Updates:
+ // - `address` to the last owner.
+ // - `startTimestamp` to the timestamp of burning.
+ // - `burned` to `true`.
+ // - `nextInitialized` to `true`.
+ ERC721AStorage.layout()._packedOwnerships[tokenId] = _packOwnershipData(
+ from,
+ (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
+ );
+
+ // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
+ if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
+ uint256 nextTokenId = tokenId + 1;
+ // If the next slot's address is zero and not burned (i.e. packed value is zero).
+ if (ERC721AStorage.layout()._packedOwnerships[nextTokenId] == 0) {
+ // If the next slot is within bounds.
+ if (nextTokenId != ERC721AStorage.layout()._currentIndex) {
+ // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
+ ERC721AStorage.layout()._packedOwnerships[nextTokenId] = prevOwnershipPacked;
+ }
+ }
+ }
+ }
+
+ emit Transfer(from, address(0), tokenId);
+ _afterTokenTransfers(from, address(0), tokenId, 1);
+
+ // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
+ unchecked {
+ ERC721AStorage.layout()._burnCounter++;
+ }
+ }
+
+ // =============================================================
+ // EXTRA DATA OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Directly sets the extra data for the ownership data `index`.
+ */
+ function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
+ uint256 packed = ERC721AStorage.layout()._packedOwnerships[index];
+ if (packed == 0) _revert(OwnershipNotInitializedForExtraData.selector);
+ uint256 extraDataCasted;
+ // Cast `extraData` with assembly to avoid redundant masking.
+ assembly {
+ extraDataCasted := extraData
+ }
+ packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
+ ERC721AStorage.layout()._packedOwnerships[index] = packed;
+ }
+
+ /**
+ * @dev Called during each token transfer to set the 24bit `extraData` field.
+ * Intended to be overridden by the cosumer contract.
+ *
+ * `previousExtraData` - the value of `extraData` before transfer.
+ *
+ * Calling conditions:
+ *
+ * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
+ * transferred to `to`.
+ * - When `from` is zero, `tokenId` will be minted for `to`.
+ * - When `to` is zero, `tokenId` will be burned by `from`.
+ * - `from` and `to` are never both zero.
+ */
+ function _extraData(
+ address from,
+ address to,
+ uint24 previousExtraData
+ ) internal view virtual returns (uint24) {}
+
+ /**
+ * @dev Returns the next extra data for the packed ownership data.
+ * The returned result is shifted into position.
+ */
+ function _nextExtraData(
+ address from,
+ address to,
+ uint256 prevOwnershipPacked
+ ) private view returns (uint256) {
+ uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
+ return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
+ }
+
+ // =============================================================
+ // OTHER OPERATIONS
+ // =============================================================
+
+ /**
+ * @dev Returns the message sender (defaults to `msg.sender`).
+ *
+ * If you are writing GSN compatible contracts, you need to override this function.
+ */
+ function _msgSenderERC721A() internal view virtual returns (address) {
+ return msg.sender;
+ }
+
+ /**
+ * @dev Converts a uint256 to its ASCII string decimal representation.
+ */
+ function _toString(uint256 value) internal pure virtual returns (string memory str) {
+ assembly {
+ // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
+ // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
+ // We will need 1 word for the trailing zeros padding, 1 word for the length,
+ // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
+ let m := add(mload(0x40), 0xa0)
+ // Update the free memory pointer to allocate.
+ mstore(0x40, m)
+ // Assign the `str` to the end.
+ str := sub(m, 0x20)
+ // Zeroize the slot after the string.
+ mstore(str, 0)
+
+ // Cache the end of the memory to calculate the length later.
+ let end := str
+
+ // We write the string from rightmost digit to leftmost digit.
+ // The following is essentially a do-while loop that also handles the zero case.
+ // prettier-ignore
+ for { let temp := value } 1 {} {
+ str := sub(str, 1)
+ // Write the character to the pointer.
+ // The ASCII index of the '0' character is 48.
+ mstore8(str, add(48, mod(temp, 10)))
+ // Keep dividing `temp` until zero.
+ temp := div(temp, 10)
+ // prettier-ignore
+ if iszero(temp) { break }
+ }
+
+ let length := sub(end, str)
+ // Move the pointer 32 bytes leftwards to make room for the length.
+ str := sub(str, 0x20)
+ // Store the length.
+ mstore(str, length)
+ }
+ }
+
+ /**
+ * @dev For more efficient reverts.
+ */
+ function _revert(bytes4 errorSelector) internal pure {
+ assembly {
+ mstore(0x00, errorSelector)
+ revert(0x00, 0x04)
+ }
+ }
+}
diff --git a/contracts/eip/queryable/ERC721A__Initializable.sol b/contracts/eip/queryable/ERC721A__Initializable.sol
new file mode 100644
index 000000000..feba56ea7
--- /dev/null
+++ b/contracts/eip/queryable/ERC721A__Initializable.sol
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+/**
+ * @dev This is a base contract to aid in writing upgradeable diamond facet contracts, or any kind of contract that will be deployed
+ * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
+ * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
+ * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
+ *
+ * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
+ * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
+ *
+ * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
+ * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
+ */
+
+import { ERC721A__InitializableStorage } from "./ERC721A__InitializableStorage.sol";
+
+abstract contract ERC721A__Initializable {
+ using ERC721A__InitializableStorage for ERC721A__InitializableStorage.Layout;
+
+ /**
+ * @dev Modifier to protect an initializer function from being invoked twice.
+ */
+ modifier initializerERC721A() {
+ // If the contract is initializing we ignore whether _initialized is set in order to support multiple
+ // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the
+ // contract may have been reentered.
+ require(
+ ERC721A__InitializableStorage.layout()._initializing
+ ? _isConstructor()
+ : !ERC721A__InitializableStorage.layout()._initialized,
+ "ERC721A__Initializable: contract is already initialized"
+ );
+
+ bool isTopLevelCall = !ERC721A__InitializableStorage.layout()._initializing;
+ if (isTopLevelCall) {
+ ERC721A__InitializableStorage.layout()._initializing = true;
+ ERC721A__InitializableStorage.layout()._initialized = true;
+ }
+
+ _;
+
+ if (isTopLevelCall) {
+ ERC721A__InitializableStorage.layout()._initializing = false;
+ }
+ }
+
+ /**
+ * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
+ * {initializer} modifier, directly or indirectly.
+ */
+ modifier onlyInitializingERC721A() {
+ require(
+ ERC721A__InitializableStorage.layout()._initializing,
+ "ERC721A__Initializable: contract is not initializing"
+ );
+ _;
+ }
+
+ /// @dev Returns true if and only if the function is running in the constructor
+ function _isConstructor() private view returns (bool) {
+ // extcodesize checks the size of the code stored in an address, and
+ // address returns the current address. Since the code is still not
+ // deployed when running a constructor, any checks on its code size will
+ // yield zero, making it an effective way to detect if a contract is
+ // under construction or not.
+ address self = address(this);
+ uint256 cs;
+ assembly {
+ cs := extcodesize(self)
+ }
+ return cs == 0;
+ }
+}
diff --git a/contracts/eip/queryable/ERC721A__InitializableStorage.sol b/contracts/eip/queryable/ERC721A__InitializableStorage.sol
new file mode 100644
index 000000000..6b649b7b1
--- /dev/null
+++ b/contracts/eip/queryable/ERC721A__InitializableStorage.sol
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT
+
+pragma solidity ^0.8.0;
+
+/**
+ * @dev This is a base storage for the initialization function for upgradeable diamond facet contracts
+ **/
+
+library ERC721A__InitializableStorage {
+ struct Layout {
+ /*
+ * Indicates that the contract has been initialized.
+ */
+ bool _initialized;
+ /*
+ * Indicates that the contract is in the process of being initialized.
+ */
+ bool _initializing;
+ }
+
+ bytes32 internal constant STORAGE_SLOT = keccak256("ERC721A.contracts.storage.initializable.facet");
+
+ function layout() internal pure returns (Layout storage l) {
+ bytes32 slot = STORAGE_SLOT;
+ assembly {
+ l.slot := slot
+ }
+ }
+}
diff --git a/contracts/eip/queryable/IERC721AQueryableUpgradeable.sol b/contracts/eip/queryable/IERC721AQueryableUpgradeable.sol
new file mode 100644
index 000000000..c606624bb
--- /dev/null
+++ b/contracts/eip/queryable/IERC721AQueryableUpgradeable.sol
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: MIT
+// ERC721A Contracts v4.2.3
+// Creator: Chiru Labs
+
+pragma solidity ^0.8.4;
+
+import "./IERC721AUpgradeable.sol";
+
+/**
+ * @dev Interface of ERC721AQueryable.
+ */
+interface IERC721AQueryableUpgradeable is IERC721AUpgradeable {
+ /**
+ * Invalid query range (`start` >= `stop`).
+ */
+ error InvalidQueryRange();
+
+ /**
+ * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
+ *
+ * If the `tokenId` is out of bounds:
+ *
+ * - `addr = address(0)`
+ * - `startTimestamp = 0`
+ * - `burned = false`
+ * - `extraData = 0`
+ *
+ * If the `tokenId` is burned:
+ *
+ * - `addr = `
+ * - `startTimestamp = `
+ * - `burned = true`
+ * - `extraData = `
+ *
+ * Otherwise:
+ *
+ * - `addr = `
+ * - `startTimestamp = `
+ * - `burned = false`
+ * - `extraData = `
+ */
+ function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);
+
+ /**
+ * @dev Returns an array of token IDs owned by `owner`,
+ * in the range [`start`, `stop`)
+ * (i.e. `start <= tokenId < stop`).
+ *
+ * This function allows for tokens to be queried if the collection
+ * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
+ *
+ * Requirements:
+ *
+ * - `start < stop`
+ */
+ function tokensOfOwnerIn(
+ address owner,
+ uint256 start,
+ uint256 stop
+ ) external view returns (uint256[] memory);
+
+ /**
+ * @dev Returns an array of token IDs owned by `owner`.
+ *
+ * This function scans the ownership mapping and is O(`totalSupply`) in complexity.
+ * It is meant to be called off-chain.
+ *
+ * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
+ * multiple smaller scans if the collection is large enough to cause
+ * an out-of-gas error (10K collections should be fine).
+ */
+ function tokensOfOwner(address owner) external view returns (uint256[] memory);
+}
diff --git a/contracts/eip/queryable/IERC721AUpgradeable.sol b/contracts/eip/queryable/IERC721AUpgradeable.sol
new file mode 100644
index 000000000..15058be66
--- /dev/null
+++ b/contracts/eip/queryable/IERC721AUpgradeable.sol
@@ -0,0 +1,282 @@
+// SPDX-License-Identifier: MIT
+// ERC721A Contracts v4.2.3
+// Creator: Chiru Labs
+
+pragma solidity ^0.8.4;
+
+/**
+ * @dev Interface of ERC721A.
+ */
+interface IERC721AUpgradeable {
+ /**
+ * The caller must own the token or be an approved operator.
+ */
+ error ApprovalCallerNotOwnerNorApproved();
+
+ /**
+ * The token does not exist.
+ */
+ error ApprovalQueryForNonexistentToken();
+
+ /**
+ * Cannot query the balance for the zero address.
+ */
+ error BalanceQueryForZeroAddress();
+
+ /**
+ * Cannot mint to the zero address.
+ */
+ error MintToZeroAddress();
+
+ /**
+ * The quantity of tokens minted must be more than zero.
+ */
+ error MintZeroQuantity();
+
+ /**
+ * The token does not exist.
+ */
+ error OwnerQueryForNonexistentToken();
+
+ /**
+ * The caller must own the token or be an approved operator.
+ */
+ error TransferCallerNotOwnerNorApproved();
+
+ /**
+ * The token must be owned by `from`.
+ */
+ error TransferFromIncorrectOwner();
+
+ /**
+ * Cannot safely transfer to a contract that does not implement the
+ * ERC721Receiver interface.
+ */
+ error TransferToNonERC721ReceiverImplementer();
+
+ /**
+ * Cannot transfer to the zero address.
+ */
+ error TransferToZeroAddress();
+
+ /**
+ * The token does not exist.
+ */
+ error URIQueryForNonexistentToken();
+
+ /**
+ * The `quantity` minted with ERC2309 exceeds the safety limit.
+ */
+ error MintERC2309QuantityExceedsLimit();
+
+ /**
+ * The `extraData` cannot be set on an unintialized ownership slot.
+ */
+ error OwnershipNotInitializedForExtraData();
+
+ // =============================================================
+ // STRUCTS
+ // =============================================================
+
+ struct TokenOwnership {
+ // The address of the owner.
+ address addr;
+ // Stores the start time of ownership with minimal overhead for tokenomics.
+ uint64 startTimestamp;
+ // Whether the token has been burned.
+ bool burned;
+ // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
+ uint24 extraData;
+ }
+
+ // =============================================================
+ // TOKEN COUNTERS
+ // =============================================================
+
+ /**
+ * @dev Returns the total number of tokens in existence.
+ * Burned tokens will reduce the count.
+ * To get the total number of tokens minted, please see {_totalMinted}.
+ */
+ function totalSupply() external view returns (uint256);
+
+ // =============================================================
+ // IERC165
+ // =============================================================
+
+ /**
+ * @dev Returns true if this contract implements the interface defined by
+ * `interfaceId`. See the corresponding
+ * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
+ * to learn more about how these ids are created.
+ *
+ * This function call must use less than 30000 gas.
+ */
+ function supportsInterface(bytes4 interfaceId) external view returns (bool);
+
+ // =============================================================
+ // IERC721
+ // =============================================================
+
+ /**
+ * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
+ */
+ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
+
+ /**
+ * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
+ */
+ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
+
+ /**
+ * @dev Emitted when `owner` enables or disables
+ * (`approved`) `operator` to manage all of its assets.
+ */
+ event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
+
+ /**
+ * @dev Returns the number of tokens in `owner`'s account.
+ */
+ function balanceOf(address owner) external view returns (uint256 balance);
+
+ /**
+ * @dev Returns the owner of the `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function ownerOf(uint256 tokenId) external view returns (address owner);
+
+ /**
+ * @dev Safely transfers `tokenId` token from `from` to `to`,
+ * checking first that contract recipients are aware of the ERC721 protocol
+ * to prevent tokens from being forever locked.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must exist and be owned by `from`.
+ * - If the caller is not `from`, it must be have been allowed to move
+ * this token by either {approve} or {setApprovalForAll}.
+ * - If `to` refers to a smart contract, it must implement
+ * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
+ *
+ * Emits a {Transfer} event.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 tokenId,
+ bytes calldata data
+ ) external payable;
+
+ /**
+ * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
+ */
+ function safeTransferFrom(
+ address from,
+ address to,
+ uint256 tokenId
+ ) external payable;
+
+ /**
+ * @dev Transfers `tokenId` from `from` to `to`.
+ *
+ * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
+ * whenever possible.
+ *
+ * Requirements:
+ *
+ * - `from` cannot be the zero address.
+ * - `to` cannot be the zero address.
+ * - `tokenId` token must be owned by `from`.
+ * - If the caller is not `from`, it must be approved to move this token
+ * by either {approve} or {setApprovalForAll}.
+ *
+ * Emits a {Transfer} event.
+ */
+ function transferFrom(
+ address from,
+ address to,
+ uint256 tokenId
+ ) external payable;
+
+ /**
+ * @dev Gives permission to `to` to transfer `tokenId` token to another account.
+ * The approval is cleared when the token is transferred.
+ *
+ * Only a single account can be approved at a time, so approving the
+ * zero address clears previous approvals.
+ *
+ * Requirements:
+ *
+ * - The caller must own the token or be an approved operator.
+ * - `tokenId` must exist.
+ *
+ * Emits an {Approval} event.
+ */
+ function approve(address to, uint256 tokenId) external payable;
+
+ /**
+ * @dev Approve or remove `operator` as an operator for the caller.
+ * Operators can call {transferFrom} or {safeTransferFrom}
+ * for any token owned by the caller.
+ *
+ * Requirements:
+ *
+ * - The `operator` cannot be the caller.
+ *
+ * Emits an {ApprovalForAll} event.
+ */
+ function setApprovalForAll(address operator, bool _approved) external;
+
+ /**
+ * @dev Returns the account approved for `tokenId` token.
+ *
+ * Requirements:
+ *
+ * - `tokenId` must exist.
+ */
+ function getApproved(uint256 tokenId) external view returns (address operator);
+
+ /**
+ * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
+ *
+ * See {setApprovalForAll}.
+ */
+ function isApprovedForAll(address owner, address operator) external view returns (bool);
+
+ // =============================================================
+ // IERC721Metadata
+ // =============================================================
+
+ /**
+ * @dev Returns the token collection name.
+ */
+ function name() external view returns (string memory);
+
+ /**
+ * @dev Returns the token collection symbol.
+ */
+ function symbol() external view returns (string memory);
+
+ /**
+ * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
+ */
+ function tokenURI(uint256 tokenId) external view returns (string memory);
+
+ // =============================================================
+ // IERC2309
+ // =============================================================
+
+ /**
+ * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
+ * (inclusive) is transferred from `from` to `to`, as defined in the
+ * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
+ *
+ * See {_mintERC2309} for more details.
+ */
+ event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
+}
diff --git a/contracts/extension/SharedMetadata.sol b/contracts/extension/SharedMetadata.sol
index ce29526e3..0498ed187 100644
--- a/contracts/extension/SharedMetadata.sol
+++ b/contracts/extension/SharedMetadata.sol
@@ -5,8 +5,9 @@ pragma solidity ^0.8.10;
import "../lib/NFTMetadataRendererLib.sol";
import "./interface/ISharedMetadata.sol";
+import "../eip/interface/IERC4906.sol";
-abstract contract SharedMetadata is ISharedMetadata {
+abstract contract SharedMetadata is ISharedMetadata, IERC4906 {
/// @notice Token metadata information
SharedMetadataInfo public sharedMetadata;
@@ -30,6 +31,8 @@ abstract contract SharedMetadata is ISharedMetadata {
animationURI: _metadata.animationURI
});
+ emit BatchMetadataUpdate(0, type(uint256).max);
+
emit SharedMetadataUpdated({
name: _metadata.name,
description: _metadata.description,
diff --git a/contracts/extension/Staking1155.sol b/contracts/extension/Staking1155.sol
index ef0c169a7..22bd39a2d 100644
--- a/contracts/extension/Staking1155.sol
+++ b/contracts/extension/Staking1155.sol
@@ -21,7 +21,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
uint8 internal isStaking = 1;
///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextDefaultConditionId;
+ uint64 private nextDefaultConditionId;
///@dev List of token-ids ever staked.
uint256[] public indexedTokens;
@@ -30,16 +30,16 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
mapping(uint256 => bool) public isIndexed;
///@dev Mapping from default condition-id to default condition.
- mapping(uint256 => StakingCondition) private defaultCondition;
+ mapping(uint64 => StakingCondition) private defaultCondition;
///@dev Mapping from token-id to next staking condition Id for the token. Tracks number of conditon updates so far.
- mapping(uint256 => uint256) private nextConditionId;
+ mapping(uint256 => uint64) private nextConditionId;
///@dev Mapping from token-id and staker address to Staker struct. See {struct IStaking1155.Staker}.
mapping(uint256 => mapping(address => Staker)) public stakers;
///@dev Mapping from token-id and condition Id to staking condition. See {struct IStaking1155.StakingCondition}
- mapping(uint256 => mapping(uint256 => StakingCondition)) private stakingConditions;
+ mapping(uint256 => mapping(uint64 => StakingCondition)) private stakingConditions;
/// @dev Mapping from token-id to list of accounts that have staked that token-id.
mapping(uint256 => address[]) public stakersArray;
@@ -61,7 +61,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
* @param _tokenId ERC1155 token-id to stake.
* @param _amount Amount to stake.
*/
- function stake(uint256 _tokenId, uint256 _amount) external nonReentrant {
+ function stake(uint256 _tokenId, uint64 _amount) external nonReentrant {
_stake(_tokenId, _amount);
}
@@ -73,7 +73,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
* @param _tokenId ERC1155 token-id to withdraw.
* @param _amount Amount to withdraw.
*/
- function withdraw(uint256 _tokenId, uint256 _amount) external nonReentrant {
+ function withdraw(uint256 _tokenId, uint64 _amount) external nonReentrant {
_withdraw(_tokenId, _amount);
}
@@ -99,12 +99,12 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
* @param _tokenId ERC1155 token Id.
* @param _timeUnit New time unit.
*/
- function setTimeUnit(uint256 _tokenId, uint256 _timeUnit) external virtual {
+ function setTimeUnit(uint256 _tokenId, uint80 _timeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
StakingCondition memory condition = _nextConditionId == 0
? defaultCondition[nextDefaultConditionId - 1]
: stakingConditions[_tokenId][_nextConditionId - 1];
@@ -130,7 +130,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
revert("Not authorized");
}
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
StakingCondition memory condition = _nextConditionId == 0
? defaultCondition[nextDefaultConditionId - 1]
: stakingConditions[_tokenId][_nextConditionId - 1];
@@ -149,7 +149,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
*
* @param _defaultTimeUnit New time unit.
*/
- function setDefaultTimeUnit(uint256 _defaultTimeUnit) external virtual {
+ function setDefaultTimeUnit(uint80 _defaultTimeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
@@ -242,13 +242,13 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
}
function getTimeUnit(uint256 _tokenId) public view returns (uint256 _timeUnit) {
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
require(_nextConditionId != 0, "Time unit not set. Check default time unit.");
_timeUnit = stakingConditions[_tokenId][_nextConditionId - 1].timeUnit;
}
function getRewardsPerUnitTime(uint256 _tokenId) public view returns (uint256 _rewardsPerUnitTime) {
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
require(_nextConditionId != 0, "Rewards not set. Check default rewards.");
_rewardsPerUnitTime = stakingConditions[_tokenId][_nextConditionId - 1].rewardsPerUnitTime;
}
@@ -266,29 +266,25 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
//////////////////////////////////////////////////////////////*/
/// @dev Staking logic. Override to add custom logic.
- function _stake(uint256 _tokenId, uint256 _amount) internal virtual {
+ function _stake(uint256 _tokenId, uint64 _amount) internal virtual {
require(_amount != 0, "Staking 0 tokens");
- address _stakingToken = stakingToken;
if (stakers[_tokenId][_stakeMsgSender()].amountStaked > 0) {
_updateUnclaimedRewardsForStaker(_tokenId, _stakeMsgSender());
} else {
stakersArray[_tokenId].push(_stakeMsgSender());
- stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
- uint256 _conditionId = nextConditionId[_tokenId];
- stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
- ? nextDefaultConditionId - 1
- : _conditionId - 1;
+ uint64 _conditionId = nextConditionId[_tokenId];
+ unchecked {
+ stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
+ ? nextDefaultConditionId - 1
+ : _conditionId - 1;
+ }
}
- require(
- IERC1155(_stakingToken).balanceOf(_stakeMsgSender(), _tokenId) >= _amount &&
- IERC1155(_stakingToken).isApprovedForAll(_stakeMsgSender(), address(this)),
- "Not balance or approved"
- );
isStaking = 2;
- IERC1155(_stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenId, _amount, "");
+ IERC1155(stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenId, _amount, "");
isStaking = 1;
// stakerAddress[_tokenIds[i]] = _stakeMsgSender();
stakers[_tokenId][_stakeMsgSender()].amountStaked += _amount;
@@ -302,7 +298,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
}
/// @dev Withdraw logic. Override to add custom logic.
- function _withdraw(uint256 _tokenId, uint256 _amount) internal virtual {
+ function _withdraw(uint256 _tokenId, uint64 _amount) internal virtual {
uint256 _amountStaked = stakers[_tokenId][_stakeMsgSender()].amountStaked;
require(_amount != 0, "Withdrawing 0 tokens");
require(_amountStaked >= _amount, "Withdrawing more than staked");
@@ -333,13 +329,16 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
require(rewards != 0, "No rewards");
- stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_tokenId][_stakeMsgSender()].unclaimedRewards = 0;
- uint256 _conditionId = nextConditionId[_tokenId];
- stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
- ? nextDefaultConditionId - 1
- : _conditionId - 1;
+ uint64 _conditionId = nextConditionId[_tokenId];
+
+ unchecked {
+ stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
+ ? nextDefaultConditionId - 1
+ : _conditionId - 1;
+ }
_mintRewards(_stakeMsgSender(), rewards);
@@ -359,25 +358,27 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
function _updateUnclaimedRewardsForStaker(uint256 _tokenId, address _staker) internal virtual {
uint256 rewards = _calculateRewards(_tokenId, _staker);
stakers[_tokenId][_staker].unclaimedRewards += rewards;
- stakers[_tokenId][_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_staker].timeOfLastUpdate = uint80(block.timestamp);
- uint256 _conditionId = nextConditionId[_tokenId];
- stakers[_tokenId][_staker].conditionIdOflastUpdate = _conditionId == 0
- ? nextDefaultConditionId - 1
- : _conditionId - 1;
+ uint64 _conditionId = nextConditionId[_tokenId];
+ unchecked {
+ stakers[_tokenId][_staker].conditionIdOflastUpdate = _conditionId == 0
+ ? nextDefaultConditionId - 1
+ : _conditionId - 1;
+ }
}
/// @dev Set staking conditions, for a token-Id.
function _setStakingCondition(
uint256 _tokenId,
- uint256 _timeUnit,
+ uint80 _timeUnit,
uint256 _rewardsPerUnitTime
) internal virtual {
require(_timeUnit != 0, "time-unit can't be 0");
- uint256 conditionId = nextConditionId[_tokenId];
+ uint64 conditionId = nextConditionId[_tokenId];
if (conditionId == 0) {
- uint256 _nextDefaultConditionId = nextDefaultConditionId;
+ uint64 _nextDefaultConditionId = nextDefaultConditionId;
for (; conditionId < _nextDefaultConditionId; conditionId += 1) {
StakingCondition memory _defaultCondition = defaultCondition[conditionId];
@@ -390,12 +391,12 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
}
}
- stakingConditions[_tokenId][conditionId - 1].endTimestamp = block.timestamp;
+ stakingConditions[_tokenId][conditionId - 1].endTimestamp = uint80(block.timestamp);
stakingConditions[_tokenId][conditionId] = StakingCondition({
timeUnit: _timeUnit,
rewardsPerUnitTime: _rewardsPerUnitTime,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
@@ -403,33 +404,33 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
}
/// @dev Set default staking conditions.
- function _setDefaultStakingCondition(uint256 _timeUnit, uint256 _rewardsPerUnitTime) internal virtual {
+ function _setDefaultStakingCondition(uint80 _timeUnit, uint256 _rewardsPerUnitTime) internal virtual {
require(_timeUnit != 0, "time-unit can't be 0");
- uint256 conditionId = nextDefaultConditionId;
+ uint64 conditionId = nextDefaultConditionId;
nextDefaultConditionId += 1;
defaultCondition[conditionId] = StakingCondition({
timeUnit: _timeUnit,
rewardsPerUnitTime: _rewardsPerUnitTime,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
if (conditionId > 0) {
- defaultCondition[conditionId - 1].endTimestamp = block.timestamp;
+ defaultCondition[conditionId - 1].endTimestamp = uint80(block.timestamp);
}
}
/// @dev Reward calculation logic. Override to implement custom logic.
function _calculateRewards(uint256 _tokenId, address _staker) internal view virtual returns (uint256 _rewards) {
Staker memory staker = stakers[_tokenId][_staker];
- uint256 _stakerConditionId = staker.conditionIdOflastUpdate;
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _stakerConditionId = staker.conditionIdOflastUpdate;
+ uint64 _nextConditionId = nextConditionId[_tokenId];
if (_nextConditionId == 0) {
_nextConditionId = nextDefaultConditionId;
- for (uint256 i = _stakerConditionId; i < _nextConditionId; i += 1) {
+ for (uint64 i = _stakerConditionId; i < _nextConditionId; i += 1) {
StakingCondition memory condition = defaultCondition[i];
uint256 startTime = i != _stakerConditionId ? condition.startTimestamp : staker.timeOfLastUpdate;
@@ -447,7 +448,7 @@ abstract contract Staking1155 is ReentrancyGuard, IStaking1155 {
_rewards = noOverflowProduct && noOverflowSum ? rewardsSum : _rewards;
}
} else {
- for (uint256 i = _stakerConditionId; i < _nextConditionId; i += 1) {
+ for (uint64 i = _stakerConditionId; i < _nextConditionId; i += 1) {
StakingCondition memory condition = stakingConditions[_tokenId][i];
uint256 startTime = i != _stakerConditionId ? condition.startTimestamp : staker.timeOfLastUpdate;
diff --git a/contracts/extension/Staking1155Upgradeable.sol b/contracts/extension/Staking1155Upgradeable.sol
index cb5e47a40..fcfa593b3 100644
--- a/contracts/extension/Staking1155Upgradeable.sol
+++ b/contracts/extension/Staking1155Upgradeable.sol
@@ -21,7 +21,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
uint8 internal isStaking = 1;
///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextDefaultConditionId;
+ uint64 private nextDefaultConditionId;
///@dev List of token-ids ever staked.
uint256[] public indexedTokens;
@@ -30,16 +30,16 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
mapping(uint256 => bool) public isIndexed;
///@dev Mapping from default condition-id to default condition.
- mapping(uint256 => StakingCondition) private defaultCondition;
+ mapping(uint64 => StakingCondition) private defaultCondition;
///@dev Mapping from token-id to next staking condition Id for the token. Tracks number of conditon updates so far.
- mapping(uint256 => uint256) private nextConditionId;
+ mapping(uint256 => uint64) private nextConditionId;
///@dev Mapping from token-id and staker address to Staker struct. See {struct IStaking1155.Staker}.
mapping(uint256 => mapping(address => Staker)) public stakers;
///@dev Mapping from token-id and condition Id to staking condition. See {struct IStaking1155.StakingCondition}
- mapping(uint256 => mapping(uint256 => StakingCondition)) private stakingConditions;
+ mapping(uint256 => mapping(uint64 => StakingCondition)) private stakingConditions;
/// @dev Mapping from token-id to list of accounts that have staked that token-id.
mapping(uint256 => address[]) public stakersArray;
@@ -63,7 +63,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
* @param _tokenId ERC1155 token-id to stake.
* @param _amount Amount to stake.
*/
- function stake(uint256 _tokenId, uint256 _amount) external nonReentrant {
+ function stake(uint256 _tokenId, uint64 _amount) external nonReentrant {
_stake(_tokenId, _amount);
}
@@ -75,7 +75,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
* @param _tokenId ERC1155 token-id to withdraw.
* @param _amount Amount to withdraw.
*/
- function withdraw(uint256 _tokenId, uint256 _amount) external nonReentrant {
+ function withdraw(uint256 _tokenId, uint64 _amount) external nonReentrant {
_withdraw(_tokenId, _amount);
}
@@ -101,12 +101,12 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
* @param _tokenId ERC1155 token Id.
* @param _timeUnit New time unit.
*/
- function setTimeUnit(uint256 _tokenId, uint256 _timeUnit) external virtual {
+ function setTimeUnit(uint256 _tokenId, uint80 _timeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
StakingCondition memory condition = _nextConditionId == 0
? defaultCondition[nextDefaultConditionId - 1]
: stakingConditions[_tokenId][_nextConditionId - 1];
@@ -132,7 +132,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
revert("Not authorized");
}
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
StakingCondition memory condition = _nextConditionId == 0
? defaultCondition[nextDefaultConditionId - 1]
: stakingConditions[_tokenId][_nextConditionId - 1];
@@ -151,7 +151,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
*
* @param _defaultTimeUnit New time unit.
*/
- function setDefaultTimeUnit(uint256 _defaultTimeUnit) external virtual {
+ function setDefaultTimeUnit(uint80 _defaultTimeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
@@ -244,13 +244,13 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
}
function getTimeUnit(uint256 _tokenId) public view returns (uint256 _timeUnit) {
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
require(_nextConditionId != 0, "Time unit not set. Check default time unit.");
_timeUnit = stakingConditions[_tokenId][_nextConditionId - 1].timeUnit;
}
function getRewardsPerUnitTime(uint256 _tokenId) public view returns (uint256 _rewardsPerUnitTime) {
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _nextConditionId = nextConditionId[_tokenId];
require(_nextConditionId != 0, "Rewards not set. Check default rewards.");
_rewardsPerUnitTime = stakingConditions[_tokenId][_nextConditionId - 1].rewardsPerUnitTime;
}
@@ -268,29 +268,23 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
//////////////////////////////////////////////////////////////*/
/// @dev Staking logic. Override to add custom logic.
- function _stake(uint256 _tokenId, uint256 _amount) internal virtual {
+ function _stake(uint256 _tokenId, uint64 _amount) internal virtual {
require(_amount != 0, "Staking 0 tokens");
- address _stakingToken = stakingToken;
if (stakers[_tokenId][_stakeMsgSender()].amountStaked > 0) {
_updateUnclaimedRewardsForStaker(_tokenId, _stakeMsgSender());
} else {
stakersArray[_tokenId].push(_stakeMsgSender());
- stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
- uint256 _conditionId = nextConditionId[_tokenId];
+ uint64 _conditionId = nextConditionId[_tokenId];
stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
? nextDefaultConditionId - 1
: _conditionId - 1;
}
- require(
- IERC1155(_stakingToken).balanceOf(_stakeMsgSender(), _tokenId) >= _amount &&
- IERC1155(_stakingToken).isApprovedForAll(_stakeMsgSender(), address(this)),
- "Not balance or approved"
- );
isStaking = 2;
- IERC1155(_stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenId, _amount, "");
+ IERC1155(stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenId, _amount, "");
isStaking = 1;
// stakerAddress[_tokenIds[i]] = _stakeMsgSender();
stakers[_tokenId][_stakeMsgSender()].amountStaked += _amount;
@@ -304,7 +298,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
}
/// @dev Withdraw logic. Override to add custom logic.
- function _withdraw(uint256 _tokenId, uint256 _amount) internal virtual {
+ function _withdraw(uint256 _tokenId, uint64 _amount) internal virtual {
uint256 _amountStaked = stakers[_tokenId][_stakeMsgSender()].amountStaked;
require(_amount != 0, "Withdrawing 0 tokens");
require(_amountStaked >= _amount, "Withdrawing more than staked");
@@ -321,6 +315,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
}
}
}
+
stakers[_tokenId][_stakeMsgSender()].amountStaked -= _amount;
IERC1155(stakingToken).safeTransferFrom(address(this), _stakeMsgSender(), _tokenId, _amount, "");
@@ -335,13 +330,15 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
require(rewards != 0, "No rewards");
- stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_tokenId][_stakeMsgSender()].unclaimedRewards = 0;
- uint256 _conditionId = nextConditionId[_tokenId];
- stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
- ? nextDefaultConditionId - 1
- : _conditionId - 1;
+ uint64 _conditionId = nextConditionId[_tokenId];
+ unchecked {
+ stakers[_tokenId][_stakeMsgSender()].conditionIdOflastUpdate = _conditionId == 0
+ ? nextDefaultConditionId - 1
+ : _conditionId - 1;
+ }
_mintRewards(_stakeMsgSender(), rewards);
@@ -361,22 +358,24 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
function _updateUnclaimedRewardsForStaker(uint256 _tokenId, address _staker) internal virtual {
uint256 rewards = _calculateRewards(_tokenId, _staker);
stakers[_tokenId][_staker].unclaimedRewards += rewards;
- stakers[_tokenId][_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_tokenId][_staker].timeOfLastUpdate = uint80(block.timestamp);
- uint256 _conditionId = nextConditionId[_tokenId];
- stakers[_tokenId][_staker].conditionIdOflastUpdate = _conditionId == 0
- ? nextDefaultConditionId - 1
- : _conditionId - 1;
+ uint64 _conditionId = nextConditionId[_tokenId];
+ unchecked {
+ stakers[_tokenId][_staker].conditionIdOflastUpdate = _conditionId == 0
+ ? nextDefaultConditionId - 1
+ : _conditionId - 1;
+ }
}
/// @dev Set staking conditions, for a token-Id.
function _setStakingCondition(
uint256 _tokenId,
- uint256 _timeUnit,
+ uint80 _timeUnit,
uint256 _rewardsPerUnitTime
) internal virtual {
require(_timeUnit != 0, "time-unit can't be 0");
- uint256 conditionId = nextConditionId[_tokenId];
+ uint64 conditionId = nextConditionId[_tokenId];
if (conditionId == 0) {
uint256 _nextDefaultConditionId = nextDefaultConditionId;
@@ -392,12 +391,12 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
}
}
- stakingConditions[_tokenId][conditionId - 1].endTimestamp = block.timestamp;
+ stakingConditions[_tokenId][conditionId - 1].endTimestamp = uint80(block.timestamp);
stakingConditions[_tokenId][conditionId] = StakingCondition({
timeUnit: _timeUnit,
rewardsPerUnitTime: _rewardsPerUnitTime,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
@@ -405,33 +404,33 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
}
/// @dev Set default staking conditions.
- function _setDefaultStakingCondition(uint256 _timeUnit, uint256 _rewardsPerUnitTime) internal virtual {
+ function _setDefaultStakingCondition(uint80 _timeUnit, uint256 _rewardsPerUnitTime) internal virtual {
require(_timeUnit != 0, "time-unit can't be 0");
- uint256 conditionId = nextDefaultConditionId;
+ uint64 conditionId = nextDefaultConditionId;
nextDefaultConditionId += 1;
defaultCondition[conditionId] = StakingCondition({
timeUnit: _timeUnit,
rewardsPerUnitTime: _rewardsPerUnitTime,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
if (conditionId > 0) {
- defaultCondition[conditionId - 1].endTimestamp = block.timestamp;
+ defaultCondition[conditionId - 1].endTimestamp = uint80(block.timestamp);
}
}
/// @dev Reward calculation logic. Override to implement custom logic.
function _calculateRewards(uint256 _tokenId, address _staker) internal view virtual returns (uint256 _rewards) {
Staker memory staker = stakers[_tokenId][_staker];
- uint256 _stakerConditionId = staker.conditionIdOflastUpdate;
- uint256 _nextConditionId = nextConditionId[_tokenId];
+ uint64 _stakerConditionId = staker.conditionIdOflastUpdate;
+ uint64 _nextConditionId = nextConditionId[_tokenId];
if (_nextConditionId == 0) {
_nextConditionId = nextDefaultConditionId;
- for (uint256 i = _stakerConditionId; i < _nextConditionId; i += 1) {
+ for (uint64 i = _stakerConditionId; i < _nextConditionId; i += 1) {
StakingCondition memory condition = defaultCondition[i];
uint256 startTime = i != _stakerConditionId ? condition.startTimestamp : staker.timeOfLastUpdate;
@@ -449,7 +448,7 @@ abstract contract Staking1155Upgradeable is ReentrancyGuardUpgradeable, IStaking
_rewards = noOverflowProduct && noOverflowSum ? rewardsSum : _rewards;
}
} else {
- for (uint256 i = _stakerConditionId; i < _nextConditionId; i += 1) {
+ for (uint64 i = _stakerConditionId; i < _nextConditionId; i += 1) {
StakingCondition memory condition = stakingConditions[_tokenId][i];
uint256 startTime = i != _stakerConditionId ? condition.startTimestamp : staker.timeOfLastUpdate;
diff --git a/contracts/extension/Staking20.sol b/contracts/extension/Staking20.sol
index 06471adc6..e1dec5bdc 100644
--- a/contracts/extension/Staking20.sol
+++ b/contracts/extension/Staking20.sol
@@ -19,22 +19,22 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
address internal immutable nativeTokenWrapper;
///@dev Address of ERC20 contract -- staked tokens belong to this contract.
- address public stakingToken;
+ address public immutable stakingToken;
/// @dev Decimals of staking token.
- uint256 public stakingTokenDecimals;
+ uint16 public immutable stakingTokenDecimals;
/// @dev Decimals of reward token.
- uint256 public rewardTokenDecimals;
+ uint16 public immutable rewardTokenDecimals;
- /// @dev List of accounts that have staked that token-id.
- address[] public stakersArray;
+ ///@dev Next staking condition Id. Tracks number of conditon updates so far.
+ uint64 private nextConditionId;
/// @dev Total amount of tokens staked in the contract.
uint256 public stakingTokenBalance;
- ///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextConditionId;
+ /// @dev List of accounts that have staked that token-id.
+ address[] public stakersArray;
///@dev Mapping staker address to Staker struct. See {struct IStaking20.Staker}.
mapping(address => Staker) public stakers;
@@ -45,8 +45,8 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
constructor(
address _nativeTokenWrapper,
address _stakingToken,
- uint256 _stakingTokenDecimals,
- uint256 _rewardTokenDecimals
+ uint16 _stakingTokenDecimals,
+ uint16 _rewardTokenDecimals
) ReentrancyGuard() {
require(_stakingToken != address(0) && _nativeTokenWrapper != address(0), "address 0");
require(_stakingTokenDecimals != 0 && _rewardTokenDecimals != 0, "decimals 0");
@@ -101,7 +101,7 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
*
* @param _timeUnit New time unit.
*/
- function setTimeUnit(uint256 _timeUnit) external virtual {
+ function setTimeUnit(uint80 _timeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
@@ -186,7 +186,7 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
_updateUnclaimedRewardsForStaker(_stakeMsgSender());
} else {
stakersArray.push(_stakeMsgSender());
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
}
@@ -244,7 +244,7 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
require(rewards != 0, "No rewards");
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_stakeMsgSender()].unclaimedRewards = 0;
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
@@ -266,13 +266,13 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
function _updateUnclaimedRewardsForStaker(address _staker) internal virtual {
uint256 rewards = _calculateRewards(_staker);
stakers[_staker].unclaimedRewards += rewards;
- stakers[_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_staker].timeOfLastUpdate = uint80(block.timestamp);
stakers[_staker].conditionIdOflastUpdate = nextConditionId - 1;
}
/// @dev Set staking conditions.
function _setStakingCondition(
- uint256 _timeUnit,
+ uint80 _timeUnit,
uint256 _numerator,
uint256 _denominator
) internal virtual {
@@ -285,12 +285,12 @@ abstract contract Staking20 is ReentrancyGuard, IStaking20 {
timeUnit: _timeUnit,
rewardRatioNumerator: _numerator,
rewardRatioDenominator: _denominator,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
if (conditionId > 0) {
- stakingConditions[conditionId - 1].endTimestamp = block.timestamp;
+ stakingConditions[conditionId - 1].endTimestamp = uint80(block.timestamp);
}
}
diff --git a/contracts/extension/Staking20Upgradeable.sol b/contracts/extension/Staking20Upgradeable.sol
index 18a1ad24c..b01ebbfe6 100644
--- a/contracts/extension/Staking20Upgradeable.sol
+++ b/contracts/extension/Staking20Upgradeable.sol
@@ -22,19 +22,19 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
address public stakingToken;
/// @dev Decimals of staking token.
- uint256 public stakingTokenDecimals;
+ uint16 public stakingTokenDecimals;
/// @dev Decimals of reward token.
- uint256 public rewardTokenDecimals;
+ uint16 public rewardTokenDecimals;
- /// @dev List of accounts that have staked that token-id.
- address[] public stakersArray;
+ ///@dev Next staking condition Id. Tracks number of conditon updates so far.
+ uint64 private nextConditionId;
/// @dev Total amount of tokens staked in the contract.
uint256 public stakingTokenBalance;
- ///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextConditionId;
+ /// @dev List of accounts that have staked that token-id.
+ address[] public stakersArray;
///@dev Mapping staker address to Staker struct. See {struct IStaking20.Staker}.
mapping(address => Staker) public stakers;
@@ -50,8 +50,8 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
function __Staking20_init(
address _stakingToken,
- uint256 _stakingTokenDecimals,
- uint256 _rewardTokenDecimals
+ uint16 _stakingTokenDecimals,
+ uint16 _rewardTokenDecimals
) internal onlyInitializing {
__ReentrancyGuard_init();
@@ -107,7 +107,7 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
*
* @param _timeUnit New time unit.
*/
- function setTimeUnit(uint256 _timeUnit) external virtual {
+ function setTimeUnit(uint80 _timeUnit) external virtual {
if (!_canSetStakeConditions()) {
revert("Not authorized");
}
@@ -163,7 +163,7 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
_rewards = _availableRewards(_staker);
}
- function getTimeUnit() public view returns (uint256 _timeUnit) {
+ function getTimeUnit() public view returns (uint80 _timeUnit) {
_timeUnit = stakingConditions[nextConditionId - 1].timeUnit;
}
@@ -192,7 +192,7 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
_updateUnclaimedRewardsForStaker(_stakeMsgSender());
} else {
stakersArray.push(_stakeMsgSender());
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
}
@@ -230,6 +230,7 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
}
}
}
+
stakers[_stakeMsgSender()].amountStaked -= _amount;
stakingTokenBalance -= _amount;
@@ -250,7 +251,7 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
require(rewards != 0, "No rewards");
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint80(block.timestamp);
stakers[_stakeMsgSender()].unclaimedRewards = 0;
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
@@ -272,13 +273,13 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
function _updateUnclaimedRewardsForStaker(address _staker) internal virtual {
uint256 rewards = _calculateRewards(_staker);
stakers[_staker].unclaimedRewards += rewards;
- stakers[_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_staker].timeOfLastUpdate = uint80(block.timestamp);
stakers[_staker].conditionIdOflastUpdate = nextConditionId - 1;
}
/// @dev Set staking conditions.
function _setStakingCondition(
- uint256 _timeUnit,
+ uint80 _timeUnit,
uint256 _numerator,
uint256 _denominator
) internal virtual {
@@ -291,12 +292,12 @@ abstract contract Staking20Upgradeable is ReentrancyGuardUpgradeable, IStaking20
timeUnit: _timeUnit,
rewardRatioNumerator: _numerator,
rewardRatioDenominator: _denominator,
- startTimestamp: block.timestamp,
+ startTimestamp: uint80(block.timestamp),
endTimestamp: 0
});
if (conditionId > 0) {
- stakingConditions[conditionId - 1].endTimestamp = block.timestamp;
+ stakingConditions[conditionId - 1].endTimestamp = uint80(block.timestamp);
}
}
diff --git a/contracts/extension/Staking721.sol b/contracts/extension/Staking721.sol
index e90a34aa1..9224d2e82 100644
--- a/contracts/extension/Staking721.sol
+++ b/contracts/extension/Staking721.sol
@@ -17,18 +17,18 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
///@dev Address of ERC721 NFT contract -- staked tokens belong to this contract.
address public stakingToken;
+ /// @dev Flag to check direct transfers of staking tokens.
+ uint8 internal isStaking = 1;
+
+ ///@dev Next staking condition Id. Tracks number of conditon updates so far.
+ uint64 private nextConditionId;
+
///@dev List of token-ids ever staked.
uint256[] public indexedTokens;
/// @dev List of accounts that have staked their NFTs.
address[] public stakersArray;
- /// @dev Flag to check direct transfers of staking tokens.
- uint8 internal isStaking = 1;
-
- ///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextConditionId;
-
///@dev Mapping from token-id to whether it is indexed or not.
mapping(uint256 => bool) public isIndexed;
@@ -175,7 +175,7 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
/// @dev Staking logic. Override to add custom logic.
function _stake(uint256[] calldata _tokenIds) internal virtual {
- uint256 len = _tokenIds.length;
+ uint64 len = uint64(_tokenIds.length);
require(len != 0, "Staking 0 tokens");
address _stakingToken = stakingToken;
@@ -184,17 +184,10 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
_updateUnclaimedRewardsForStaker(_stakeMsgSender());
} else {
stakersArray.push(_stakeMsgSender());
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint128(block.timestamp);
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
}
for (uint256 i = 0; i < len; ++i) {
- require(
- IERC721(_stakingToken).ownerOf(_tokenIds[i]) == _stakeMsgSender() &&
- (IERC721(_stakingToken).getApproved(_tokenIds[i]) == address(this) ||
- IERC721(_stakingToken).isApprovedForAll(_stakeMsgSender(), address(this))),
- "Not owned or approved"
- );
-
isStaking = 2;
IERC721(_stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenIds[i]);
isStaking = 1;
@@ -214,7 +207,7 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
/// @dev Withdraw logic. Override to add custom logic.
function _withdraw(uint256[] calldata _tokenIds) internal virtual {
uint256 _amountStaked = stakers[_stakeMsgSender()].amountStaked;
- uint256 len = _tokenIds.length;
+ uint64 len = uint64(_tokenIds.length);
require(len != 0, "Withdrawing 0 tokens");
require(_amountStaked >= len, "Withdrawing more than staked");
@@ -249,7 +242,7 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
require(rewards != 0, "No rewards");
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint128(block.timestamp);
stakers[_stakeMsgSender()].unclaimedRewards = 0;
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
@@ -271,7 +264,7 @@ abstract contract Staking721 is ReentrancyGuard, IStaking721 {
function _updateUnclaimedRewardsForStaker(address _staker) internal virtual {
uint256 rewards = _calculateRewards(_staker);
stakers[_staker].unclaimedRewards += rewards;
- stakers[_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_staker].timeOfLastUpdate = uint128(block.timestamp);
stakers[_staker].conditionIdOflastUpdate = nextConditionId - 1;
}
diff --git a/contracts/extension/Staking721Upgradeable.sol b/contracts/extension/Staking721Upgradeable.sol
index 44a92a064..03d748890 100644
--- a/contracts/extension/Staking721Upgradeable.sol
+++ b/contracts/extension/Staking721Upgradeable.sol
@@ -17,18 +17,18 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
///@dev Address of ERC721 NFT contract -- staked tokens belong to this contract.
address public stakingToken;
+ /// @dev Flag to check direct transfers of staking tokens.
+ uint8 internal isStaking = 1;
+
+ ///@dev Next staking condition Id. Tracks number of conditon updates so far.
+ uint64 private nextConditionId;
+
///@dev List of token-ids ever staked.
uint256[] public indexedTokens;
/// @dev List of accounts that have staked their NFTs.
address[] public stakersArray;
- /// @dev Flag to check direct transfers of staking tokens.
- uint8 internal isStaking = 1;
-
- ///@dev Next staking condition Id. Tracks number of conditon updates so far.
- uint256 private nextConditionId;
-
///@dev Mapping from token-id to whether it is indexed or not.
mapping(uint256 => bool) public isIndexed;
@@ -177,7 +177,7 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
/// @dev Staking logic. Override to add custom logic.
function _stake(uint256[] calldata _tokenIds) internal virtual {
- uint256 len = _tokenIds.length;
+ uint64 len = uint64(_tokenIds.length);
require(len != 0, "Staking 0 tokens");
address _stakingToken = stakingToken;
@@ -186,17 +186,10 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
_updateUnclaimedRewardsForStaker(_stakeMsgSender());
} else {
stakersArray.push(_stakeMsgSender());
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint128(block.timestamp);
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
}
for (uint256 i = 0; i < len; ++i) {
- require(
- IERC721(_stakingToken).ownerOf(_tokenIds[i]) == _stakeMsgSender() &&
- (IERC721(_stakingToken).getApproved(_tokenIds[i]) == address(this) ||
- IERC721(_stakingToken).isApprovedForAll(_stakeMsgSender(), address(this))),
- "Not owned or approved"
- );
-
isStaking = 2;
IERC721(_stakingToken).safeTransferFrom(_stakeMsgSender(), address(this), _tokenIds[i]);
isStaking = 1;
@@ -216,7 +209,7 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
/// @dev Withdraw logic. Override to add custom logic.
function _withdraw(uint256[] calldata _tokenIds) internal virtual {
uint256 _amountStaked = stakers[_stakeMsgSender()].amountStaked;
- uint256 len = _tokenIds.length;
+ uint64 len = uint64(_tokenIds.length);
require(len != 0, "Withdrawing 0 tokens");
require(_amountStaked >= len, "Withdrawing more than staked");
@@ -251,7 +244,7 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
require(rewards != 0, "No rewards");
- stakers[_stakeMsgSender()].timeOfLastUpdate = block.timestamp;
+ stakers[_stakeMsgSender()].timeOfLastUpdate = uint128(block.timestamp);
stakers[_stakeMsgSender()].unclaimedRewards = 0;
stakers[_stakeMsgSender()].conditionIdOflastUpdate = nextConditionId - 1;
@@ -273,7 +266,7 @@ abstract contract Staking721Upgradeable is ReentrancyGuardUpgradeable, IStaking7
function _updateUnclaimedRewardsForStaker(address _staker) internal virtual {
uint256 rewards = _calculateRewards(_staker);
stakers[_staker].unclaimedRewards += rewards;
- stakers[_staker].timeOfLastUpdate = block.timestamp;
+ stakers[_staker].timeOfLastUpdate = uint128(block.timestamp);
stakers[_staker].conditionIdOflastUpdate = nextConditionId - 1;
}
diff --git a/contracts/extension/interface/IDrop.sol b/contracts/extension/interface/IDrop.sol
index 6f25e5c83..4e466e6c3 100644
--- a/contracts/extension/interface/IDrop.sol
+++ b/contracts/extension/interface/IDrop.sol
@@ -15,7 +15,7 @@ import "./IClaimConditionMultiPhase.sol";
interface IDrop is IClaimConditionMultiPhase {
/**
- * @param proof Prood of concerned wallet's inclusion in an allowlist.
+ * @param proof Proof of concerned wallet's inclusion in an allowlist.
* @param quantityLimitPerWallet The total quantity of tokens the allowlisted wallet is eligible to claim over time.
* @param pricePerToken The price per token the allowlisted wallet must pay to claim tokens.
* @param currency The currency in which the allowlisted wallet must pay the price for claiming tokens.
diff --git a/contracts/extension/interface/IDrop1155.sol b/contracts/extension/interface/IDrop1155.sol
index a69b73fd9..2a18da17e 100644
--- a/contracts/extension/interface/IDrop1155.sol
+++ b/contracts/extension/interface/IDrop1155.sol
@@ -15,7 +15,7 @@ import "./IClaimConditionMultiPhase.sol";
interface IDrop1155 is IClaimConditionMultiPhase {
/**
- * @param proof Prood of concerned wallet's inclusion in an allowlist.
+ * @param proof Proof of concerned wallet's inclusion in an allowlist.
* @param quantityLimitPerWallet The total quantity of tokens the allowlisted wallet is eligible to claim over time.
* @param pricePerToken The price per token the allowlisted wallet must pay to claim tokens.
* @param currency The currency in which the allowlisted wallet must pay the price for claiming tokens.
diff --git a/contracts/extension/interface/IDropSinglePhase.sol b/contracts/extension/interface/IDropSinglePhase.sol
index f4468f192..92717755c 100644
--- a/contracts/extension/interface/IDropSinglePhase.sol
+++ b/contracts/extension/interface/IDropSinglePhase.sol
@@ -15,7 +15,7 @@ import "./IClaimCondition.sol";
interface IDropSinglePhase is IClaimCondition {
/**
- * @param proof Prood of concerned wallet's inclusion in an allowlist.
+ * @param proof Proof of concerned wallet's inclusion in an allowlist.
* @param quantityLimitPerWallet The total quantity of tokens the allowlisted wallet is eligible to claim over time.
* @param pricePerToken The price per token the allowlisted wallet must pay to claim tokens.
* @param currency The currency in which the allowlisted wallet must pay the price for claiming tokens.
diff --git a/contracts/extension/interface/IDropSinglePhase1155.sol b/contracts/extension/interface/IDropSinglePhase1155.sol
index db9445d09..dd1d8f065 100644
--- a/contracts/extension/interface/IDropSinglePhase1155.sol
+++ b/contracts/extension/interface/IDropSinglePhase1155.sol
@@ -15,7 +15,7 @@ import "./IClaimCondition.sol";
interface IDropSinglePhase1155 is IClaimCondition {
/**
- * @param proof Prood of concerned wallet's inclusion in an allowlist.
+ * @param proof Proof of concerned wallet's inclusion in an allowlist.
* @param quantityLimitPerWallet The total quantity of tokens the allowlisted wallet is eligible to claim over time.
* @param pricePerToken The price per token the allowlisted wallet must pay to claim tokens.
* @param currency The currency in which the allowlisted wallet must pay the price for claiming tokens.
diff --git a/contracts/extension/interface/IStaking1155.sol b/contracts/extension/interface/IStaking1155.sol
index 59502ac70..73e34e6b5 100644
--- a/contracts/extension/interface/IStaking1155.sol
+++ b/contracts/extension/interface/IStaking1155.sol
@@ -41,10 +41,10 @@ interface IStaking1155 {
* @param conditionIdOflastUpdate Condition-Id when rewards were last updated for user.
*/
struct Staker {
- uint256 amountStaked;
- uint256 timeOfLastUpdate;
+ uint64 conditionIdOflastUpdate;
+ uint64 amountStaked;
+ uint128 timeOfLastUpdate;
uint256 unclaimedRewards;
- uint256 conditionIdOflastUpdate;
}
/**
@@ -59,10 +59,10 @@ interface IStaking1155 {
* @param endTimestamp Condition end timestamp.
*/
struct StakingCondition {
- uint256 timeUnit;
+ uint80 timeUnit;
+ uint80 startTimestamp;
+ uint80 endTimestamp;
uint256 rewardsPerUnitTime;
- uint256 startTimestamp;
- uint256 endTimestamp;
}
/**
@@ -71,7 +71,7 @@ interface IStaking1155 {
* @param tokenId ERC1155 token-id to stake.
* @param amount Amount to stake.
*/
- function stake(uint256 tokenId, uint256 amount) external;
+ function stake(uint256 tokenId, uint64 amount) external;
/**
* @notice Withdraw staked tokens.
@@ -79,7 +79,7 @@ interface IStaking1155 {
* @param tokenId ERC1155 token-id to withdraw.
* @param amount Amount to withdraw.
*/
- function withdraw(uint256 tokenId, uint256 amount) external;
+ function withdraw(uint256 tokenId, uint64 amount) external;
/**
* @notice Claim accumulated rewards.
diff --git a/contracts/extension/interface/IStaking20.sol b/contracts/extension/interface/IStaking20.sol
index 4971c82a6..494a0d0a5 100644
--- a/contracts/extension/interface/IStaking20.sol
+++ b/contracts/extension/interface/IStaking20.sol
@@ -39,10 +39,10 @@ interface IStaking20 {
* @param conditionIdOflastUpdate Condition-Id when rewards were last updated for user.
*/
struct Staker {
+ uint128 timeOfLastUpdate;
+ uint64 conditionIdOflastUpdate;
uint256 amountStaked;
- uint256 timeOfLastUpdate;
uint256 unclaimedRewards;
- uint256 conditionIdOflastUpdate;
}
/**
@@ -61,11 +61,11 @@ interface IStaking20 {
* @param endTimestamp Condition end timestamp.
*/
struct StakingCondition {
- uint256 timeUnit;
+ uint80 timeUnit;
+ uint80 startTimestamp;
+ uint80 endTimestamp;
uint256 rewardRatioNumerator;
uint256 rewardRatioDenominator;
- uint256 startTimestamp;
- uint256 endTimestamp;
}
/**
diff --git a/contracts/extension/interface/IStaking721.sol b/contracts/extension/interface/IStaking721.sol
index fcbc62eb3..21ef88b38 100644
--- a/contracts/extension/interface/IStaking721.sol
+++ b/contracts/extension/interface/IStaking721.sol
@@ -31,10 +31,10 @@ interface IStaking721 {
* @param conditionIdOflastUpdate Condition-Id when rewards were last updated for user.
*/
struct Staker {
- uint256 amountStaked;
- uint256 timeOfLastUpdate;
+ uint64 amountStaked;
+ uint64 conditionIdOflastUpdate;
+ uint128 timeOfLastUpdate;
uint256 unclaimedRewards;
- uint256 conditionIdOflastUpdate;
}
/**
diff --git a/contracts/pack/PackVRFDirect.sol b/contracts/pack/PackVRFDirect.sol
index 5cfb71b44..ad5c91969 100644
--- a/contracts/pack/PackVRFDirect.sol
+++ b/contracts/pack/PackVRFDirect.sol
@@ -23,7 +23,7 @@ import "@openzeppelin/contracts-upgradeable/interfaces/IERC2981Upgradeable.sol";
import "@openzeppelin/contracts/interfaces/IERC721Receiver.sol";
import { IERC1155Receiver } from "@openzeppelin/contracts/interfaces/IERC1155Receiver.sol";
-import "@chainlink/contracts/src/v0.8/vrf/VRFV2WrapperConsumerBase.sol";
+import "./VRFV2WrapperConsumerBase.sol";
// ========== Internal imports ==========
diff --git a/contracts/pack/VRFV2WrapperConsumerBase.sol b/contracts/pack/VRFV2WrapperConsumerBase.sol
new file mode 100644
index 000000000..c5e2f7e68
--- /dev/null
+++ b/contracts/pack/VRFV2WrapperConsumerBase.sol
@@ -0,0 +1,83 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.0;
+
+import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
+import "@chainlink/contracts/src/v0.8/interfaces/VRFV2WrapperInterface.sol";
+
+/** *******************************************************************************
+ * @notice Interface for contracts using VRF randomness through the VRF V2 wrapper
+ * ********************************************************************************
+ * @dev PURPOSE
+ *
+ * @dev Create VRF V2 requests without the need for subscription management. Rather than creating
+ * @dev and funding a VRF V2 subscription, a user can use this wrapper to create one off requests,
+ * @dev paying up front rather than at fulfillment.
+ *
+ * @dev Since the price is determined using the gas price of the request transaction rather than
+ * @dev the fulfillment transaction, the wrapper charges an additional premium on callback gas
+ * @dev usage, in addition to some extra overhead costs associated with the VRFV2Wrapper contract.
+ * *****************************************************************************
+ * @dev USAGE
+ *
+ * @dev Calling contracts must inherit from VRFV2WrapperConsumerBase. The consumer must be funded
+ * @dev with enough LINK to make the request, otherwise requests will revert. To request randomness,
+ * @dev call the 'requestRandomness' function with the desired VRF parameters. This function handles
+ * @dev paying for the request based on the current pricing.
+ *
+ * @dev Consumers must implement the fullfillRandomWords function, which will be called during
+ * @dev fulfillment with the randomness result.
+ */
+abstract contract VRFV2WrapperConsumerBase {
+ // solhint-disable-next-line var-name-mixedcase
+ LinkTokenInterface internal immutable LINK;
+ // solhint-disable-next-line var-name-mixedcase
+ VRFV2WrapperInterface internal immutable VRF_V2_WRAPPER;
+
+ /**
+ * @param _link is the address of LinkToken
+ * @param _vrfV2Wrapper is the address of the VRFV2Wrapper contract
+ */
+ constructor(address _link, address _vrfV2Wrapper) {
+ LINK = LinkTokenInterface(_link);
+ VRF_V2_WRAPPER = VRFV2WrapperInterface(_vrfV2Wrapper);
+ }
+
+ /**
+ * @dev Requests randomness from the VRF V2 wrapper.
+ *
+ * @param _callbackGasLimit is the gas limit that should be used when calling the consumer's
+ * fulfillRandomWords function.
+ * @param _requestConfirmations is the number of confirmations to wait before fulfilling the
+ * request. A higher number of confirmations increases security by reducing the likelihood
+ * that a chain re-org changes a published randomness outcome.
+ * @param _numWords is the number of random words to request.
+ *
+ * @return requestId is the VRF V2 request ID of the newly created randomness request.
+ */
+ function requestRandomness(
+ uint32 _callbackGasLimit,
+ uint16 _requestConfirmations,
+ uint32 _numWords
+ ) internal returns (uint256 requestId) {
+ LINK.transferAndCall(
+ address(VRF_V2_WRAPPER),
+ VRF_V2_WRAPPER.calculateRequestPrice(_callbackGasLimit),
+ abi.encode(_callbackGasLimit, _requestConfirmations, _numWords)
+ );
+ return VRF_V2_WRAPPER.lastRequestId();
+ }
+
+ /**
+ * @notice fulfillRandomWords handles the VRF V2 wrapper response. The consuming contract must
+ * @notice implement it.
+ *
+ * @param _requestId is the VRF V2 request ID.
+ * @param _randomWords is the randomness result.
+ */
+ function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal virtual;
+
+ function rawFulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) external {
+ require(msg.sender == address(VRF_V2_WRAPPER), "only VRF V2 wrapper can fulfill");
+ fulfillRandomWords(_requestId, _randomWords);
+ }
+}
diff --git a/contracts/package.json b/contracts/package.json
index 9e3f0a4cb..75bf603e7 100644
--- a/contracts/package.json
+++ b/contracts/package.json
@@ -1,7 +1,7 @@
{
"name": "@thirdweb-dev/contracts",
"description": "Collection of smart contracts deployable via the thirdweb SDK, dashboard and CLI",
- "version": "3.8.0",
+ "version": "3.8.2",
"license": "Apache-2.0",
"repository": {
"type": "git",
diff --git a/contracts/smart-wallet/non-upgradeable/Account.sol b/contracts/smart-wallet/non-upgradeable/Account.sol
index 5b068ab4e..a20f100a0 100644
--- a/contracts/smart-wallet/non-upgradeable/Account.sol
+++ b/contracts/smart-wallet/non-upgradeable/Account.sol
@@ -107,42 +107,52 @@ contract Account is
// First, check if the signer is an admin.
if (data.isAdmin[_signer]) {
return true;
- } else {
- SignerPermissionsStatic memory permissions = data.signerPermissions[_signer];
-
- // If not an admin, check if the signer is active.
- require(
- permissions.startTimestamp <= block.timestamp &&
- block.timestamp < permissions.endTimestamp &&
- data.approvedTargets[_signer].length() > 0,
- "Account: no active permissions."
- );
-
- // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.
- bytes4 sig = getFunctionSignature(_userOp.callData);
-
- if (sig == this.execute.selector) {
- // Extract the `target` and `value` arguments from the calldata for `execute`.
- (address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);
-
- // Check if the value is within the allowed range and if the target is approved.
- require(permissions.nativeTokenLimitPerTransaction >= value, "Account: value too high.");
- require(data.approvedTargets[_signer].contains(target), "Account: target not approved.");
- } else if (sig == this.executeBatch.selector) {
- // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
- (address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);
-
- // For each target+value pair, check if the value is within the allowed range and if the target is approved.
- for (uint256 i = 0; i < targets.length; i++) {
- require(permissions.nativeTokenLimitPerTransaction >= values[i], "Account: value too high.");
- require(data.approvedTargets[_signer].contains(targets[i]), "Account: target not approved.");
+ }
+
+ SignerPermissionsStatic memory permissions = data.signerPermissions[_signer];
+
+ // If not an admin, check if the signer is active.
+ if (
+ permissions.startTimestamp > block.timestamp ||
+ block.timestamp >= permissions.endTimestamp ||
+ data.approvedTargets[_signer].length() == 0
+ ) {
+ // Account: no active permissions.
+ return false;
+ }
+
+ // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.
+ bytes4 sig = getFunctionSignature(_userOp.callData);
+
+ if (sig == this.execute.selector) {
+ // Extract the `target` and `value` arguments from the calldata for `execute`.
+ (address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);
+
+ // Check if the value is within the allowed range and if the target is approved.
+ if (permissions.nativeTokenLimitPerTransaction < value || !data.approvedTargets[_signer].contains(target)) {
+ // Account: value too high OR Account: target not approved.
+ return false;
+ }
+ } else if (sig == this.executeBatch.selector) {
+ // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
+ (address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);
+
+ // For each target+value pair, check if the value is within the allowed range and if the target is approved.
+ for (uint256 i = 0; i < targets.length; i++) {
+ if (
+ permissions.nativeTokenLimitPerTransaction < values[i] ||
+ !data.approvedTargets[_signer].contains(targets[i])
+ ) {
+ // Account: value too high OR Account: target not approved.
+ return false;
}
- } else {
- revert("Account: calling invalid fn.");
}
-
- return true;
+ } else {
+ // Account: calling invalid fn.
+ return false;
}
+
+ return true;
}
/// @notice See EIP-1271
diff --git a/contracts/smart-wallet/utils/AccountCore.sol b/contracts/smart-wallet/utils/AccountCore.sol
index 25615487b..b11c60cf3 100644
--- a/contracts/smart-wallet/utils/AccountCore.sol
+++ b/contracts/smart-wallet/utils/AccountCore.sol
@@ -78,48 +78,59 @@ contract AccountCore is IAccountCore, Initializable, Multicall, BaseAccount, ERC
/// @notice Returns whether a signer is authorized to perform transactions using the wallet.
function isValidSigner(address _signer, UserOperation calldata _userOp) public view virtual returns (bool) {
+ // We use the underlying storage instead of high level view functions to save gas.
// We use the underlying storage instead of high level view functions to save gas.
AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage();
// First, check if the signer is an admin.
if (data.isAdmin[_signer]) {
return true;
- } else {
- SignerPermissionsStatic memory permissions = data.signerPermissions[_signer];
-
- // If not an admin, check if the signer is active.
- require(
- permissions.startTimestamp <= block.timestamp &&
- block.timestamp < permissions.endTimestamp &&
- data.approvedTargets[_signer].length() > 0,
- "Account: no active permissions."
- );
-
- // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.
- bytes4 sig = getFunctionSignature(_userOp.callData);
-
- if (sig == Account.execute.selector) {
- // Extract the `target` and `value` arguments from the calldata for `execute`.
- (address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);
-
- // Check if the value is within the allowed range and if the target is approved.
- require(permissions.nativeTokenLimitPerTransaction >= value, "Account: value too high.");
- require(data.approvedTargets[_signer].contains(target), "Account: target not approved.");
- } else if (sig == Account.executeBatch.selector) {
- // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
- (address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);
-
- // For each target+value pair, check if the value is within the allowed range and if the target is approved.
- for (uint256 i = 0; i < targets.length; i++) {
- require(permissions.nativeTokenLimitPerTransaction >= values[i], "Account: value too high.");
- require(data.approvedTargets[_signer].contains(targets[i]), "Account: target not approved.");
+ }
+
+ SignerPermissionsStatic memory permissions = data.signerPermissions[_signer];
+
+ // If not an admin, check if the signer is active.
+ if (
+ permissions.startTimestamp > block.timestamp ||
+ block.timestamp >= permissions.endTimestamp ||
+ data.approvedTargets[_signer].length() == 0
+ ) {
+ // Account: no active permissions.
+ return false;
+ }
+
+ // Extract the function signature from the userOp calldata and check whether the signer is attempting to call `execute` or `executeBatch`.
+ bytes4 sig = getFunctionSignature(_userOp.callData);
+
+ if (sig == Account.execute.selector) {
+ // Extract the `target` and `value` arguments from the calldata for `execute`.
+ (address target, uint256 value) = decodeExecuteCalldata(_userOp.callData);
+
+ // Check if the value is within the allowed range and if the target is approved.
+ if (permissions.nativeTokenLimitPerTransaction < value || !data.approvedTargets[_signer].contains(target)) {
+ // Account: value too high OR Account: target not approved.
+ return false;
+ }
+ } else if (sig == Account.executeBatch.selector) {
+ // Extract the `target` and `value` array arguments from the calldata for `executeBatch`.
+ (address[] memory targets, uint256[] memory values, ) = decodeExecuteBatchCalldata(_userOp.callData);
+
+ // For each target+value pair, check if the value is within the allowed range and if the target is approved.
+ for (uint256 i = 0; i < targets.length; i++) {
+ if (
+ permissions.nativeTokenLimitPerTransaction < values[i] ||
+ !data.approvedTargets[_signer].contains(targets[i])
+ ) {
+ // Account: value too high OR Account: target not approved.
+ return false;
}
- } else {
- revert("Account: calling invalid fn.");
}
-
- return true;
+ } else {
+ // Account: calling invalid fn.
+ return false;
}
+
+ return true;
}
/// @notice See EIP-1271
diff --git a/contracts/staking/EditionStake.sol b/contracts/staking/EditionStake.sol
index 6f0865adc..01f15bafa 100644
--- a/contracts/staking/EditionStake.sol
+++ b/contracts/staking/EditionStake.sol
@@ -65,7 +65,7 @@ contract EditionStake is
address[] memory _trustedForwarders,
address _rewardToken,
address _stakingToken,
- uint256 _defaultTimeUnit,
+ uint80 _defaultTimeUnit,
uint256 _defaultRewardsPerUnitTime
) external initializer {
__ERC2771Context_init_unchained(_trustedForwarders);
@@ -147,7 +147,7 @@ contract EditionStake is
uint256,
uint256,
bytes calldata
- ) external returns (bytes4) {
+ ) external view returns (bytes4) {
require(isStaking == 2, "Direct transfer");
return this.onERC1155Received.selector;
}
diff --git a/contracts/staking/TokenStake.sol b/contracts/staking/TokenStake.sol
index f9a1eec9d..77d785e88 100644
--- a/contracts/staking/TokenStake.sol
+++ b/contracts/staking/TokenStake.sol
@@ -57,7 +57,7 @@ contract TokenStake is
address[] memory _trustedForwarders,
address _rewardToken,
address _stakingToken,
- uint256 _timeUnit,
+ uint80 _timeUnit,
uint256 _rewardRatioNumerator,
uint256 _rewardRatioDenominator
) external initializer {
@@ -66,10 +66,10 @@ contract TokenStake is
require(_rewardToken != _stakingToken, "Reward Token and Staking Token can't be same.");
rewardToken = _rewardToken;
- uint256 _stakingTokenDecimals = _stakingToken == CurrencyTransferLib.NATIVE_TOKEN
+ uint16 _stakingTokenDecimals = _stakingToken == CurrencyTransferLib.NATIVE_TOKEN
? 18
: IERC20Metadata(_stakingToken).decimals();
- uint256 _rewardTokenDecimals = _rewardToken == CurrencyTransferLib.NATIVE_TOKEN
+ uint16 _rewardTokenDecimals = _rewardToken == CurrencyTransferLib.NATIVE_TOKEN
? 18
: IERC20Metadata(_rewardToken).decimals();
diff --git a/docs/ERC6551AccountLib.md b/docs/ERC6551AccountLib.md
new file mode 100644
index 000000000..03d95b596
--- /dev/null
+++ b/docs/ERC6551AccountLib.md
@@ -0,0 +1,12 @@
+# ERC6551AccountLib
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/ERC6551BytecodeLib.md b/docs/ERC6551BytecodeLib.md
new file mode 100644
index 000000000..234567136
--- /dev/null
+++ b/docs/ERC6551BytecodeLib.md
@@ -0,0 +1,12 @@
+# ERC6551BytecodeLib
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/ERC721AQueryableUpgradeable.md b/docs/ERC721AQueryableUpgradeable.md
new file mode 100644
index 000000000..d95adb25e
--- /dev/null
+++ b/docs/ERC721AQueryableUpgradeable.md
@@ -0,0 +1,589 @@
+# ERC721AQueryableUpgradeable
+
+
+
+> ERC721AQueryable.
+
+
+
+*ERC721A subclass with convenience query functions.*
+
+## Methods
+
+### approve
+
+```solidity
+function approve(address to, uint256 tokenId) external payable
+```
+
+
+
+*Gives permission to `to` to transfer `tokenId` token to another account. See {ERC721A-_approve}. Requirements: - The caller must own the token or be an approved operator.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+### balanceOf
+
+```solidity
+function balanceOf(address owner) external view returns (uint256)
+```
+
+
+
+*Returns the number of tokens in `owner`'s account.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### explicitOwnershipOf
+
+```solidity
+function explicitOwnershipOf(uint256 tokenId) external view returns (struct IERC721AUpgradeable.TokenOwnership ownership)
+```
+
+
+
+*Returns the `TokenOwnership` struct at `tokenId` without reverting. If the `tokenId` is out of bounds: - `addr = address(0)` - `startTimestamp = 0` - `burned = false` - `extraData = 0` If the `tokenId` is burned: - `addr = <Address of owner before token was burned>` - `startTimestamp = <Timestamp when token was burned>` - `burned = true` - `extraData = <Extra data when token was burned>` Otherwise: - `addr = <Address of owner>` - `startTimestamp = <Timestamp of start of ownership>` - `burned = false` - `extraData = <Extra data at start of ownership>`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| ownership | IERC721AUpgradeable.TokenOwnership | undefined |
+
+### getApproved
+
+```solidity
+function getApproved(uint256 tokenId) external view returns (address)
+```
+
+
+
+*Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+### isApprovedForAll
+
+```solidity
+function isApprovedForAll(address owner, address operator) external view returns (bool)
+```
+
+
+
+*Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+| operator | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### name
+
+```solidity
+function name() external view returns (string)
+```
+
+
+
+*Returns the token collection name.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### ownerOf
+
+```solidity
+function ownerOf(uint256 tokenId) external view returns (address)
+```
+
+
+
+*Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+### safeTransferFrom
+
+```solidity
+function safeTransferFrom(address from, address to, uint256 tokenId) external payable
+```
+
+
+
+*Equivalent to `safeTransferFrom(from, to, tokenId, '')`.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+### safeTransferFrom
+
+```solidity
+function safeTransferFrom(address from, address to, uint256 tokenId, bytes _data) external payable
+```
+
+
+
+*Safely transfers `tokenId` token from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+| _data | bytes | undefined |
+
+### setApprovalForAll
+
+```solidity
+function setApprovalForAll(address operator, bool approved) external nonpayable
+```
+
+
+
+*Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| operator | address | undefined |
+| approved | bool | undefined |
+
+### supportsInterface
+
+```solidity
+function supportsInterface(bytes4 interfaceId) external view returns (bool)
+```
+
+
+
+*Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. This function call must use less than 30000 gas.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| interfaceId | bytes4 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### symbol
+
+```solidity
+function symbol() external view returns (string)
+```
+
+
+
+*Returns the token collection symbol.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### tokenURI
+
+```solidity
+function tokenURI(uint256 tokenId) external view returns (string)
+```
+
+
+
+*Returns the Uniform Resource Identifier (URI) for `tokenId` token.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### tokensOfOwner
+
+```solidity
+function tokensOfOwner(address owner) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`. This function scans the ownership mapping and is O(`totalSupply`) in complexity. It is meant to be called off-chain. See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into multiple smaller scans if the collection is large enough to cause an out-of-gas error (10K collections should be fine).*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
+### tokensOfOwnerIn
+
+```solidity
+function tokensOfOwnerIn(address owner, uint256 start, uint256 stop) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`, in the range [`start`, `stop`) (i.e. `start <= tokenId < stop`). This function allows for tokens to be queried if the collection grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. Requirements: - `start < stop`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+| start | uint256 | undefined |
+| stop | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
+### totalSupply
+
+```solidity
+function totalSupply() external view returns (uint256)
+```
+
+
+
+*Returns the total number of tokens in existence. Burned tokens will reduce the count. To get the total number of tokens minted, please see {_totalMinted}.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### transferFrom
+
+```solidity
+function transferFrom(address from, address to, uint256 tokenId) external payable
+```
+
+
+
+*Transfers `tokenId` from `from` to `to`. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+
+
+## Events
+
+### Approval
+
+```solidity
+event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner `indexed` | address | undefined |
+| approved `indexed` | address | undefined |
+| tokenId `indexed` | uint256 | undefined |
+
+### ApprovalForAll
+
+```solidity
+event ApprovalForAll(address indexed owner, address indexed operator, bool approved)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner `indexed` | address | undefined |
+| operator `indexed` | address | undefined |
+| approved | bool | undefined |
+
+### ConsecutiveTransfer
+
+```solidity
+event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| fromTokenId `indexed` | uint256 | undefined |
+| toTokenId | uint256 | undefined |
+| from `indexed` | address | undefined |
+| to `indexed` | address | undefined |
+
+### Transfer
+
+```solidity
+event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from `indexed` | address | undefined |
+| to `indexed` | address | undefined |
+| tokenId `indexed` | uint256 | undefined |
+
+
+
+## Errors
+
+### ApprovalCallerNotOwnerNorApproved
+
+```solidity
+error ApprovalCallerNotOwnerNorApproved()
+```
+
+The caller must own the token or be an approved operator.
+
+
+
+
+### ApprovalQueryForNonexistentToken
+
+```solidity
+error ApprovalQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+### BalanceQueryForZeroAddress
+
+```solidity
+error BalanceQueryForZeroAddress()
+```
+
+Cannot query the balance for the zero address.
+
+
+
+
+### InvalidQueryRange
+
+```solidity
+error InvalidQueryRange()
+```
+
+Invalid query range (`start` >= `stop`).
+
+
+
+
+### MintERC2309QuantityExceedsLimit
+
+```solidity
+error MintERC2309QuantityExceedsLimit()
+```
+
+The `quantity` minted with ERC2309 exceeds the safety limit.
+
+
+
+
+### MintToZeroAddress
+
+```solidity
+error MintToZeroAddress()
+```
+
+Cannot mint to the zero address.
+
+
+
+
+### MintZeroQuantity
+
+```solidity
+error MintZeroQuantity()
+```
+
+The quantity of tokens minted must be more than zero.
+
+
+
+
+### OwnerQueryForNonexistentToken
+
+```solidity
+error OwnerQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+### OwnershipNotInitializedForExtraData
+
+```solidity
+error OwnershipNotInitializedForExtraData()
+```
+
+The `extraData` cannot be set on an unintialized ownership slot.
+
+
+
+
+### TransferCallerNotOwnerNorApproved
+
+```solidity
+error TransferCallerNotOwnerNorApproved()
+```
+
+The caller must own the token or be an approved operator.
+
+
+
+
+### TransferFromIncorrectOwner
+
+```solidity
+error TransferFromIncorrectOwner()
+```
+
+The token must be owned by `from`.
+
+
+
+
+### TransferToNonERC721ReceiverImplementer
+
+```solidity
+error TransferToNonERC721ReceiverImplementer()
+```
+
+Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
+
+
+
+
+### TransferToZeroAddress
+
+```solidity
+error TransferToZeroAddress()
+```
+
+Cannot transfer to the zero address.
+
+
+
+
+### URIQueryForNonexistentToken
+
+```solidity
+error URIQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+
diff --git a/docs/ERC721AStorage.md b/docs/ERC721AStorage.md
index 0737cb905..4ead51e0e 100644
--- a/docs/ERC721AStorage.md
+++ b/docs/ERC721AStorage.md
@@ -8,25 +8,5 @@
-## Methods
-
-### ERC721A_STORAGE_POSITION
-
-```solidity
-function ERC721A_STORAGE_POSITION() external view returns (bytes32)
-```
-
-
-
-
-
-
-#### Returns
-
-| Name | Type | Description |
-|---|---|---|
-| _0 | bytes32 | undefined |
-
-
diff --git a/docs/ERC721A__IERC721ReceiverUpgradeable.md b/docs/ERC721A__IERC721ReceiverUpgradeable.md
new file mode 100644
index 000000000..3de156096
--- /dev/null
+++ b/docs/ERC721A__IERC721ReceiverUpgradeable.md
@@ -0,0 +1,40 @@
+# ERC721A__IERC721ReceiverUpgradeable
+
+
+
+
+
+
+
+*Interface of ERC721 token receiver.*
+
+## Methods
+
+### onERC721Received
+
+```solidity
+function onERC721Received(address operator, address from, uint256 tokenId, bytes data) external nonpayable returns (bytes4)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| operator | address | undefined |
+| from | address | undefined |
+| tokenId | uint256 | undefined |
+| data | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bytes4 | undefined |
+
+
+
+
diff --git a/docs/ERC721A__Initializable.md b/docs/ERC721A__Initializable.md
new file mode 100644
index 000000000..8b4854503
--- /dev/null
+++ b/docs/ERC721A__Initializable.md
@@ -0,0 +1,12 @@
+# ERC721A__Initializable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/ERC721A__InitializableStorage.md b/docs/ERC721A__InitializableStorage.md
new file mode 100644
index 000000000..2927cdb21
--- /dev/null
+++ b/docs/ERC721A__InitializableStorage.md
@@ -0,0 +1,12 @@
+# ERC721A__InitializableStorage
+
+
+
+
+
+
+
+*This is a base storage for the initialization function for upgradeable diamond facet contracts**
+
+
+
diff --git a/docs/IERC6551Account.md b/docs/IERC6551Account.md
new file mode 100644
index 000000000..e910ffadb
--- /dev/null
+++ b/docs/IERC6551Account.md
@@ -0,0 +1,113 @@
+# IERC6551Account
+
+
+
+
+
+
+
+*the ERC-165 identifier for this interface is `0xeff4d378`*
+
+## Methods
+
+### executeCall
+
+```solidity
+function executeCall(address to, uint256 value, bytes data) external payable returns (bytes)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| to | address | undefined |
+| value | uint256 | undefined |
+| data | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bytes | undefined |
+
+### nonce
+
+```solidity
+function nonce() external view returns (uint256)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### owner
+
+```solidity
+function owner() external view returns (address)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+### token
+
+```solidity
+function token() external view returns (uint256 chainId, address tokenContract, uint256 tokenId)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| chainId | uint256 | undefined |
+| tokenContract | address | undefined |
+| tokenId | uint256 | undefined |
+
+
+
+## Events
+
+### TransactionExecuted
+
+```solidity
+event TransactionExecuted(address indexed target, uint256 indexed value, bytes data)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| target `indexed` | address | undefined |
+| value `indexed` | uint256 | undefined |
+| data | bytes | undefined |
+
+
+
diff --git a/docs/IERC6551AccountProxy.md b/docs/IERC6551AccountProxy.md
new file mode 100644
index 000000000..939810a14
--- /dev/null
+++ b/docs/IERC6551AccountProxy.md
@@ -0,0 +1,32 @@
+# IERC6551AccountProxy
+
+
+
+
+
+
+
+
+
+## Methods
+
+### implementation
+
+```solidity
+function implementation() external view returns (address)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+
+
+
diff --git a/docs/IERC721AQueryableUpgradeable.md b/docs/IERC721AQueryableUpgradeable.md
new file mode 100644
index 000000000..2e41b18fd
--- /dev/null
+++ b/docs/IERC721AQueryableUpgradeable.md
@@ -0,0 +1,589 @@
+# IERC721AQueryableUpgradeable
+
+
+
+
+
+
+
+*Interface of ERC721AQueryable.*
+
+## Methods
+
+### approve
+
+```solidity
+function approve(address to, uint256 tokenId) external payable
+```
+
+
+
+*Gives permission to `to` to transfer `tokenId` token to another account. The approval is cleared when the token is transferred. Only a single account can be approved at a time, so approving the zero address clears previous approvals. Requirements: - The caller must own the token or be an approved operator. - `tokenId` must exist. Emits an {Approval} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+### balanceOf
+
+```solidity
+function balanceOf(address owner) external view returns (uint256 balance)
+```
+
+
+
+*Returns the number of tokens in `owner`'s account.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| balance | uint256 | undefined |
+
+### explicitOwnershipOf
+
+```solidity
+function explicitOwnershipOf(uint256 tokenId) external view returns (struct IERC721AUpgradeable.TokenOwnership)
+```
+
+
+
+*Returns the `TokenOwnership` struct at `tokenId` without reverting. If the `tokenId` is out of bounds: - `addr = address(0)` - `startTimestamp = 0` - `burned = false` - `extraData = 0` If the `tokenId` is burned: - `addr = <Address of owner before token was burned>` - `startTimestamp = <Timestamp when token was burned>` - `burned = true` - `extraData = <Extra data when token was burned>` Otherwise: - `addr = <Address of owner>` - `startTimestamp = <Timestamp of start of ownership>` - `burned = false` - `extraData = <Extra data at start of ownership>`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | IERC721AUpgradeable.TokenOwnership | undefined |
+
+### getApproved
+
+```solidity
+function getApproved(uint256 tokenId) external view returns (address operator)
+```
+
+
+
+*Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| operator | address | undefined |
+
+### isApprovedForAll
+
+```solidity
+function isApprovedForAll(address owner, address operator) external view returns (bool)
+```
+
+
+
+*Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+| operator | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### name
+
+```solidity
+function name() external view returns (string)
+```
+
+
+
+*Returns the token collection name.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### ownerOf
+
+```solidity
+function ownerOf(uint256 tokenId) external view returns (address owner)
+```
+
+
+
+*Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+### safeTransferFrom
+
+```solidity
+function safeTransferFrom(address from, address to, uint256 tokenId) external payable
+```
+
+
+
+*Equivalent to `safeTransferFrom(from, to, tokenId, '')`.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+### safeTransferFrom
+
+```solidity
+function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external payable
+```
+
+
+
+*Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients are aware of the ERC721 protocol to prevent tokens from being forever locked. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must exist and be owned by `from`. - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. Emits a {Transfer} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+| data | bytes | undefined |
+
+### setApprovalForAll
+
+```solidity
+function setApprovalForAll(address operator, bool _approved) external nonpayable
+```
+
+
+
+*Approve or remove `operator` as an operator for the caller. Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. Requirements: - The `operator` cannot be the caller. Emits an {ApprovalForAll} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| operator | address | undefined |
+| _approved | bool | undefined |
+
+### supportsInterface
+
+```solidity
+function supportsInterface(bytes4 interfaceId) external view returns (bool)
+```
+
+
+
+*Returns true if this contract implements the interface defined by `interfaceId`. See the corresponding [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified) to learn more about how these ids are created. This function call must use less than 30000 gas.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| interfaceId | bytes4 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### symbol
+
+```solidity
+function symbol() external view returns (string)
+```
+
+
+
+*Returns the token collection symbol.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### tokenURI
+
+```solidity
+function tokenURI(uint256 tokenId) external view returns (string)
+```
+
+
+
+*Returns the Uniform Resource Identifier (URI) for `tokenId` token.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### tokensOfOwner
+
+```solidity
+function tokensOfOwner(address owner) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`. This function scans the ownership mapping and is O(`totalSupply`) in complexity. It is meant to be called off-chain. See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into multiple smaller scans if the collection is large enough to cause an out-of-gas error (10K collections should be fine).*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
+### tokensOfOwnerIn
+
+```solidity
+function tokensOfOwnerIn(address owner, uint256 start, uint256 stop) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`, in the range [`start`, `stop`) (i.e. `start <= tokenId < stop`). This function allows for tokens to be queried if the collection grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. Requirements: - `start < stop`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+| start | uint256 | undefined |
+| stop | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
+### totalSupply
+
+```solidity
+function totalSupply() external view returns (uint256)
+```
+
+
+
+*Returns the total number of tokens in existence. Burned tokens will reduce the count. To get the total number of tokens minted, please see {_totalMinted}.*
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### transferFrom
+
+```solidity
+function transferFrom(address from, address to, uint256 tokenId) external payable
+```
+
+
+
+*Transfers `tokenId` from `from` to `to`. WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. Requirements: - `from` cannot be the zero address. - `to` cannot be the zero address. - `tokenId` token must be owned by `from`. - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. Emits a {Transfer} event.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from | address | undefined |
+| to | address | undefined |
+| tokenId | uint256 | undefined |
+
+
+
+## Events
+
+### Approval
+
+```solidity
+event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner `indexed` | address | undefined |
+| approved `indexed` | address | undefined |
+| tokenId `indexed` | uint256 | undefined |
+
+### ApprovalForAll
+
+```solidity
+event ApprovalForAll(address indexed owner, address indexed operator, bool approved)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner `indexed` | address | undefined |
+| operator `indexed` | address | undefined |
+| approved | bool | undefined |
+
+### ConsecutiveTransfer
+
+```solidity
+event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| fromTokenId `indexed` | uint256 | undefined |
+| toTokenId | uint256 | undefined |
+| from `indexed` | address | undefined |
+| to `indexed` | address | undefined |
+
+### Transfer
+
+```solidity
+event Transfer(address indexed from, address indexed to, uint256 indexed tokenId)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| from `indexed` | address | undefined |
+| to `indexed` | address | undefined |
+| tokenId `indexed` | uint256 | undefined |
+
+
+
+## Errors
+
+### ApprovalCallerNotOwnerNorApproved
+
+```solidity
+error ApprovalCallerNotOwnerNorApproved()
+```
+
+The caller must own the token or be an approved operator.
+
+
+
+
+### ApprovalQueryForNonexistentToken
+
+```solidity
+error ApprovalQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+### BalanceQueryForZeroAddress
+
+```solidity
+error BalanceQueryForZeroAddress()
+```
+
+Cannot query the balance for the zero address.
+
+
+
+
+### InvalidQueryRange
+
+```solidity
+error InvalidQueryRange()
+```
+
+Invalid query range (`start` >= `stop`).
+
+
+
+
+### MintERC2309QuantityExceedsLimit
+
+```solidity
+error MintERC2309QuantityExceedsLimit()
+```
+
+The `quantity` minted with ERC2309 exceeds the safety limit.
+
+
+
+
+### MintToZeroAddress
+
+```solidity
+error MintToZeroAddress()
+```
+
+Cannot mint to the zero address.
+
+
+
+
+### MintZeroQuantity
+
+```solidity
+error MintZeroQuantity()
+```
+
+The quantity of tokens minted must be more than zero.
+
+
+
+
+### OwnerQueryForNonexistentToken
+
+```solidity
+error OwnerQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+### OwnershipNotInitializedForExtraData
+
+```solidity
+error OwnershipNotInitializedForExtraData()
+```
+
+The `extraData` cannot be set on an unintialized ownership slot.
+
+
+
+
+### TransferCallerNotOwnerNorApproved
+
+```solidity
+error TransferCallerNotOwnerNorApproved()
+```
+
+The caller must own the token or be an approved operator.
+
+
+
+
+### TransferFromIncorrectOwner
+
+```solidity
+error TransferFromIncorrectOwner()
+```
+
+The token must be owned by `from`.
+
+
+
+
+### TransferToNonERC721ReceiverImplementer
+
+```solidity
+error TransferToNonERC721ReceiverImplementer()
+```
+
+Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
+
+
+
+
+### TransferToZeroAddress
+
+```solidity
+error TransferToZeroAddress()
+```
+
+Cannot transfer to the zero address.
+
+
+
+
+### URIQueryForNonexistentToken
+
+```solidity
+error URIQueryForNonexistentToken()
+```
+
+The token does not exist.
+
+
+
+
+
diff --git a/docs/OpenEditionERC721.md b/docs/OpenEditionERC721.md
index 22a1d92ec..caaa5e09d 100644
--- a/docs/OpenEditionERC721.md
+++ b/docs/OpenEditionERC721.md
@@ -30,7 +30,7 @@ function DEFAULT_ADMIN_ROLE() external view returns (bytes32)
### approve
```solidity
-function approve(address operator, uint256 tokenId) external nonpayable
+function approve(address operator, uint256 tokenId) external payable
```
@@ -52,7 +52,7 @@ function balanceOf(address owner) external view returns (uint256)
-*See {IERC721-balanceOf}.*
+*Returns the number of tokens in `owner`'s account.*
#### Parameters
@@ -138,6 +138,28 @@ Returns the contract metadata URI.
|---|---|---|
| _0 | string | undefined |
+### explicitOwnershipOf
+
+```solidity
+function explicitOwnershipOf(uint256 tokenId) external view returns (struct IERC721AUpgradeable.TokenOwnership ownership)
+```
+
+
+
+*Returns the `TokenOwnership` struct at `tokenId` without reverting. If the `tokenId` is out of bounds: - `addr = address(0)` - `startTimestamp = 0` - `burned = false` - `extraData = 0` If the `tokenId` is burned: - `addr = <Address of owner before token was burned>` - `startTimestamp = <Timestamp when token was burned>` - `burned = true` - `extraData = <Extra data when token was burned>` Otherwise: - `addr = <Address of owner>` - `startTimestamp = <Timestamp of start of ownership>` - `burned = false` - `extraData = <Extra data at start of ownership>`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| tokenId | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| ownership | IERC721AUpgradeable.TokenOwnership | undefined |
+
### getActiveClaimConditionId
```solidity
@@ -163,7 +185,7 @@ function getApproved(uint256 tokenId) external view returns (address)
-*See {IERC721-getApproved}.*
+*Returns the account approved for `tokenId` token. Requirements: - `tokenId` must exist.*
#### Parameters
@@ -217,59 +239,6 @@ Returns the defualt royalty recipient and BPS for this contract's NFTs.
| _0 | address | undefined |
| _1 | uint16 | undefined |
-### getFlatPlatformFeeInfo
-
-```solidity
-function getFlatPlatformFeeInfo() external view returns (address, uint256)
-```
-
-
-
-*Returns the platform fee bps and recipient.*
-
-
-#### Returns
-
-| Name | Type | Description |
-|---|---|---|
-| _0 | address | undefined |
-| _1 | uint256 | undefined |
-
-### getPlatformFeeInfo
-
-```solidity
-function getPlatformFeeInfo() external view returns (address, uint16)
-```
-
-
-
-*Returns the platform fee recipient and bps.*
-
-
-#### Returns
-
-| Name | Type | Description |
-|---|---|---|
-| _0 | address | undefined |
-| _1 | uint16 | undefined |
-
-### getPlatformFeeType
-
-```solidity
-function getPlatformFeeType() external view returns (enum IPlatformFee.PlatformFeeType)
-```
-
-
-
-*Returns the platform fee bps and recipient.*
-
-
-#### Returns
-
-| Name | Type | Description |
-|---|---|---|
-| _0 | enum IPlatformFee.PlatformFeeType | undefined |
-
### getRoleAdmin
```solidity
@@ -449,7 +418,7 @@ Checks whether an account has a particular role; role restricti
### initialize
```solidity
-function initialize(address _defaultAdmin, string _name, string _symbol, string _contractURI, address[] _trustedForwarders, address _saleRecipient, address _royaltyRecipient, uint128 _royaltyBps, uint128 _platformFeeBps, address _platformFeeRecipient) external nonpayable
+function initialize(address _defaultAdmin, string _name, string _symbol, string _contractURI, address[] _trustedForwarders, address _saleRecipient, address _royaltyRecipient, uint128 _royaltyBps) external nonpayable
```
@@ -468,8 +437,6 @@ function initialize(address _defaultAdmin, string _name, string _symbol, string
| _saleRecipient | address | undefined |
| _royaltyRecipient | address | undefined |
| _royaltyBps | uint128 | undefined |
-| _platformFeeBps | uint128 | undefined |
-| _platformFeeRecipient | address | undefined |
### isApprovedForAll
@@ -479,7 +446,7 @@ function isApprovedForAll(address owner, address operator) external view returns
-*See {IERC721-isApprovedForAll}.*
+*Returns if the `operator` is allowed to manage all of the assets of `owner`. See {setApprovalForAll}.*
#### Parameters
@@ -546,7 +513,7 @@ function name() external view returns (string)
-*See {IERC721Metadata-name}.*
+*Returns the token collection name.*
#### Returns
@@ -631,7 +598,7 @@ function ownerOf(uint256 tokenId) external view returns (address)
-*See {IERC721-ownerOf}.*
+*Returns the owner of the `tokenId` token. Requirements: - `tokenId` must exist.*
#### Parameters
@@ -723,7 +690,7 @@ View royalty info for a given token and sale price.
### safeTransferFrom
```solidity
-function safeTransferFrom(address from, address to, uint256 tokenId) external nonpayable
+function safeTransferFrom(address from, address to, uint256 tokenId) external payable
```
@@ -741,7 +708,7 @@ function safeTransferFrom(address from, address to, uint256 tokenId) external no
### safeTransferFrom
```solidity
-function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external nonpayable
+function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external payable
```
@@ -824,23 +791,6 @@ Updates default royalty recipient and bps.
| _royaltyRecipient | address | Address to be set as default royalty recipient. |
| _royaltyBps | uint256 | Updated royalty bps. |
-### setFlatPlatformFeeInfo
-
-```solidity
-function setFlatPlatformFeeInfo(address _platformFeeRecipient, uint256 _flatFee) external nonpayable
-```
-
-Lets a module admin set a flat fee on primary sales.
-
-
-
-#### Parameters
-
-| Name | Type | Description |
-|---|---|---|
-| _platformFeeRecipient | address | undefined |
-| _flatFee | uint256 | undefined |
-
### setOperatorRestriction
```solidity
@@ -873,39 +823,6 @@ Lets an authorized wallet set a new owner for the contract.
|---|---|---|
| _newOwner | address | The address to set as the new owner of the contract. |
-### setPlatformFeeInfo
-
-```solidity
-function setPlatformFeeInfo(address _platformFeeRecipient, uint256 _platformFeeBps) external nonpayable
-```
-
-Updates the platform fee recipient and bps.
-
-*Caller should be authorized to set platform fee info. See {_canSetPlatformFeeInfo}. Emits {PlatformFeeInfoUpdated Event}; See {_setupPlatformFeeInfo}.*
-
-#### Parameters
-
-| Name | Type | Description |
-|---|---|---|
-| _platformFeeRecipient | address | Address to be set as new platformFeeRecipient. |
-| _platformFeeBps | uint256 | Updated platformFeeBps. |
-
-### setPlatformFeeType
-
-```solidity
-function setPlatformFeeType(enum IPlatformFee.PlatformFeeType _feeType) external nonpayable
-```
-
-Lets a module admin set platform fee type.
-
-
-
-#### Parameters
-
-| Name | Type | Description |
-|---|---|---|
-| _feeType | enum IPlatformFee.PlatformFeeType | undefined |
-
### setPrimarySaleRecipient
```solidity
@@ -1039,7 +956,7 @@ function symbol() external view returns (string)
-*See {IERC721Metadata-symbol}.*
+*Returns the token collection symbol.*
#### Returns
@@ -1070,6 +987,52 @@ function tokenURI(uint256 _tokenId) external view returns (string)
|---|---|---|
| _0 | string | undefined |
+### tokensOfOwner
+
+```solidity
+function tokensOfOwner(address owner) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`. This function scans the ownership mapping and is O(`totalSupply`) in complexity. It is meant to be called off-chain. See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into multiple smaller scans if the collection is large enough to cause an out-of-gas error (10K collections should be fine).*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
+### tokensOfOwnerIn
+
+```solidity
+function tokensOfOwnerIn(address owner, uint256 start, uint256 stop) external view returns (uint256[])
+```
+
+
+
+*Returns an array of token IDs owned by `owner`, in the range [`start`, `stop`) (i.e. `start <= tokenId < stop`). This function allows for tokens to be queried if the collection grows too big for a single call of {ERC721AQueryable-tokensOfOwner}. Requirements: - `start < stop`*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| owner | address | undefined |
+| start | uint256 | undefined |
+| stop | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256[] | undefined |
+
### totalMinted
```solidity
@@ -1095,7 +1058,7 @@ function totalSupply() external view returns (uint256)
-*Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.*
+*Returns the total number of tokens in existence. Burned tokens will reduce the count. To get the total number of tokens minted, please see {_totalMinted}.*
#### Returns
@@ -1107,7 +1070,7 @@ function totalSupply() external view returns (uint256)
### transferFrom
```solidity
-function transferFrom(address from, address to, uint256 tokenId) external nonpayable
+function transferFrom(address from, address to, uint256 tokenId) external payable
```
@@ -1206,10 +1169,10 @@ Emitted when the contract's claim conditions are updated.
| claimConditions | IClaimCondition.ClaimCondition[] | undefined |
| resetEligibility | bool | undefined |
-### ContractURIUpdated
+### ConsecutiveTransfer
```solidity
-event ContractURIUpdated(string prevURI, string newURI)
+event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to)
```
@@ -1220,13 +1183,15 @@ event ContractURIUpdated(string prevURI, string newURI)
| Name | Type | Description |
|---|---|---|
-| prevURI | string | undefined |
-| newURI | string | undefined |
+| fromTokenId `indexed` | uint256 | undefined |
+| toTokenId | uint256 | undefined |
+| from `indexed` | address | undefined |
+| to `indexed` | address | undefined |
-### DefaultRoyalty
+### ContractURIUpdated
```solidity
-event DefaultRoyalty(address indexed newRoyaltyRecipient, uint256 newRoyaltyBps)
+event ContractURIUpdated(string prevURI, string newURI)
```
@@ -1237,13 +1202,13 @@ event DefaultRoyalty(address indexed newRoyaltyRecipient, uint256 newRoyaltyBps)
| Name | Type | Description |
|---|---|---|
-| newRoyaltyRecipient `indexed` | address | undefined |
-| newRoyaltyBps | uint256 | undefined |
+| prevURI | string | undefined |
+| newURI | string | undefined |
-### FlatPlatformFeeUpdated
+### DefaultRoyalty
```solidity
-event FlatPlatformFeeUpdated(address platformFeeRecipient, uint256 flatFee)
+event DefaultRoyalty(address indexed newRoyaltyRecipient, uint256 newRoyaltyBps)
```
@@ -1254,8 +1219,8 @@ event FlatPlatformFeeUpdated(address platformFeeRecipient, uint256 flatFee)
| Name | Type | Description |
|---|---|---|
-| platformFeeRecipient | address | undefined |
-| flatFee | uint256 | undefined |
+| newRoyaltyRecipient `indexed` | address | undefined |
+| newRoyaltyBps | uint256 | undefined |
### Initialized
@@ -1306,39 +1271,6 @@ event OwnerUpdated(address indexed prevOwner, address indexed newOwner)
| prevOwner `indexed` | address | undefined |
| newOwner `indexed` | address | undefined |
-### PlatformFeeInfoUpdated
-
-```solidity
-event PlatformFeeInfoUpdated(address indexed platformFeeRecipient, uint256 platformFeeBps)
-```
-
-
-
-
-
-#### Parameters
-
-| Name | Type | Description |
-|---|---|---|
-| platformFeeRecipient `indexed` | address | undefined |
-| platformFeeBps | uint256 | undefined |
-
-### PlatformFeeTypeUpdated
-
-```solidity
-event PlatformFeeTypeUpdated(enum IPlatformFee.PlatformFeeType feeType)
-```
-
-
-
-
-
-#### Parameters
-
-| Name | Type | Description |
-|---|---|---|
-| feeType | enum IPlatformFee.PlatformFeeType | undefined |
-
### PrimarySaleRecipientUpdated
```solidity
@@ -1510,35 +1442,35 @@ The token does not exist.
-### ApprovalToCurrentOwner
+### BalanceQueryForZeroAddress
```solidity
-error ApprovalToCurrentOwner()
+error BalanceQueryForZeroAddress()
```
-The caller cannot approve to the current owner.
+Cannot query the balance for the zero address.
-### ApproveToCaller
+### InvalidQueryRange
```solidity
-error ApproveToCaller()
+error InvalidQueryRange()
```
-The caller cannot approve to their own address.
+Invalid query range (`start` >= `stop`).
-### BalanceQueryForZeroAddress
+### MintERC2309QuantityExceedsLimit
```solidity
-error BalanceQueryForZeroAddress()
+error MintERC2309QuantityExceedsLimit()
```
-Cannot query the balance for the zero address.
+The `quantity` minted with ERC2309 exceeds the safety limit.
@@ -1592,6 +1524,17 @@ The token does not exist.
+### OwnershipNotInitializedForExtraData
+
+```solidity
+error OwnershipNotInitializedForExtraData()
+```
+
+The `extraData` cannot be set on an unintialized ownership slot.
+
+
+
+
### TransferCallerNotOwnerNorApproved
```solidity
diff --git a/docs/TokenBoundAccount.md b/docs/TokenBoundAccount.md
new file mode 100644
index 000000000..79bab9889
--- /dev/null
+++ b/docs/TokenBoundAccount.md
@@ -0,0 +1,746 @@
+# TokenBoundAccount
+
+
+
+
+
+
+
+
+
+## Methods
+
+### addDeposit
+
+```solidity
+function addDeposit() external payable
+```
+
+Deposit funds for this account in Entrypoint.
+
+
+
+
+### contractURI
+
+```solidity
+function contractURI() external view returns (string)
+```
+
+Returns the contract metadata URI.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | string | undefined |
+
+### entryPoint
+
+```solidity
+function entryPoint() external view returns (contract IEntryPoint)
+```
+
+Returns the EIP 4337 entrypoint contract.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | contract IEntryPoint | undefined |
+
+### execute
+
+```solidity
+function execute(address _target, uint256 _value, bytes _calldata) external nonpayable
+```
+
+Executes a transaction (called directly from an admin, or by entryPoint)
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _target | address | undefined |
+| _value | uint256 | undefined |
+| _calldata | bytes | undefined |
+
+### executeBatch
+
+```solidity
+function executeBatch(address[] _target, uint256[] _value, bytes[] _calldata) external nonpayable
+```
+
+Executes a sequence transaction (called directly from an admin, or by entryPoint)
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _target | address[] | undefined |
+| _value | uint256[] | undefined |
+| _calldata | bytes[] | undefined |
+
+### executeCall
+
+```solidity
+function executeCall(address to, uint256 value, bytes data) external payable returns (bytes result)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| to | address | undefined |
+| value | uint256 | undefined |
+| data | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| result | bytes | undefined |
+
+### factory
+
+```solidity
+function factory() external view returns (address)
+```
+
+EIP 4337 factory for this contract.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+### getAllActiveSigners
+
+```solidity
+function getAllActiveSigners() external view returns (struct IAccountPermissions.SignerPermissions[] signers)
+```
+
+Returns all signers with active permissions to use the account.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| signers | IAccountPermissions.SignerPermissions[] | undefined |
+
+### getAllAdmins
+
+```solidity
+function getAllAdmins() external view returns (address[])
+```
+
+Returns all admins of the account.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address[] | undefined |
+
+### getAllSigners
+
+```solidity
+function getAllSigners() external view returns (struct IAccountPermissions.SignerPermissions[] signers)
+```
+
+Returns all active and inactive signers of the account.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| signers | IAccountPermissions.SignerPermissions[] | undefined |
+
+### getDeposit
+
+```solidity
+function getDeposit() external view returns (uint256)
+```
+
+Returns the balance of the account in Entrypoint.
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### getNonce
+
+```solidity
+function getNonce() external view returns (uint256)
+```
+
+Return the account nonce. This method returns the next sequential nonce. For a nonce of a specific key, use `entrypoint.getNonce(account, key)`
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### getPermissionsForSigner
+
+```solidity
+function getPermissionsForSigner(address signer) external view returns (struct IAccountPermissions.SignerPermissions)
+```
+
+Returns the restrictions under which a signer can use the smart wallet.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| signer | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | IAccountPermissions.SignerPermissions | undefined |
+
+### initialize
+
+```solidity
+function initialize(address _defaultAdmin, bytes) external nonpayable
+```
+
+Initializes the smart contract wallet.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _defaultAdmin | address | undefined |
+| _1 | bytes | undefined |
+
+### isActiveSigner
+
+```solidity
+function isActiveSigner(address signer) external view returns (bool)
+```
+
+Returns whether the given account is an active signer on the account.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| signer | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### isAdmin
+
+```solidity
+function isAdmin(address _account) external view returns (bool)
+```
+
+Returns whether the given account is an admin.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _account | address | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### isValidSignature
+
+```solidity
+function isValidSignature(bytes32 _hash, bytes _signature) external view returns (bytes4 magicValue)
+```
+
+See EIP-1271
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _hash | bytes32 | undefined |
+| _signature | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| magicValue | bytes4 | undefined |
+
+### isValidSigner
+
+```solidity
+function isValidSigner(address _signer, UserOperation) external view returns (bool)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _signer | address | undefined |
+| _1 | UserOperation | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### multicall
+
+```solidity
+function multicall(bytes[] data) external nonpayable returns (bytes[] results)
+```
+
+Receives and executes a batch of function calls on this contract.
+
+*Receives and executes a batch of function calls on this contract.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| data | bytes[] | The bytes data that makes up the batch of function calls to execute. |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| results | bytes[] | The bytes data that makes up the result of the batch of function calls executed. |
+
+### nonce
+
+```solidity
+function nonce() external view returns (uint256)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | uint256 | undefined |
+
+### onERC1155BatchReceived
+
+```solidity
+function onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) external nonpayable returns (bytes4)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+| _1 | address | undefined |
+| _2 | uint256[] | undefined |
+| _3 | uint256[] | undefined |
+| _4 | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bytes4 | undefined |
+
+### onERC1155Received
+
+```solidity
+function onERC1155Received(address, address, uint256, uint256, bytes) external nonpayable returns (bytes4)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+| _1 | address | undefined |
+| _2 | uint256 | undefined |
+| _3 | uint256 | undefined |
+| _4 | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bytes4 | undefined |
+
+### onERC721Received
+
+```solidity
+function onERC721Received(address, address, uint256, bytes) external nonpayable returns (bytes4)
+```
+
+
+
+*See {IERC721Receiver-onERC721Received}. Always returns `IERC721Receiver.onERC721Received.selector`.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+| _1 | address | undefined |
+| _2 | uint256 | undefined |
+| _3 | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bytes4 | undefined |
+
+### owner
+
+```solidity
+function owner() external view returns (address)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | address | undefined |
+
+### setAdmin
+
+```solidity
+function setAdmin(address _account, bool _isAdmin) external nonpayable
+```
+
+Adds / removes an account as an admin.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _account | address | undefined |
+| _isAdmin | bool | undefined |
+
+### setContractURI
+
+```solidity
+function setContractURI(string _uri) external nonpayable
+```
+
+Lets a contract admin set the URI for contract-level metadata.
+
+*Caller should be authorized to setup contractURI, e.g. contract admin. See {_canSetContractURI}. Emits {ContractURIUpdated Event}.*
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _uri | string | keccak256 hash of the role. e.g. keccak256("TRANSFER_ROLE") |
+
+### setPermissionsForSigner
+
+```solidity
+function setPermissionsForSigner(IAccountPermissions.SignerPermissionRequest _req, bytes _signature) external nonpayable
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| _req | IAccountPermissions.SignerPermissionRequest | undefined |
+| _signature | bytes | undefined |
+
+### supportsInterface
+
+```solidity
+function supportsInterface(bytes4 interfaceId) external view returns (bool)
+```
+
+See {IERC165-supportsInterface}.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| interfaceId | bytes4 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| _0 | bool | undefined |
+
+### token
+
+```solidity
+function token() external view returns (uint256 chainId, address tokenContract, uint256 tokenId)
+```
+
+
+
+
+
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| chainId | uint256 | undefined |
+| tokenContract | address | undefined |
+| tokenId | uint256 | undefined |
+
+### validateUserOp
+
+```solidity
+function validateUserOp(UserOperation userOp, bytes32 userOpHash, uint256 missingAccountFunds) external nonpayable returns (uint256 validationData)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| userOp | UserOperation | undefined |
+| userOpHash | bytes32 | undefined |
+| missingAccountFunds | uint256 | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| validationData | uint256 | undefined |
+
+### verifySignerPermissionRequest
+
+```solidity
+function verifySignerPermissionRequest(IAccountPermissions.SignerPermissionRequest req, bytes signature) external view returns (bool success, address signer)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| req | IAccountPermissions.SignerPermissionRequest | undefined |
+| signature | bytes | undefined |
+
+#### Returns
+
+| Name | Type | Description |
+|---|---|---|
+| success | bool | undefined |
+| signer | address | undefined |
+
+### withdrawDepositTo
+
+```solidity
+function withdrawDepositTo(address payable withdrawAddress, uint256 amount) external nonpayable
+```
+
+Withdraw funds for this account from Entrypoint.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| withdrawAddress | address payable | undefined |
+| amount | uint256 | undefined |
+
+
+
+## Events
+
+### AdminUpdated
+
+```solidity
+event AdminUpdated(address indexed signer, bool isAdmin)
+```
+
+Emitted when an admin is set or removed.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| signer `indexed` | address | undefined |
+| isAdmin | bool | undefined |
+
+### ContractURIUpdated
+
+```solidity
+event ContractURIUpdated(string prevURI, string newURI)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| prevURI | string | undefined |
+| newURI | string | undefined |
+
+### Initialized
+
+```solidity
+event Initialized(uint8 version)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| version | uint8 | undefined |
+
+### SignerPermissionsUpdated
+
+```solidity
+event SignerPermissionsUpdated(address indexed authorizingSigner, address indexed targetSigner, IAccountPermissions.SignerPermissionRequest permissions)
+```
+
+Emitted when permissions for a signer are updated.
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| authorizingSigner `indexed` | address | undefined |
+| targetSigner `indexed` | address | undefined |
+| permissions | IAccountPermissions.SignerPermissionRequest | undefined |
+
+### TokenBoundAccountCreated
+
+```solidity
+event TokenBoundAccountCreated(address indexed account, bytes indexed data)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| account `indexed` | address | undefined |
+| data `indexed` | bytes | undefined |
+
+### TransactionExecuted
+
+```solidity
+event TransactionExecuted(address indexed target, uint256 indexed value, bytes data)
+```
+
+
+
+
+
+#### Parameters
+
+| Name | Type | Description |
+|---|---|---|
+| target `indexed` | address | undefined |
+| value `indexed` | uint256 | undefined |
+| data | bytes | undefined |
+
+
+
diff --git a/gasreport.txt b/gasreport.txt
index f61d596c2..62dca4240 100644
--- a/gasreport.txt
+++ b/gasreport.txt
@@ -1,96 +1,96 @@
No files changed, compilation skipped
Running 3 tests for src/test/benchmark/EditionStakeBenchmark.t.sol:EditionStakeBenchmarkTest
-[32m[PASS][0m test_benchmark_editionStake_claimRewards() (gas: 67222)
-[32m[PASS][0m test_benchmark_editionStake_stake() (gas: 214264)
-[32m[PASS][0m test_benchmark_editionStake_withdraw() (gas: 49437)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 1.08s
+[32m[PASS][0m test_benchmark_editionStake_claimRewards() (gas: 65580)
+[32m[PASS][0m test_benchmark_editionStake_stake() (gas: 185145)
+[32m[PASS][0m test_benchmark_editionStake_withdraw() (gas: 46326)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 468.09ms
Running 5 tests for src/test/benchmark/SignatureDropBenchmark.t.sol:SignatureDropBenchmarkTest
-[32m[PASS][0m test_bechmark_signatureDrop_claim_five_tokens() (gas: 141434)
-[32m[PASS][0m test_bechmark_signatureDrop_setClaimConditions() (gas: 73754)
-[32m[PASS][0m test_benchmark_signatureDrop_lazyMint() (gas: 124617)
-[32m[PASS][0m test_benchmark_signatureDrop_lazyMint_for_delayed_reveal() (gas: 226206)
-[32m[PASS][0m test_benchmark_signatureDrop_reveal() (gas: 9223372036854754743)
-Test result: [32mok[0m. 5 passed; 0 failed; finished in 1.09s
+[32m[PASS][0m test_bechmark_signatureDrop_claim_five_tokens() (gas: 141456)
+[32m[PASS][0m test_bechmark_signatureDrop_setClaimConditions() (gas: 73774)
+[32m[PASS][0m test_benchmark_signatureDrop_lazyMint() (gas: 124639)
+[32m[PASS][0m test_benchmark_signatureDrop_lazyMint_for_delayed_reveal() (gas: 226228)
+[32m[PASS][0m test_benchmark_signatureDrop_reveal() (gas: 9183)
+Test result: [32mok[0m. 5 passed; 0 failed; finished in 468.49ms
Running 3 tests for src/test/benchmark/NFTStakeBenchmark.t.sol:NFTStakeBenchmarkTest
-[32m[PASS][0m test_benchmark_nftStake_claimRewards() (gas: 66461)
-[32m[PASS][0m test_benchmark_nftStake_stake_five_tokens() (gas: 617427)
-[32m[PASS][0m test_benchmark_nftStake_withdraw() (gas: 9223372036854754743)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 1.09s
+[32m[PASS][0m test_benchmark_nftStake_claimRewards() (gas: 68826)
+[32m[PASS][0m test_benchmark_nftStake_stake_five_tokens() (gas: 549421)
+[32m[PASS][0m test_benchmark_nftStake_withdraw() (gas: 39648)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 468.46ms
+
+Running 4 tests for src/test/benchmark/TokenERC1155Benchmark.t.sol:TokenERC1155BenchmarkTest
+[32m[PASS][0m test_benchmark_tokenERC1155_burn() (gas: 5744)
+[32m[PASS][0m test_benchmark_tokenERC1155_mintTo() (gas: 121028)
+[32m[PASS][0m test_benchmark_tokenERC1155_mintWithSignature_pay_with_ERC20() (gas: 263757)
+[32m[PASS][0m test_benchmark_tokenERC1155_mintWithSignature_pay_with_native_token() (gas: 292255)
+Test result: [32mok[0m. 4 passed; 0 failed; finished in 469.08ms
Running 3 tests for src/test/benchmark/PackBenchmark.t.sol:PackBenchmarkTest
-[32m[PASS][0m test_benchmark_pack_addPackContents() (gas: 219427)
-[32m[PASS][0m test_benchmark_pack_createPack() (gas: 1416215)
-[32m[PASS][0m test_benchmark_pack_openPack() (gas: 170258)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 1.09s
+[32m[PASS][0m test_benchmark_pack_addPackContents() (gas: 219449)
+[32m[PASS][0m test_benchmark_pack_createPack() (gas: 1425232)
+[32m[PASS][0m test_benchmark_pack_openPack() (gas: 170278)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 469.74ms
Running 2 tests for src/test/benchmark/MultiwrapBenchmark.t.sol:MultiwrapBenchmarkTest
-[32m[PASS][0m test_benchmark_multiwrap_unwrap() (gas: 92386)
-[32m[PASS][0m test_benchmark_multiwrap_wrap() (gas: 475292)
-Test result: [32mok[0m. 2 passed; 0 failed; finished in 1.10s
-
-Running 4 tests for src/test/benchmark/TokenERC1155Benchmark.t.sol:TokenERC1155BenchmarkTest
-[32m[PASS][0m test_benchmark_tokenERC1155_burn() (gas: 5728)
-[32m[PASS][0m test_benchmark_tokenERC1155_mintTo() (gas: 121006)
-[32m[PASS][0m test_benchmark_tokenERC1155_mintWithSignature_pay_with_ERC20() (gas: 263735)
-[32m[PASS][0m test_benchmark_tokenERC1155_mintWithSignature_pay_with_native_token() (gas: 292233)
-Test result: [32mok[0m. 4 passed; 0 failed; finished in 1.11s
+[32m[PASS][0m test_benchmark_multiwrap_unwrap() (gas: 92404)
+[32m[PASS][0m test_benchmark_multiwrap_wrap() (gas: 475314)
+Test result: [32mok[0m. 2 passed; 0 failed; finished in 476.27ms
Running 1 test for src/test/benchmark/AirdropERC20Benchmark.t.sol:AirdropERC20BenchmarkTest
-[32m[PASS][0m test_benchmark_airdropERC20_airdrop() (gas: 32179335)
-Test result: [32mok[0m. 1 passed; 0 failed; finished in 1.11s
+[32m[PASS][0m test_benchmark_airdropERC20_airdrop() (gas: 32173710)
+Test result: [32mok[0m. 1 passed; 0 failed; finished in 491.93ms
Running 1 test for src/test/benchmark/AirdropERC1155Benchmark.t.sol:AirdropERC1155BenchmarkTest
-[32m[PASS][0m test_benchmark_airdropERC1155_airdrop() (gas: 38082296)
-Test result: [32mok[0m. 1 passed; 0 failed; finished in 1.13s
+[32m[PASS][0m test_benchmark_airdropERC1155_airdrop() (gas: 38084693)
+Test result: [32mok[0m. 1 passed; 0 failed; finished in 492.70ms
Running 1 test for src/test/benchmark/AirdropERC721Benchmark.t.sol:AirdropERC721BenchmarkTest
-[32m[PASS][0m test_benchmark_airdropERC721_airdrop() (gas: 43896326)
-Test result: [32mok[0m. 1 passed; 0 failed; finished in 1.15s
+[32m[PASS][0m test_benchmark_airdropERC721_airdrop() (gas: 43898701)
+Test result: [32mok[0m. 1 passed; 0 failed; finished in 498.05ms
-Running 3 tests for src/test/benchmark/PackVRFDirectBenchmark.t.sol:PackVRFDirectBenchmarkTest
-[32m[PASS][0m test_benchmark_packvrf_createPack() (gas: 1391844)
-[32m[PASS][0m test_benchmark_packvrf_openPack() (gas: 119961)
-[32m[PASS][0m test_benchmark_packvrf_openPackAndClaimRewards() (gas: 140350)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 162.19ms
+Running 3 tests for src/test/benchmark/TokenERC20Benchmark.t.sol:TokenERC20BenchmarkTest
+[32m[PASS][0m test_benchmark_tokenERC20_mintTo() (gas: 118533)
+[32m[PASS][0m test_benchmark_tokenERC20_mintWithSignature_pay_with_ERC20() (gas: 181738)
+[32m[PASS][0m test_benchmark_tokenERC20_mintWithSignature_pay_with_native_token() (gas: 206150)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 145.19ms
Running 3 tests for src/test/benchmark/TokenStakeBenchmark.t.sol:TokenStakeBenchmarkTest
-[32m[PASS][0m test_benchmark_tokenStake_claimRewards() (gas: 73676)
-[32m[PASS][0m test_benchmark_tokenStake_stake() (gas: 181762)
-[32m[PASS][0m test_benchmark_tokenStake_withdraw() (gas: 55520)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 148.05ms
+[32m[PASS][0m test_benchmark_tokenStake_claimRewards() (gas: 68065)
+[32m[PASS][0m test_benchmark_tokenStake_stake() (gas: 178011)
+[32m[PASS][0m test_benchmark_tokenStake_withdraw() (gas: 47890)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 147.70ms
-Running 4 tests for src/test/benchmark/TokenERC721Benchmark.t.sol:TokenERC721BenchmarkTest
-[32m[PASS][0m test_benchmark_tokenERC721_burn() (gas: 10393)
-[32m[PASS][0m test_benchmark_tokenERC721_mintTo() (gas: 149955)
-[32m[PASS][0m test_benchmark_tokenERC721_mintWithSignature_pay_with_ERC20() (gas: 259360)
-[32m[PASS][0m test_benchmark_tokenERC721_mintWithSignature_pay_with_native_token() (gas: 283702)
-Test result: [32mok[0m. 4 passed; 0 failed; finished in 157.71ms
+Running 3 tests for src/test/benchmark/PackVRFDirectBenchmark.t.sol:PackVRFDirectBenchmarkTest
+[32m[PASS][0m test_benchmark_packvrf_createPack() (gas: 1391866)
+[32m[PASS][0m test_benchmark_packvrf_openPack() (gas: 119981)
+[32m[PASS][0m test_benchmark_packvrf_openPackAndClaimRewards() (gas: 3621)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 153.05ms
-Running 3 tests for src/test/benchmark/TokenERC20Benchmark.t.sol:TokenERC20BenchmarkTest
-[32m[PASS][0m test_benchmark_tokenERC20_mintTo() (gas: 118511)
-[32m[PASS][0m test_benchmark_tokenERC20_mintWithSignature_pay_with_ERC20() (gas: 181716)
-[32m[PASS][0m test_benchmark_tokenERC20_mintWithSignature_pay_with_native_token() (gas: 206128)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 159.72ms
+Running 4 tests for src/test/benchmark/TokenERC721Benchmark.t.sol:TokenERC721BenchmarkTest
+[32m[PASS][0m test_benchmark_tokenERC721_burn() (gas: 10411)
+[32m[PASS][0m test_benchmark_tokenERC721_mintTo() (gas: 149977)
+[32m[PASS][0m test_benchmark_tokenERC721_mintWithSignature_pay_with_ERC20() (gas: 259382)
+[32m[PASS][0m test_benchmark_tokenERC721_mintWithSignature_pay_with_native_token() (gas: 283724)
+Test result: [32mok[0m. 4 passed; 0 failed; finished in 160.72ms
Running 3 tests for src/test/benchmark/DropERC1155Benchmark.t.sol:DropERC1155BenchmarkTest
-[32m[PASS][0m test_bechmark_dropERC1155_claim() (gas: 186646)
-[32m[PASS][0m test_bechmark_dropERC1155_setClaimConditions_five_conditions() (gas: 492311)
-[32m[PASS][0m test_benchmark_dropERC1155_lazyMint() (gas: 123851)
-Test result: [32mok[0m. 3 passed; 0 failed; finished in 1.37s
-
-Running 2 tests for src/test/benchmark/DropERC20Benchmark.t.sol:DropERC20BenchmarkTest
-[32m[PASS][0m test_bechmark_dropERC20_claim() (gas: 230419)
-[32m[PASS][0m test_bechmark_dropERC20_setClaimConditions_five_conditions() (gas: 501025)
-Test result: [32mok[0m. 2 passed; 0 failed; finished in 387.05ms
+[32m[PASS][0m test_bechmark_dropERC1155_claim() (gas: 186668)
+[32m[PASS][0m test_bechmark_dropERC1155_setClaimConditions_five_conditions() (gas: 492331)
+[32m[PASS][0m test_benchmark_dropERC1155_lazyMint() (gas: 123873)
+Test result: [32mok[0m. 3 passed; 0 failed; finished in 758.20ms
Running 5 tests for src/test/benchmark/DropERC721Benchmark.t.sol:DropERC721BenchmarkTest
-[32m[PASS][0m test_bechmark_dropERC721_claim_five_tokens() (gas: 211945)
-[32m[PASS][0m test_bechmark_dropERC721_setClaimConditions_five_conditions() (gas: 500839)
-[32m[PASS][0m test_benchmark_dropERC721_lazyMint() (gas: 124522)
-[32m[PASS][0m test_benchmark_dropERC721_lazyMint_for_delayed_reveal() (gas: 217107)
-[32m[PASS][0m test_benchmark_dropERC721_reveal() (gas: 9223372036854754743)
-Test result: [32mok[0m. 5 passed; 0 failed; finished in 578.70ms
+[32m[PASS][0m test_bechmark_dropERC721_claim_five_tokens() (gas: 211967)
+[32m[PASS][0m test_bechmark_dropERC721_setClaimConditions_five_conditions() (gas: 500859)
+[32m[PASS][0m test_benchmark_dropERC721_lazyMint() (gas: 124544)
+[32m[PASS][0m test_benchmark_dropERC721_lazyMint_for_delayed_reveal() (gas: 226124)
+[32m[PASS][0m test_benchmark_dropERC721_reveal() (gas: 8800)
+Test result: [32mok[0m. 5 passed; 0 failed; finished in 366.44ms
+
+Running 2 tests for src/test/benchmark/DropERC20Benchmark.t.sol:DropERC20BenchmarkTest
+[32m[PASS][0m test_bechmark_dropERC20_claim() (gas: 230441)
+[32m[PASS][0m test_bechmark_dropERC20_setClaimConditions_five_conditions() (gas: 501045)
+Test result: [32mok[0m. 2 passed; 0 failed; finished in 373.94ms
diff --git a/lib/chainlink b/lib/chainlink
index 9d5ec20aa..c272befd7 160000
--- a/lib/chainlink
+++ b/lib/chainlink
@@ -1 +1 @@
-Subproject commit 9d5ec20aa7c03c5f08722fa88f621075d300dcc1
+Subproject commit c272befd714d827c890582d74df838345ed1caa7
diff --git a/package.json b/package.json
index 9fd54e134..f64a7b285 100644
--- a/package.json
+++ b/package.json
@@ -54,19 +54,20 @@
"typescript": "^4.4.4"
},
"scripts": {
- "clean": "hardhat clean && rm -rf abi/ && rm -rf artifacts/ && rm -rf dist/ && rm -rf typechain/",
- "compile": "hardhat compile",
+ "clean": "forge clean && rm -rf abi/ && rm -rf artifacts_forge/ && rm -rf dist/ && rm -rf typechain/",
+ "compile": "forge build",
"lint": "solhint \"contracts/**/*.sol\"",
"prettier": "prettier --config .prettierrc --write \"{contracts,src}/**/*.{js,json,sol,ts}\"",
"prettier:list-different": "prettier --config .prettierrc --list-different \"**/*.{js,json,sol,ts}\"",
"prettier:contracts": "prettier --config .prettierrc --list-different \"{contracts,src}/**/*.sol\"",
- "test": "hardhat test",
- "typechain": "hardhat typechain",
+ "test": "forge test",
+ "typechain": "typechain --target ethers-v5 --out-dir ./typechain artifacts_forge/**/*.json",
"build": "yarn clean && yarn compile",
"forge:build": "forge build --hardhat",
"forge:test": "forge test --hardhat",
"export-abi": "hardhat export-abi",
"gas": "forge test --mc Benchmark --gas-report > gasreport.txt",
"forge:snapshot": "forge snapshot --check"
- }
+ },
+ "dependencies": {}
}
diff --git a/release.sh b/release.sh
index 6af49096d..5f2d6a6ea 100755
--- a/release.sh
+++ b/release.sh
@@ -35,9 +35,7 @@ echo "### Build finished. Copying abis."
rm -rf contracts/abi
mkdir -p contracts/abi
# copy all abis to contracts/abi
-find artifacts/contracts ! -iregex ".*([a-zA-Z0-9_]).json" -exec cp {} contracts/abi 2>/dev/null \;
-# remove non-abi files
-rm contracts/abi/*.dbg.json
+find artifacts_forge ! -iregex ".*([a-zA-Z0-9_]).json" -exec cp {} contracts/abi 2>/dev/null \;
echo "### Copying README."
# copy root README to contracts folder
cp README.md contracts/README.md
diff --git a/src/test/LoyaltyCard.t.sol b/src/test/LoyaltyCard.t.sol
index 7bd1b5c30..8504831d3 100644
--- a/src/test/LoyaltyCard.t.sol
+++ b/src/test/LoyaltyCard.t.sol
@@ -313,8 +313,6 @@ contract LoyaltyCardTest is BaseTest {
_mintrequest.currency = address(erc20);
_signature = signMintRequest(_mintrequest, privateKey);
- uint256 erc20BalanceOfSeller = erc20.balanceOf(address(saleRecipient));
-
vm.prank(recipient);
erc20.approve(address(loyaltyCard), 5);
diff --git a/src/test/OpenEditionERC721.t.sol b/src/test/OpenEditionERC721.t.sol
index f1dec21b3..c9bdb2f91 100644
--- a/src/test/OpenEditionERC721.t.sol
+++ b/src/test/OpenEditionERC721.t.sol
@@ -44,9 +44,7 @@ contract OpenEditionERC721Test is BaseTest {
forwarders(),
saleRecipient,
royaltyRecipient,
- royaltyBps,
- platformFeeBps,
- platformFeeRecipient
+ royaltyBps
)
)
)
@@ -161,71 +159,6 @@ contract OpenEditionERC721Test is BaseTest {
vm.stopPrank();
}
- /**
- * @dev Tests contract state for Transfer role.
- */
- function test_state_getRoleMember_transferRole() public {
- bytes32 role = keccak256("TRANSFER_ROLE");
-
- uint256 roleMemberCount = openEdition.getRoleMemberCount(role);
- assertEq(roleMemberCount, 2);
-
- address roleMember = openEdition.getRoleMember(role, 1);
- assertEq(roleMember, address(0));
-
- vm.startPrank(deployer);
- openEdition.grantRole(role, address(2));
- openEdition.grantRole(role, address(3));
- openEdition.grantRole(role, address(4));
-
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
-
- openEdition.revokeRole(role, address(2));
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
-
- openEdition.revokeRole(role, address(0));
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
-
- openEdition.grantRole(role, address(5));
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
-
- openEdition.grantRole(role, address(0));
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
-
- openEdition.grantRole(role, address(6));
- roleMemberCount = openEdition.getRoleMemberCount(role);
- console.log(roleMemberCount);
- for (uint256 i = 0; i < roleMemberCount; i++) {
- console.log(openEdition.getRoleMember(role, i));
- }
- console.log("");
- }
-
/**
* note: Testing transfer of tokens when transfer-role is restricted
*/
@@ -258,25 +191,6 @@ contract OpenEditionERC721Test is BaseTest {
openEdition.transferFrom(receiver, address(123), 1);
}
- /**
- * @dev Tests whether role member count is incremented correctly.
- */
- function test_member_count_incremented_properly_when_role_granted() public {
- bytes32 role = keccak256("ABC_ROLE");
- address receiver = getActor(0);
-
- vm.startPrank(deployer);
- uint256 roleMemberCount = openEdition.getRoleMemberCount(role);
-
- assertEq(roleMemberCount, 0);
-
- openEdition.grantRole(role, receiver);
-
- assertEq(openEdition.getRoleMemberCount(role), 1);
-
- vm.stopPrank();
- }
-
function test_claimCondition_with_startTimestamp() public {
vm.warp(1);
diff --git a/src/test/airdrop/AirdropERC1155.t.sol b/src/test/airdrop/AirdropERC1155.t.sol
index 640aaf807..b0901b14b 100644
--- a/src/test/airdrop/AirdropERC1155.t.sol
+++ b/src/test/airdrop/AirdropERC1155.t.sol
@@ -135,7 +135,7 @@ contract AirdropERC1155GasTest is BaseTest {
uint256,
uint256,
bytes calldata
- ) external returns (bytes4) {
+ ) external pure returns (bytes4) {
return this.onERC1155Received.selector;
}
}
diff --git a/src/test/airdrop/AirdropERC20.t.sol b/src/test/airdrop/AirdropERC20.t.sol
index 6cec0e266..d60a8ebf6 100644
--- a/src/test/airdrop/AirdropERC20.t.sol
+++ b/src/test/airdrop/AirdropERC20.t.sol
@@ -150,25 +150,38 @@ contract AirdropERC20GasTest is BaseTest {
function test_transferNativeToken_toEOA() public {
vm.prank(address(tokenOwner));
- address(0x123).call{ value: 1 ether }("");
+ (bool success, bytes memory data) = address(0x123).call{ value: 1 ether }("");
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
}
function test_transferNativeToken_toContract() public {
vm.prank(address(tokenOwner));
- address(this).call{ value: 1 ether }("");
+ (bool success, bytes memory data) = address(this).call{ value: 1 ether }("");
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
}
function test_transferNativeToken_toEOA_gasOverride() public {
vm.prank(address(tokenOwner));
console.log(gasleft());
- address(0x123).call{ value: 1 ether, gas: 100_000 }("");
+ (bool success, bytes memory data) = address(0x123).call{ value: 1 ether, gas: 100_000 }("");
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
+
console.log(gasleft());
}
function test_transferNativeToken_toContract_gasOverride() public {
vm.prank(address(tokenOwner));
console.log(gasleft());
- address(this).call{ value: 1 ether, gas: 100_000 }("");
+ (bool success, bytes memory data) = address(this).call{ value: 1 ether, gas: 100_000 }("");
console.log(gasleft());
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
}
}
diff --git a/src/test/airdrop/AirdropERC721.t.sol b/src/test/airdrop/AirdropERC721.t.sol
index 1f7157108..379c92b27 100644
--- a/src/test/airdrop/AirdropERC721.t.sol
+++ b/src/test/airdrop/AirdropERC721.t.sol
@@ -116,7 +116,7 @@ contract AirdropERC721GasTest is BaseTest {
address,
uint256,
bytes calldata
- ) external view returns (bytes4) {
+ ) external pure returns (bytes4) {
return this.onERC721Received.selector;
}
}
diff --git a/src/test/benchmark/DropERC1155Benchmark.t.sol b/src/test/benchmark/DropERC1155Benchmark.t.sol
index a73c9041a..a4d61e6a1 100644
--- a/src/test/benchmark/DropERC1155Benchmark.t.sol
+++ b/src/test/benchmark/DropERC1155Benchmark.t.sol
@@ -111,8 +111,6 @@ contract DropERC1155BenchmarkTest is BaseTest {
vm.warp(1);
- address receiver = address(0x92Bb439374a091c7507bE100183d8D1Ed2c9dAD3); // in allowlist
-
DropERC1155.ClaimCondition[] memory conditions = new DropERC1155.ClaimCondition[](5);
conditions[0].maxClaimableSupply = 500;
conditions[0].quantityLimitPerWallet = 10;
diff --git a/src/test/benchmark/DropERC20Benchmark.t.sol b/src/test/benchmark/DropERC20Benchmark.t.sol
index 28f492c82..cdbe7be37 100644
--- a/src/test/benchmark/DropERC20Benchmark.t.sol
+++ b/src/test/benchmark/DropERC20Benchmark.t.sol
@@ -55,8 +55,6 @@ contract DropERC20BenchmarkTest is BaseTest {
vm.warp(1);
- address receiver = address(0x92Bb439374a091c7507bE100183d8D1Ed2c9dAD3); // in allowlist
-
DropERC20.ClaimCondition[] memory conditions = new DropERC20.ClaimCondition[](5);
conditions[0].maxClaimableSupply = 500 ether;
conditions[0].quantityLimitPerWallet = 10 ether;
diff --git a/src/test/benchmark/DropERC721Benchmark.t.sol b/src/test/benchmark/DropERC721Benchmark.t.sol
index c060f3e57..d5d98df9e 100644
--- a/src/test/benchmark/DropERC721Benchmark.t.sol
+++ b/src/test/benchmark/DropERC721Benchmark.t.sol
@@ -109,8 +109,6 @@ contract DropERC721BenchmarkTest is BaseTest {
vm.warp(1);
- address receiver = address(0x92Bb439374a091c7507bE100183d8D1Ed2c9dAD3); // in allowlist
-
DropERC721.ClaimCondition[] memory conditions = new DropERC721.ClaimCondition[](5);
conditions[0].maxClaimableSupply = 500;
conditions[0].quantityLimitPerWallet = 10;
@@ -153,8 +151,6 @@ contract DropERC721BenchmarkTest is BaseTest {
bytes memory encryptedBaseURI = "encryptedBaseURI://";
bytes32 provenanceHash = bytes32("whatever");
- uint256 nextTokenIdToMintBefore = drop.nextTokenIdToMint();
-
vm.prank(deployer);
vm.resumeGasMetering();
drop.lazyMint(amountToLazyMint, baseURI, abi.encode(encryptedBaseURI, provenanceHash));
@@ -174,6 +170,7 @@ contract DropERC721BenchmarkTest is BaseTest {
drop.lazyMint(amountToLazyMint, placeholderURI, abi.encode(encryptedURI, provenanceHash));
vm.prank(deployer);
+ vm.resumeGasMetering();
drop.reveal(0, key);
}
diff --git a/src/test/benchmark/EditionStakeBenchmark.t.sol b/src/test/benchmark/EditionStakeBenchmark.t.sol
index 6e988b070..91aee909d 100644
--- a/src/test/benchmark/EditionStakeBenchmark.t.sol
+++ b/src/test/benchmark/EditionStakeBenchmark.t.sol
@@ -70,13 +70,11 @@ contract EditionStakeBenchmarkTest is BaseTest {
// stake 50 tokens with token-id 0
vm.prank(stakerOne);
stakeContract.stake(0, 50);
- uint256 timeOfLastUpdate_one = block.timestamp;
//=================== warp timestamp to claim rewards
vm.roll(100);
vm.warp(1000);
- uint256 rewardBalanceBefore = stakeContract.getRewardTokenBalance();
vm.prank(stakerOne);
vm.resumeGasMetering();
stakeContract.claimRewards(0);
@@ -92,8 +90,6 @@ contract EditionStakeBenchmarkTest is BaseTest {
vm.prank(stakerTwo);
stakeContract.stake(1, 20);
- uint256 timeOfLastUpdate = block.timestamp;
-
//========== warp timestamp before withdraw
vm.roll(100);
vm.warp(1000);
diff --git a/src/test/benchmark/NFTStakeBenchmark.t.sol b/src/test/benchmark/NFTStakeBenchmark.t.sol
index ee72f0916..4ffb5ad17 100644
--- a/src/test/benchmark/NFTStakeBenchmark.t.sol
+++ b/src/test/benchmark/NFTStakeBenchmark.t.sol
@@ -78,13 +78,10 @@ contract NFTStakeBenchmarkTest is BaseTest {
// stake 3 tokens
vm.prank(stakerOne);
stakeContract.stake(_tokenIdsOne);
- uint256 timeOfLastUpdate_one = block.timestamp;
//=================== warp timestamp to claim rewards
vm.roll(100);
vm.warp(1000);
-
- uint256 rewardBalanceBefore = stakeContract.getRewardTokenBalance();
vm.prank(stakerOne);
vm.resumeGasMetering();
stakeContract.claimRewards();
@@ -111,6 +108,7 @@ contract NFTStakeBenchmarkTest is BaseTest {
_tokensToWithdraw[0] = 1;
vm.prank(stakerOne);
+ vm.resumeGasMetering();
stakeContract.withdraw(_tokensToWithdraw);
}
diff --git a/src/test/benchmark/PackBenchmark.t.sol b/src/test/benchmark/PackBenchmark.t.sol
index 786223012..3aa7975a0 100644
--- a/src/test/benchmark/PackBenchmark.t.sol
+++ b/src/test/benchmark/PackBenchmark.t.sol
@@ -179,7 +179,6 @@ contract PackBenchmarkTest is BaseTest {
function test_benchmark_pack_createPack() public {
vm.pauseGasMetering();
- uint256 packId = pack.nextTokenIdToMint();
address recipient = address(1);
vm.prank(address(tokenOwner));
@@ -214,7 +213,7 @@ contract PackBenchmarkTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
vm.resumeGasMetering();
diff --git a/src/test/benchmark/PackVRFDirectBenchmark.t.sol b/src/test/benchmark/PackVRFDirectBenchmark.t.sol
index aaa5ac3f1..bded43e97 100644
--- a/src/test/benchmark/PackVRFDirectBenchmark.t.sol
+++ b/src/test/benchmark/PackVRFDirectBenchmark.t.sol
@@ -194,16 +194,13 @@ contract PackVRFDirectBenchmarkTest is BaseTest {
function test_benchmark_packvrf_openPackAndClaimRewards() public {
vm.pauseGasMetering();
vm.warp(1000);
- uint256 packId = pack.nextTokenIdToMint();
- uint256 packsToOpen = 3;
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
vm.resumeGasMetering();
- uint256 requestId = pack.openPackAndClaimRewards(packId, packsToOpen, 2_500_000);
}
function test_benchmark_packvrf_openPack() public {
@@ -214,7 +211,7 @@ contract PackVRFDirectBenchmarkTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
vm.resumeGasMetering();
diff --git a/src/test/benchmark/SignatureDropBenchmark.t.sol b/src/test/benchmark/SignatureDropBenchmark.t.sol
index 38ae9637d..e0b620a18 100644
--- a/src/test/benchmark/SignatureDropBenchmark.t.sol
+++ b/src/test/benchmark/SignatureDropBenchmark.t.sol
@@ -86,8 +86,6 @@ contract SignatureDropBenchmarkTest is BaseTest {
function test_bechmark_signatureDrop_setClaimConditions() public {
vm.pauseGasMetering();
vm.warp(1);
-
- address receiver = getActor(0);
bytes32[] memory proofs = new bytes32[](0);
SignatureDrop.AllowlistProof memory alp;
@@ -138,6 +136,7 @@ contract SignatureDropBenchmarkTest is BaseTest {
sigdrop.lazyMint(amountToLazyMint, placeholderURI, abi.encode(encryptedURI, provenanceHash));
vm.prank(deployerSigner);
+ vm.resumeGasMetering();
sigdrop.reveal(0, key);
}
diff --git a/src/test/benchmark/TokenERC1155Benchmark.t.sol b/src/test/benchmark/TokenERC1155Benchmark.t.sol
index 981639ae8..ad863b06c 100644
--- a/src/test/benchmark/TokenERC1155Benchmark.t.sol
+++ b/src/test/benchmark/TokenERC1155Benchmark.t.sol
@@ -169,7 +169,6 @@ contract TokenERC1155BenchmarkTest is BaseTest {
uint256 _amount = 100;
uint256 nextTokenId = tokenContract.nextTokenIdToMint();
- uint256 currentBalanceOfRecipient = tokenContract.balanceOf(recipient, nextTokenId);
vm.prank(deployerSigner);
tokenContract.mintTo(recipient, type(uint256).max, _tokenURI, _amount);
diff --git a/src/test/benchmark/TokenStakeBenchmark.t.sol b/src/test/benchmark/TokenStakeBenchmark.t.sol
index c005aece3..9c63e741e 100644
--- a/src/test/benchmark/TokenStakeBenchmark.t.sol
+++ b/src/test/benchmark/TokenStakeBenchmark.t.sol
@@ -70,13 +70,10 @@ contract TokenStakeBenchmarkTest is BaseTest {
// stake 50 tokens with token-id 0
vm.prank(stakerOne);
stakeContract.stake(400);
- uint256 timeOfLastUpdate_one = block.timestamp;
//=================== warp timestamp to claim rewards
vm.roll(100);
vm.warp(1000);
-
- uint256 rewardBalanceBefore = stakeContract.getRewardTokenBalance();
vm.prank(stakerOne);
vm.resumeGasMetering();
stakeContract.claimRewards();
@@ -92,8 +89,6 @@ contract TokenStakeBenchmarkTest is BaseTest {
vm.prank(stakerTwo);
stakeContract.stake(200);
- uint256 timeOfLastUpdate = block.timestamp;
-
//========== warp timestamp before withdraw
vm.roll(100);
vm.warp(1000);
diff --git a/src/test/marketplace/DirectListings.t.sol b/src/test/marketplace/DirectListings.t.sol
index 46a932503..e6e29126d 100644
--- a/src/test/marketplace/DirectListings.t.sol
+++ b/src/test/marketplace/DirectListings.t.sol
@@ -186,7 +186,7 @@ contract MarketplaceDirectListingsTest is BaseTest {
);
vm.prank(seller);
- uint256 listingId = DirectListingsLogic(marketplace).createListing(listingParams);
+ DirectListingsLogic(marketplace).createListing(listingParams);
// Total listings incremented
assertEq(DirectListingsLogic(marketplace).totalListings(), 1);
@@ -462,11 +462,7 @@ contract MarketplaceDirectListingsTest is BaseTest {
}
function test_royaltyEngine_tokenWithERC2981() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -585,11 +581,7 @@ contract MarketplaceDirectListingsTest is BaseTest {
}
function test_revert_feesExceedTotalPrice() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -2074,9 +2066,7 @@ contract IssueC2_MarketplaceDirectListingsTest is BaseTest {
function test_state_buyFromListing_after_update() public {
(uint256 listingId, IDirectListings.Listing memory listing) = _setup_buyFromListing();
- address buyFor = buyer;
uint256 quantityToBuy = listing.quantity;
- address currency = listing.currency;
uint256 pricePerToken = listing.pricePerToken;
uint256 totalPrice = pricePerToken * quantityToBuy;
diff --git a/src/test/marketplace/EnglishAuctions.t.sol b/src/test/marketplace/EnglishAuctions.t.sol
index 5acec3f7c..94c5fbd0e 100644
--- a/src/test/marketplace/EnglishAuctions.t.sol
+++ b/src/test/marketplace/EnglishAuctions.t.sol
@@ -268,11 +268,7 @@ contract MarketplaceEnglishAuctionsTest is BaseTest {
}
function test_royaltyEngine_tokenWithERC2981() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -407,11 +403,7 @@ contract MarketplaceEnglishAuctionsTest is BaseTest {
}
function test_revert_feesExceedTotalPrice() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -2253,7 +2245,6 @@ contract BreitwieserTheBidder is BaseTest {
// Condition: multiple copies in circulation and attacker has at least 1.
uint256 tokenId = 999;
- uint256 quantity = 2;
// Victim.
erc1155.mint(seller, tokenId, 1);
erc1155.mint(attacker, tokenId, 1);
@@ -2266,7 +2257,7 @@ contract BreitwieserTheBidder is BaseTest {
address currency = address(erc20);
uint256 minimumBidAmount = 1 ether;
uint256 buyoutBidAmount = 10 ether;
- uint256 quantity = 1;
+ uint256 qty = 1;
uint64 timeBufferInSeconds = 10 seconds;
uint64 bidBufferBps = 1000;
uint64 startTimestamp = 0;
@@ -2274,7 +2265,7 @@ contract BreitwieserTheBidder is BaseTest {
auctionParams1 = IEnglishAuctions.AuctionParameters(
assetContract,
tokenId,
- quantity,
+ qty,
currency,
minimumBidAmount,
buyoutBidAmount,
diff --git a/src/test/marketplace/Offers.t.sol b/src/test/marketplace/Offers.t.sol
index b33b2f53d..3f51bf738 100644
--- a/src/test/marketplace/Offers.t.sol
+++ b/src/test/marketplace/Offers.t.sol
@@ -208,11 +208,7 @@ contract MarketplaceOffersTest is BaseTest {
}
function test_royaltyEngine_tokenWithERC2981() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -332,11 +328,7 @@ contract MarketplaceOffersTest is BaseTest {
}
function test_revert_feesExceedTotalPrice() public {
- (
- MockRoyaltyEngineV1 royaltyEngine,
- address payable[] memory customRoyaltyRecipients,
- uint256[] memory customRoyaltyAmounts
- ) = _setupRoyaltyEngine();
+ (MockRoyaltyEngineV1 royaltyEngine, , ) = _setupRoyaltyEngine();
// Add RoyaltyEngine to marketplace
vm.prank(marketplaceDeployer);
@@ -361,8 +353,6 @@ contract MarketplaceOffersTest is BaseTest {
IOffers.Offer memory offer = OffersLogic(marketplace).getOffer(offerId);
- uint256 totalPrice = offer.totalPrice;
-
// Approve Marketplace to transfer token.
vm.prank(seller);
IERC721(offer.assetContract).setApprovalForAll(marketplace, true);
diff --git a/src/test/mocks/MockRoyaltyEngineV1.sol b/src/test/mocks/MockRoyaltyEngineV1.sol
index 07f0cc9e5..9328ce0c6 100644
--- a/src/test/mocks/MockRoyaltyEngineV1.sol
+++ b/src/test/mocks/MockRoyaltyEngineV1.sol
@@ -22,7 +22,7 @@ contract MockRoyaltyEngineV1 is ERC165, IRoyaltyEngineV1 {
address tokenAddress,
uint256 tokenId,
uint256 value
- ) public override returns (address payable[] memory recipients, uint256[] memory amounts) {
+ ) public view override returns (address payable[] memory recipients, uint256[] memory amounts) {
try IERC2981(tokenAddress).royaltyInfo(tokenId, value) returns (address recipient, uint256 amount) {
// Supports EIP2981. Return amounts
recipients = new address payable[](1);
diff --git a/src/test/pack/PackVRFDirect.t.sol b/src/test/pack/PackVRFDirect.t.sol
index 5a248f0ab..bdc0f7bb8 100644
--- a/src/test/pack/PackVRFDirect.t.sol
+++ b/src/test/pack/PackVRFDirect.t.sol
@@ -534,7 +534,7 @@ contract PackVRFDirectTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
uint256 requestId = pack.openPackAndClaimRewards(packId, packsToOpen, 2_500_000);
@@ -564,7 +564,7 @@ contract PackVRFDirectTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
uint256 requestId = pack.openPackAndClaimRewards(packId, packsToOpen, 2);
@@ -596,7 +596,7 @@ contract PackVRFDirectTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
uint256 requestId = pack.openPackAndClaimRewards(packId, packsToOpen, 2_500_000);
@@ -797,7 +797,7 @@ contract PackVRFDirectTest is BaseTest {
address recipient = address(1);
vm.prank(address(tokenOwner));
- (, uint256 totalSupply) = pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
+ pack.createPack(packContents, numOfRewardUnits, packUri, 0, 2, recipient);
vm.prank(recipient, recipient);
uint256 requestId = pack.openPack(packId, packsToOpen);
diff --git a/src/test/sdk/extension/StakingExtension.t.sol b/src/test/sdk/extension/StakingExtension.t.sol
index 54494ae49..5267d87d5 100644
--- a/src/test/sdk/extension/StakingExtension.t.sol
+++ b/src/test/sdk/extension/StakingExtension.t.sol
@@ -198,7 +198,7 @@ contract StakingExtensionTest is DSTest, Test {
_tokenIds[0] = 6;
vm.prank(stakerOne);
- vm.expectRevert("Not owned or approved");
+ vm.expectRevert("ERC721: transfer from incorrect owner");
ext.stake(_tokenIds);
}
diff --git a/src/test/smart-wallet/Account.t.sol b/src/test/smart-wallet/Account.t.sol
index 12611493f..1d61a3f57 100644
--- a/src/test/smart-wallet/Account.t.sol
+++ b/src/test/smart-wallet/Account.t.sol
@@ -474,7 +474,10 @@ contract SimpleAccountTest is BaseTest {
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: 1000 }("");
+ (bool success, bytes memory data) = payable(account).call{ value: 1000 }("");
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
assertEq(address(account).balance, 1000);
}
@@ -488,9 +491,12 @@ contract SimpleAccountTest is BaseTest {
address account = accountFactory.getAddress(accountAdmin, bytes(""));
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: value }("");
+ (bool success, bytes memory data) = payable(account).call{ value: value }("");
assertEq(address(account).balance, value);
+ // Silence warning: Return value of low-level calls not used.
+ (success, data) = (success, data);
+
address recipient = address(0x3456);
UserOperation[] memory userOp = _setupUserOpExecute(accountAdminPKey, bytes(""), recipient, value, bytes(""));
diff --git a/src/test/smart-wallet/DynamicAccount.t.sol b/src/test/smart-wallet/DynamicAccount.t.sol
index 39b618ce1..c25832638 100644
--- a/src/test/smart-wallet/DynamicAccount.t.sol
+++ b/src/test/smart-wallet/DynamicAccount.t.sol
@@ -528,7 +528,10 @@ contract DynamicAccountTest is BaseTest {
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: 1000 }("");
+ (bool success, bytes memory ret) = payable(account).call{ value: 1000 }("");
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, ret) = (success, ret);
assertEq(address(account).balance, 1000);
}
@@ -542,9 +545,12 @@ contract DynamicAccountTest is BaseTest {
address account = accountFactory.getAddress(accountAdmin, bytes(""));
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: value }("");
+ (bool success, bytes memory ret) = payable(account).call{ value: value }("");
assertEq(address(account).balance, value);
+ // Silence warning: Return value of low-level calls not used.
+ (success, ret) = (success, ret);
+
address recipient = address(0x3456);
UserOperation[] memory userOp = _setupUserOpExecute(accountAdminPKey, bytes(""), recipient, value, bytes(""));
diff --git a/src/test/smart-wallet/ManagedAccount.t.sol b/src/test/smart-wallet/ManagedAccount.t.sol
index 45960cd70..7747b673a 100644
--- a/src/test/smart-wallet/ManagedAccount.t.sol
+++ b/src/test/smart-wallet/ManagedAccount.t.sol
@@ -531,9 +531,12 @@ contract ManagedAccountTest is BaseTest {
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: 1000 }("");
+ (bool success, bytes memory ret) = payable(account).call{ value: 1000 }("");
assertEq(address(account).balance, 1000);
+
+ // Silence warning: Return value of low-level calls not used.
+ (success, ret) = (success, ret);
}
/// @dev Transfer native tokens out of an account.
@@ -545,9 +548,12 @@ contract ManagedAccountTest is BaseTest {
address account = accountFactory.getAddress(accountAdmin, bytes(""));
vm.prank(accountAdmin);
// solhint-disable-next-line avoid-low-level-calls
- payable(account).call{ value: value }("");
+ (bool success, bytes memory ret) = payable(account).call{ value: value }("");
assertEq(address(account).balance, value);
+ // Silence warning: Return value of low-level calls not used.
+ (success, ret) = (success, ret);
+
address recipient = address(0x3456);
UserOperation[] memory userOp = _setupUserOpExecute(accountAdminPKey, bytes(""), recipient, value, bytes(""));
diff --git a/src/test/staking/EditionStake.t.sol b/src/test/staking/EditionStake.t.sol
index 34b9f921a..0db955698 100644
--- a/src/test/staking/EditionStake.t.sol
+++ b/src/test/staking/EditionStake.t.sol
@@ -138,7 +138,7 @@ contract EditionStakeTest is BaseTest {
function test_revert_stake_notBalanceOrApproved() public {
// stake unowned tokens
vm.prank(stakerOne);
- vm.expectRevert("Not balance or approved");
+ vm.expectRevert("ERC1155: insufficient balance for transfer");
stakeContract.stake(2, 10);
}
@@ -595,7 +595,7 @@ contract EditionStakeTest is BaseTest {
function test_state_setTimeUnit_token0() public {
// set value and check
- uint256 timeUnit = 100;
+ uint80 timeUnit = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(0, timeUnit);
assertEq(timeUnit, stakeContract.getTimeUnit(0));
@@ -679,7 +679,7 @@ contract EditionStakeTest is BaseTest {
function test_state_setTimeUnit_bothTokens() public {
// set value and check
- uint256 timeUnit = 100;
+ uint80 timeUnit = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(0, timeUnit);
assertEq(timeUnit, stakeContract.getTimeUnit(0));
@@ -1018,7 +1018,7 @@ contract EditionStakeTest is BaseTest {
stakeContract.stake(0, 50);
// set default timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setDefaultTimeUnit(newTimeUnit);
@@ -1058,7 +1058,7 @@ contract Macro_EditionStakeTest is BaseTest {
uint256 internal defaultTimeUnit;
uint256 internal defaultRewardsPerUnitTime;
- uint256 internal tokenAmount = 100;
+ uint64 internal tokenAmount = 100;
address internal stakerOne = address(0x345);
address internal stakerTwo = address(0x567);
@@ -1096,7 +1096,7 @@ contract Macro_EditionStakeTest is BaseTest {
stakeContract.stake(2, tokenAmount);
// set timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setDefaultTimeUnit(newTimeUnit);
diff --git a/src/test/staking/EditionStake_EthReward.t.sol b/src/test/staking/EditionStake_EthReward.t.sol
index 02538fa84..455754605 100644
--- a/src/test/staking/EditionStake_EthReward.t.sol
+++ b/src/test/staking/EditionStake_EthReward.t.sol
@@ -147,7 +147,7 @@ contract EditionStakeEthRewardTest is BaseTest {
function test_revert_stake_notBalanceOrApproved() public {
// stake unowned tokens
vm.prank(stakerOne);
- vm.expectRevert("Not balance or approved");
+ vm.expectRevert("ERC1155: insufficient balance for transfer");
stakeContract.stake(2, 10);
}
@@ -604,7 +604,7 @@ contract EditionStakeEthRewardTest is BaseTest {
function test_state_setTimeUnit_token0() public {
// set value and check
- uint256 timeUnit = 100;
+ uint80 timeUnit = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(0, timeUnit);
assertEq(timeUnit, stakeContract.getTimeUnit(0));
@@ -688,7 +688,7 @@ contract EditionStakeEthRewardTest is BaseTest {
function test_state_setTimeUnit_bothTokens() public {
// set value and check
- uint256 timeUnit = 100;
+ uint80 timeUnit = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(0, timeUnit);
assertEq(timeUnit, stakeContract.getTimeUnit(0));
@@ -1027,7 +1027,7 @@ contract EditionStakeEthRewardTest is BaseTest {
stakeContract.stake(0, 50);
// set default timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setDefaultTimeUnit(newTimeUnit);
diff --git a/src/test/staking/NFTStake.t.sol b/src/test/staking/NFTStake.t.sol
index 861cabdc2..bd049f608 100644
--- a/src/test/staking/NFTStake.t.sol
+++ b/src/test/staking/NFTStake.t.sol
@@ -151,7 +151,7 @@ contract NFTStakeTest is BaseTest {
_tokenIds[0] = 6;
vm.prank(stakerOne);
- vm.expectRevert("Not owned or approved");
+ vm.expectRevert("ERC721: transfer from incorrect owner");
stakeContract.stake(_tokenIds);
}
diff --git a/src/test/staking/NFTStake_EthReward.t.sol b/src/test/staking/NFTStake_EthReward.t.sol
index f3bc0a04f..ba9c7da4b 100644
--- a/src/test/staking/NFTStake_EthReward.t.sol
+++ b/src/test/staking/NFTStake_EthReward.t.sol
@@ -160,7 +160,7 @@ contract NFTStakeEthRewardTest is BaseTest {
_tokenIds[0] = 6;
vm.prank(stakerOne);
- vm.expectRevert("Not owned or approved");
+ vm.expectRevert("ERC721: transfer from incorrect owner");
stakeContract.stake(_tokenIds);
}
diff --git a/src/test/staking/TokenStake.t.sol b/src/test/staking/TokenStake.t.sol
index 1443cd11d..a2d4055f9 100644
--- a/src/test/staking/TokenStake.t.sol
+++ b/src/test/staking/TokenStake.t.sol
@@ -13,7 +13,7 @@ contract TokenStakeTest is BaseTest {
address internal stakerOne;
address internal stakerTwo;
- uint256 internal timeUnit;
+ uint80 internal timeUnit;
uint256 internal rewardRatioNumerator;
uint256 internal rewardRatioDenominator;
@@ -298,7 +298,7 @@ contract TokenStakeTest is BaseTest {
function test_state_setTimeUnit() public {
// set value and check
- uint256 timeUnitToSet = 100;
+ uint80 timeUnitToSet = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(timeUnitToSet);
assertEq(timeUnitToSet, stakeContract.getTimeUnit());
@@ -504,7 +504,7 @@ contract TokenStakeTest is BaseTest {
stakeContract.stake(400);
// set timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setTimeUnit(newTimeUnit);
@@ -537,7 +537,7 @@ contract Macro_TokenStake_Rewards6_Staking18_Test is BaseTest {
address internal stakerOne;
- uint256 internal timeUnit;
+ uint80 internal timeUnit;
uint256 internal rewardRatioNumerator;
uint256 internal rewardRatioDenominator;
@@ -631,7 +631,7 @@ contract Macro_TokenStake_Rewards18_Staking6_Test is BaseTest {
address internal stakerOne;
- uint256 internal timeUnit;
+ uint80 internal timeUnit;
uint256 internal rewardRatioNumerator;
uint256 internal rewardRatioDenominator;
@@ -719,7 +719,7 @@ contract Macro_TokenStake_Rewards18_Staking6_Test is BaseTest {
contract Macro_TokenStakeTest is BaseTest {
TokenStake internal stakeContract;
- uint256 internal timeUnit;
+ uint80 internal timeUnit;
uint256 internal rewardsPerUnitTime;
uint256 internal rewardRatioNumerator;
uint256 internal rewardRatioDenominator;
@@ -767,7 +767,7 @@ contract Macro_TokenStakeTest is BaseTest {
stakeContract.stake(tokenAmount);
// set timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setTimeUnit(newTimeUnit);
diff --git a/src/test/staking/TokenStake_EthReward.t.sol b/src/test/staking/TokenStake_EthReward.t.sol
index e5de73992..f8e20354c 100644
--- a/src/test/staking/TokenStake_EthReward.t.sol
+++ b/src/test/staking/TokenStake_EthReward.t.sol
@@ -307,7 +307,7 @@ contract TokenStakeEthRewardTest is BaseTest {
function test_state_setTimeUnit() public {
// set value and check
- uint256 timeUnitToSet = 100;
+ uint80 timeUnitToSet = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(timeUnitToSet);
assertEq(timeUnitToSet, stakeContract.getTimeUnit());
@@ -513,7 +513,7 @@ contract TokenStakeEthRewardTest is BaseTest {
stakeContract.stake(400);
// set timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setTimeUnit(newTimeUnit);
diff --git a/src/test/staking/TokenStake_EthStake.t.sol b/src/test/staking/TokenStake_EthStake.t.sol
index 435856c55..fa5616568 100644
--- a/src/test/staking/TokenStake_EthStake.t.sol
+++ b/src/test/staking/TokenStake_EthStake.t.sol
@@ -301,7 +301,7 @@ contract TokenStakeEthStakeTest is BaseTest {
function test_state_setTimeUnit() public {
// set value and check
- uint256 timeUnitToSet = 100;
+ uint80 timeUnitToSet = 100;
vm.prank(deployer);
stakeContract.setTimeUnit(timeUnitToSet);
assertEq(timeUnitToSet, stakeContract.getTimeUnit());
@@ -507,7 +507,7 @@ contract TokenStakeEthStakeTest is BaseTest {
stakeContract.stake{ value: 400 }(400);
// set timeUnit to zero
- uint256 newTimeUnit = 0;
+ uint80 newTimeUnit = 0;
vm.prank(deployer);
vm.expectRevert("time-unit can't be 0");
stakeContract.setTimeUnit(newTimeUnit);
diff --git a/yarn.lock b/yarn.lock
index be190795c..92457b423 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -82,9 +82,9 @@
strip-json-comments "^3.1.1"
"@eth-optimism/contracts@^0.5.21":
- version "0.5.39"
- resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.39.tgz#a312a0a0b2d5853cd417c5e8969e87288e166fcb"
- integrity sha512-u3UufuZFzgidRN2/cC3mhRxX+M6VsMV9tauIKu8D5pym5/UO4pZr85WP3KxHFfLh1i8zmkdj+pN/GRQsNYCqMg==
+ version "0.5.40"
+ resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.5.40.tgz#d13a04a15ea947a69055e6fc74d87e215d4c936a"
+ integrity sha512-MrzV0nvsymfO/fursTB7m/KunkPsCndltVgfdHaT1Aj5Vi6R/doKIGGkOofHX+8B6VMZpuZosKCMQ5lQuqjt8w==
dependencies:
"@eth-optimism/core-utils" "0.12.0"
"@ethersproject/abstract-provider" "^5.7.0"
@@ -931,9 +931,9 @@
integrity sha512-5OnVuO4HlkjSCJO165a4i2Pu1zQGzMs//o54LPrwUgxvEO2P3ax1QuaSI0cEHHTveA77guS0PnNugpR2JMsPfA==
"@openzeppelin/contracts-upgradeable@^4.7.3":
- version "4.8.3"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.3.tgz#6b076a7b751811b90fe3a172a7faeaa603e13a3f"
- integrity sha512-SXDRl7HKpl2WDoJpn7CK/M9U4Z8gNXDHHChAKh0Iz+Wew3wu6CmFYBeie3je8V0GSXZAIYYwUktSrnW/kwVPtg==
+ version "4.9.3"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811"
+ integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==
"@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2":
version "3.4.2"
@@ -2495,7 +2495,7 @@ bcrypt-pbkdf@^1.0.0:
bech32@1.1.4:
version "1.1.4"
- resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz"
+ resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
bignumber.js@^9.0.0, bignumber.js@^9.0.1:
@@ -2545,7 +2545,7 @@ bn.js@4.11.6:
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.10.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9, bn.js@^4.8.0:
version "4.12.0"
- resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2:
@@ -2555,7 +2555,7 @@ bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2:
bn.js@^5.2.0, bn.js@^5.2.1:
version "5.2.1"
- resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz"
+ resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
body-parser@1.19.2:
@@ -2625,8 +2625,8 @@ braces@^3.0.2, braces@~3.0.2:
brorand@^1.0.1, brorand@^1.1.0:
version "1.1.0"
- resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
- integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
+ resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
+ integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
browser-stdout@1.3.1:
version "1.3.1"
@@ -2769,9 +2769,9 @@ bufferutil@^4.0.1:
node-gyp-build "^4.3.0"
bufio@^1.0.7:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.1.3.tgz#7f8e524fd719ced2caa563a09d50550f283f745f"
- integrity sha512-W0ydG8t+ST+drUpEwl1N+dU9Ije06g8+43CLtvEIzfKo9nPFLXbKqDYE2XSg4w6RugsBcCj7pEU7jOpBC6BqrA==
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.0.tgz#b9ad1c06b0d9010363c387c39d2810a7086d143f"
+ integrity sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA==
bundle-require@^3.0.2:
version "3.0.4"
@@ -3749,7 +3749,7 @@ electron-to-chromium@^1.3.47:
elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4:
version "6.5.4"
- resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz"
+ resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
dependencies:
bn.js "^4.11.9"
@@ -5743,7 +5743,7 @@ hash.js@1.1.3:
hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7:
version "1.1.7"
- resolved "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz"
+ resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
dependencies:
inherits "^2.0.3"
@@ -5761,8 +5761,8 @@ heap@0.2.6:
hmac-drbg@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz"
- integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
+ resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
+ integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
dependencies:
hash.js "^1.0.3"
minimalistic-assert "^1.0.0"
@@ -5939,7 +5939,7 @@ inflight@^1.0.4:
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
version "2.0.4"
- resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
inquirer@^6.2.2:
@@ -6435,7 +6435,7 @@ js-sha3@0.5.7, js-sha3@^0.5.7:
js-sha3@0.8.0, js-sha3@^0.8.0:
version "0.8.0"
- resolved "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz"
+ resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
@@ -7291,13 +7291,13 @@ min-document@^2.19.0:
minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz"
+ resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
- resolved "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
- integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
+ resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
+ integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
minimatch@3.0.4:
version "3.0.4"
@@ -10775,7 +10775,7 @@ write@1.0.3:
ws@7.4.6:
version "7.4.6"
- resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
ws@^3.0.0: