diff --git a/.env.example b/.env.example index 1eafe87..a0cf48b 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ CHAIN_TO_FORK=sepolia -COLLECTION=DO +# do | dn - Digital(Original | Native) +COLLECTION=do FORKED_CHAIN=sepolia FORKED_CHAIN_URL=http://localhost:8545/ diff --git a/.husky/pre-commit b/.husky/pre-commit index d24fdfc..2312dc5 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1 @@ -#!/usr/bin/env sh -. "$(dirname -- "$0")/_/husky.sh" - npx lint-staged diff --git a/.prettierignore b/.prettierignore index 60d4e98..1dcf57c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,7 +3,6 @@ artifacts cache coverage* gasReporterOutput.json -package.json img .env .* diff --git a/.prettierrc b/.prettierrc index e035d99..07e2430 100644 --- a/.prettierrc +++ b/.prettierrc @@ -15,6 +15,12 @@ "singleQuote": false, "bracketSpacing": false } + }, + { + "files": "*.json", + "options": { + "printWidth": 60 + } } ] } diff --git a/README.md b/README.md index cb02c23..2c65cbd 100644 --- a/README.md +++ b/README.md @@ -1,62 +1,79 @@ +![license](https://img.shields.io/badge/license-GPLv3-blue) +![hardhat](https://img.shields.io/badge/built%20with-Hardhat-blueviolet) +![solidity](https://img.shields.io/badge/solidity-0.8.20-363636) + # Digital Original Smart Contracts + The repository contains two core smart contracts: [`ArtToken`](https://github.com/digital-original/contracts/blob/master/contracts/art-token/ArtToken.sol) and [`AuctionHouse`](https://github.com/digital-original/contracts/blob/master/contracts/auction-house/AuctionHouse.sol). Development takes place in the [Hardhat](https://hardhat.org/) environment, utilizing [OpenZeppelin](https://www.openzeppelin.com/) as the main smart contract library. +## Project Description + ### ArtToken -Upgradable contract. The contract provides functionality to track, transfer and sell Digital Original NFTs. +The `ArtToken` is an upgradable contract that provides functionality to track, transfer, and sell Digital Original NFTs. It ensures secure and efficient management of digital assets. ### AuctionHouse -Upgradable contract. The contract provides functionality to sell Digital Original NFTs according to auction rules. +The `AuctionHouse` is an upgradable contract that facilitates the sale of Digital Original NFTs according to auction rules. -## Get Started -1. Install dependencies -``` -$ npm install -``` -2. Fill out `config.env.yaml` -3. Compile contracts -``` -$ npm run compile -``` +## Setup Instructions -## Run test -``` -$ npm run test -``` +1. **Install Dependencies** + ```bash + npm install + ``` -## Run local fork -``` -$ npm run fork -``` +2. **Configure Environment** + Fill out the `config.env.yaml` file with the necessary configuration details. -## Run scripts -``` -$ npx hardhat run --network fork -``` +3. **Compile Contracts** + ```bash + npm run compile + ``` -## Deploy protocol -``` -$ npx hardhat deploy-protocol --network fork -``` +## Usage -## Run slither -1. Create Python virtual environment -``` -$ python3 -m venv venv -``` -2. Run Python virtual environment -``` -$ source ./venv/bin/activate -``` -3. Instal Python packages -``` -$ pip install -r requirements.txt +### Run Tests +Execute the test suite to ensure all contracts function as expected. +```bash +npm run test ``` -4. Run Slither -``` -$ npm run slither + +### Run Local Fork +Set up a local fork of the blockchain for testing and development. +```bash +npm run fork ``` -## Generate Documentation +### Run Scripts +Execute scripts using Hardhat. +```bash +npx hardhat run --network fork ``` -$ forge doc -b + +### Deploy Protocol +Deploy the smart contracts to the specified network. +```bash +npx hardhat deploy-protocol --network fork ``` + +### Run Slither +Perform static analysis using Slither. +1. Create a Python virtual environment: + ```bash + python3 -m venv venv + ``` +2. Activate the virtual environment: + ```bash + source ./venv/bin/activate + ``` +3. Install Python packages: + ```bash + pip install -r requirements.txt + ``` +4. Run Slither: + ```bash + npm run slither + ``` + +## License + +This project is licensed under the GNU General Public License v3.0. See the [LICENSE](./LICENSE) file for details. diff --git a/abis/ArtToken.json b/abis/ArtToken.json index 22dac10..4ae3004 100644 --- a/abis/ArtToken.json +++ b/abis/ArtToken.json @@ -1,6 +1,11 @@ [ { "inputs": [ + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, { "internalType": "address", "name": "main", @@ -64,88 +69,86 @@ }, { "inputs": [], - "name": "ArtTokenForbiddenAction", + "name": "ArtTokenInvalidFee", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], - "name": "ArtTokenInvalidFee", + "inputs": [], + "name": "ArtTokenInvalidPrice", "type": "error" }, { "inputs": [ { "internalType": "uint256", - "name": "value", + "name": "argIndex", "type": "uint256" } ], - "name": "ArtTokenInvalidPrice", + "name": "ArtTokenMisconfiguration", + "type": "error" + }, + { + "inputs": [], + "name": "ArtTokenTokenReserved", "type": "error" }, { "inputs": [ { "internalType": "address", - "name": "receiver", + "name": "account", "type": "address" } ], - "name": "ArtTokenInvalidReceiver", + "name": "ArtTokenUnauthorizedAccount", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "argIndex", - "type": "uint256" - } - ], - "name": "ArtTokenMisconfiguration", + "inputs": [], + "name": "AuthorizationDeadlineExpired", + "type": "error" + }, + { + "inputs": [], + "name": "AuthorizationUnauthorizedAction", + "type": "error" + }, + { + "inputs": [], + "name": "DistributionParticipantsSharesMismatch", "type": "error" }, { "inputs": [ { "internalType": "uint256", - "name": "tokenId", + "name": "shareSum", "type": "uint256" } ], - "name": "ArtTokenReserved", + "name": "DistributionSharesSumTooBig", "type": "error" }, { "inputs": [ { - "internalType": "address", - "name": "account", - "type": "address" + "internalType": "uint256", + "name": "shareSum", + "type": "uint256" } ], - "name": "ArtTokenUnauthorizedAccount", + "name": "DistributionSharesSumTooLow", "type": "error" }, { "inputs": [], - "name": "DistributionInvalidSharesCount", - "type": "error" - }, - { - "inputs": [], - "name": "DistributionInvalidSharesSum", + "name": "DistributionZeroAddress", "type": "error" }, { "inputs": [], - "name": "DistributionZeroAddress", + "name": "DistributionZeroShare", "type": "error" }, { @@ -176,18 +179,19 @@ "type": "error" }, { - "inputs": [], - "name": "EIP712ExpiredSignature", - "type": "error" - }, - { - "inputs": [], - "name": "EIP712InvalidSignature", + "inputs": [ + { + "internalType": "uint256", + "name": "argIndex", + "type": "uint256" + } + ], + "name": "EIP712DomainMisconfiguration", "type": "error" }, { "inputs": [], - "name": "EIP712SignerZeroAddress", + "name": "EIP712SignatureZeroAddress", "type": "error" }, { @@ -324,6 +328,11 @@ "name": "InvalidInitialization", "type": "error" }, + { + "inputs": [], + "name": "MathOverflowedMulDiv", + "type": "error" + }, { "inputs": [], "name": "NotInitializing", @@ -345,22 +354,6 @@ "name": "RoleSystemNotMain", "type": "error" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "neededRole", - "type": "bytes32" - } - ], - "name": "RoleSystemUnauthorizedAccount", - "type": "error" - }, { "inputs": [], "name": "RoleSystemZeroAddress", @@ -540,21 +533,15 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" + "internalType": "bytes32", + "name": "role", + "type": "bytes32" }, { "indexed": true, "internalType": "address", - "name": "to", + "name": "newOwner", "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" } ], "name": "UniqueRoleTransferred", @@ -562,12 +549,12 @@ }, { "inputs": [], - "name": "ADMIN_ROLE", + "name": "AUCTION_HOUSE", "outputs": [ { - "internalType": "bytes32", + "internalType": "contract IAuctionHouse", "name": "", - "type": "bytes32" + "type": "address" } ], "stateMutability": "view", @@ -575,12 +562,12 @@ }, { "inputs": [], - "name": "AUCTION_HOUSE", + "name": "BUY_PERMIT_TYPE_HASH", "outputs": [ { - "internalType": "contract IAuctionHouse", + "internalType": "bytes32", "name": "", - "type": "address" + "type": "bytes32" } ], "stateMutability": "view", @@ -588,7 +575,7 @@ }, { "inputs": [], - "name": "BUY_PERMIT_TYPE_HASH", + "name": "DOMAIN_SEPARATOR", "outputs": [ { "internalType": "bytes32", @@ -601,7 +588,7 @@ }, { "inputs": [], - "name": "FINANCIAL_ROLE", + "name": "DOMAIN_TYPE_HASH", "outputs": [ { "internalType": "bytes32", @@ -651,19 +638,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [], - "name": "PARTNER_ROLE", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "REGULATED", @@ -814,7 +788,7 @@ "type": "address" } ], - "name": "grandRole", + "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -952,7 +926,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "authorized", "type": "bool" } ], @@ -1133,7 +1107,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "reserved", "type": "bool" } ], @@ -1204,7 +1178,7 @@ }, { "internalType": "address", - "name": "to", + "name": "newOwner", "type": "address" } ], @@ -1221,11 +1195,11 @@ "type": "bytes32" } ], - "name": "uniqueRoleAccount", + "name": "uniqueRoleOwner", "outputs": [ { "internalType": "address", - "name": "account", + "name": "owner", "type": "address" } ], diff --git a/abis/AuctionHouse.json b/abis/AuctionHouse.json index 64c9ee4..2e3245f 100644 --- a/abis/AuctionHouse.json +++ b/abis/AuctionHouse.json @@ -1,6 +1,11 @@ [ { "inputs": [ + { + "internalType": "address", + "name": "proxy", + "type": "address" + }, { "internalType": "address", "name": "main", @@ -58,93 +63,32 @@ "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blockTime", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseAuctionEnded", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseAuctionExists", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blockTime", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseAuctionNotEnded", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - } - ], - "name": "AuctionHouseAuctionNotExist", + "inputs": [], + "name": "AuctionHouseAuctionNotExists", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - }, - { - "internalType": "address", - "name": "buyer", - "type": "address" - } - ], + "inputs": [], "name": "AuctionHouseBuyerExists", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseBuyerNotExists", "type": "error" }, @@ -154,51 +98,17 @@ "type": "error" }, { - "inputs": [ - { - "internalType": "address", - "name": "buyer", - "type": "address" - } - ], - "name": "AuctionHouseInvalidBuyer", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "endTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "blockTime", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseInvalidEndTime", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseInvalidFee", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "value", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseInvalidPrice", "type": "error" }, @@ -220,55 +130,71 @@ }, { "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, { "internalType": "uint256", "name": "minAmount", "type": "uint256" } ], - "name": "AuctionHouseRaiseTooSmall", + "name": "AuctionHouseRaiseTooLow", "type": "error" }, { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], + "inputs": [], "name": "AuctionHouseTokenReserved", "type": "error" }, + { + "inputs": [], + "name": "AuctionHouseTokenSold", + "type": "error" + }, { "inputs": [ { - "internalType": "uint256", - "name": "auctionId", - "type": "uint256" + "internalType": "address", + "name": "account", + "type": "address" } ], - "name": "AuctionHouseTokenSold", + "name": "AuctionHouseUnauthorizedAccount", "type": "error" }, { "inputs": [], - "name": "AuctionHouseZeroId", + "name": "AuthorizationDeadlineExpired", "type": "error" }, { "inputs": [], - "name": "DistributionInvalidSharesCount", + "name": "AuthorizationUnauthorizedAction", "type": "error" }, { "inputs": [], - "name": "DistributionInvalidSharesSum", + "name": "DistributionParticipantsSharesMismatch", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shareSum", + "type": "uint256" + } + ], + "name": "DistributionSharesSumTooBig", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "shareSum", + "type": "uint256" + } + ], + "name": "DistributionSharesSumTooLow", "type": "error" }, { @@ -276,6 +202,11 @@ "name": "DistributionZeroAddress", "type": "error" }, + { + "inputs": [], + "name": "DistributionZeroShare", + "type": "error" + }, { "inputs": [], "name": "ECDSAInvalidSignature", @@ -304,23 +235,29 @@ "type": "error" }, { - "inputs": [], - "name": "EIP712ExpiredSignature", + "inputs": [ + { + "internalType": "uint256", + "name": "argIndex", + "type": "uint256" + } + ], + "name": "EIP712DomainMisconfiguration", "type": "error" }, { "inputs": [], - "name": "EIP712InvalidSignature", + "name": "EIP712SignatureZeroAddress", "type": "error" }, { "inputs": [], - "name": "EIP712SignerZeroAddress", + "name": "FailedInnerCall", "type": "error" }, { "inputs": [], - "name": "FailedInnerCall", + "name": "MathOverflowedMulDiv", "type": "error" }, { @@ -339,22 +276,6 @@ "name": "RoleSystemNotMain", "type": "error" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "bytes32", - "name": "neededRole", - "type": "bytes32" - } - ], - "name": "RoleSystemUnauthorizedAccount", - "type": "error" - }, { "inputs": [], "name": "RoleSystemZeroAddress", @@ -483,21 +404,15 @@ "inputs": [ { "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" + "internalType": "bytes32", + "name": "role", + "type": "bytes32" }, { "indexed": true, "internalType": "address", - "name": "to", + "name": "newOwner", "type": "address" - }, - { - "indexed": true, - "internalType": "bytes32", - "name": "role", - "type": "bytes32" } ], "name": "UniqueRoleTransferred", @@ -505,12 +420,12 @@ }, { "inputs": [], - "name": "ADMIN_ROLE", + "name": "ART_TOKEN", "outputs": [ { - "internalType": "bytes32", + "internalType": "contract IArtToken", "name": "", - "type": "bytes32" + "type": "address" } ], "stateMutability": "view", @@ -518,12 +433,12 @@ }, { "inputs": [], - "name": "ART_TOKEN", + "name": "CREATE_PERMIT_TYPE_HASH", "outputs": [ { - "internalType": "contract IArtToken", + "internalType": "bytes32", "name": "", - "type": "address" + "type": "bytes32" } ], "stateMutability": "view", @@ -531,7 +446,7 @@ }, { "inputs": [], - "name": "CREATE_PERMIT_TYPE_HASH", + "name": "DOMAIN_SEPARATOR", "outputs": [ { "internalType": "bytes32", @@ -544,7 +459,7 @@ }, { "inputs": [], - "name": "FINANCIAL_ROLE", + "name": "DOMAIN_TYPE_HASH", "outputs": [ { "internalType": "bytes32", @@ -800,7 +715,7 @@ "type": "address" } ], - "name": "grandRole", + "name": "grantRole", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -838,7 +753,7 @@ }, { "internalType": "uint256", - "name": "price", + "name": "newPrice", "type": "uint256" } ], @@ -856,7 +771,7 @@ }, { "internalType": "uint256", - "name": "price", + "name": "newPrice", "type": "uint256" } ], @@ -895,7 +810,7 @@ "outputs": [ { "internalType": "bool", - "name": "", + "name": "reserved", "type": "bool" } ], @@ -911,7 +826,7 @@ }, { "internalType": "address", - "name": "to", + "name": "newOwner", "type": "address" } ], @@ -928,11 +843,11 @@ "type": "bytes32" } ], - "name": "uniqueRoleAccount", + "name": "uniqueRoleOwner", "outputs": [ { "internalType": "address", - "name": "account", + "name": "owner", "type": "address" } ], diff --git a/config.dc.yaml b/config.dn.yaml similarity index 97% rename from config.dc.yaml rename to config.dn.yaml index bc9ef96..92f22ae 100644 --- a/config.dc.yaml +++ b/config.dn.yaml @@ -1,5 +1,5 @@ -name: 'DigitalCommon' -symbol: 'DC' +name: 'DigitalNative' +symbol: 'DN' sepolia: minPriceUsd: 50 diff --git a/constants/usdc.ts b/constants/usdc.ts deleted file mode 100644 index 6b3bbcf..0000000 --- a/constants/usdc.ts +++ /dev/null @@ -1 +0,0 @@ -export const USDC_DECIMALS = 6; diff --git a/contracts/art-token/ArtToken.sol b/contracts/art-token/ArtToken.sol index 9c9c0df..68bbb4e 100644 --- a/contracts/art-token/ArtToken.sol +++ b/contracts/art-token/ArtToken.sol @@ -3,9 +3,11 @@ pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {EIP712Domain} from "../utils/EIP712Domain.sol"; import {RoleSystem} from "../utils/role-system/RoleSystem.sol"; -import {EIP712} from "../utils/EIP712.sol"; +import {Authorization} from "../utils/Authorization.sol"; import {Distribution} from "../utils/Distribution.sol"; +import {Roles} from "../utils/Roles.sol"; import {IAuctionHouse} from "../auction-house/IAuctionHouse.sol"; import {ArtTokenBase} from "./ArtTokenBase.sol"; import {IArtToken} from "./IArtToken.sol"; @@ -13,14 +15,23 @@ import {IArtToken} from "./IArtToken.sol"; /** * @title ArtToken * - * @notice ArtToken contract extends ERC721 standard. - * The contract provides functionality to track, transfer and sell Digital Original NFTs. + * @notice Upgradeable ERC-721 token used by DigitalOriginal + * protocols. Adds primary-sale logic via `buy`, integrates EIP-712 + * permits and enforces optional transfer restrictions for regulated + * collections. + * + * @dev Implements {IArtToken}. Uses mix-ins for EIP-712 domain + * separation, role management and signature authorization. */ -contract ArtToken is IArtToken, ArtTokenBase, RoleSystem, EIP712("ArtToken", "1") { +contract ArtToken is IArtToken, ArtTokenBase, EIP712Domain, RoleSystem, Authorization { using SafeERC20 for IERC20; + /** + * @notice EIP-712 struct type-hash used to validate `BuyPermit` signatures + * supplied to {buy}. + */ + // prettier-ignore bytes32 public constant BUY_PERMIT_TYPE_HASH = - // prettier-ignore keccak256( "BuyPermit(" "uint256 tokenId," @@ -34,22 +45,23 @@ contract ArtToken is IArtToken, ArtTokenBase, RoleSystem, EIP712("ArtToken", "1" ")" ); - IAuctionHouse public immutable AUCTION_HOUSE; // AuctionHouse contract address - IERC20 public immutable USDC; // USDC asset contract address + /// @notice Address of the accompanying AuctionHouse contract. + IAuctionHouse public immutable AUCTION_HOUSE; - uint256 public immutable MIN_PRICE; // Minimum price value - uint256 public immutable MIN_FEE; // Minimum fee value + /// @notice Settlement token (USDC) accepted by `buy`. + IERC20 public immutable USDC; - bool public immutable REGULATED; + /// @notice Minimum allowed primary-sale price (protocol-level constant). + uint256 public immutable MIN_PRICE; - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); - bytes32 public constant FINANCIAL_ROLE = keccak256("FINANCIAL_ROLE"); - bytes32 public constant PARTNER_ROLE = keccak256("PARTNER_ROLE"); + /// @notice Minimum allowed platform fee (protocol-level constant). + uint256 public immutable MIN_FEE; - /** - * @dev Throws if called by any account without a minting permission. - */ - modifier canMint() { + /// @notice If true, transfers are limited to EOAs and partners only. + bool public immutable REGULATED; + + /// @notice Restricts a function so it can only be called by {AUCTION_HOUSE}. + modifier onlyAuctionHouse() { if (msg.sender != address(AUCTION_HOUSE)) { revert ArtTokenUnauthorizedAccount(msg.sender); } @@ -58,22 +70,30 @@ contract ArtToken is IArtToken, ArtTokenBase, RoleSystem, EIP712("ArtToken", "1" } /** - * @param main The main account for managing the role system. - * @param auctionHouse AuctionHouse contract address. - * @param usdc USDC asset contract address. + * @notice Contract constructor. + * + * @param proxy Address of the proxy that will ultimately own the + * implementation (used for EIP-712 domain separator). + * @param main Address that will be set as {RoleSystem.MAIN}. + * @param auctionHouse Address of the AuctionHouse contract. + * @param usdc Address of the USDC token contract. + * @param minPrice Absolute minimum `price` accepted by `buy`. + * @param minFee Absolute minimum `fee` accepted by `buy`. + * @param regulated Whether transfer restrictions are enabled. */ constructor( + address proxy, address main, address auctionHouse, address usdc, uint256 minPrice, uint256 minFee, bool regulated - ) RoleSystem(main) { - if (auctionHouse == address(0)) revert ArtTokenMisconfiguration(1); - if (usdc == address(0)) revert ArtTokenMisconfiguration(2); - if (minPrice == 0) revert ArtTokenMisconfiguration(3); - if (minFee == 0) revert ArtTokenMisconfiguration(4); + ) EIP712Domain(proxy, "ArtToken", "1") RoleSystem(main) { + if (auctionHouse == address(0)) revert ArtTokenMisconfiguration(2); + if (usdc == address(0)) revert ArtTokenMisconfiguration(3); + if (minPrice == 0) revert ArtTokenMisconfiguration(4); + if (minFee == 0) revert ArtTokenMisconfiguration(5); AUCTION_HOUSE = IAuctionHouse(auctionHouse); USDC = IERC20(usdc); @@ -85,18 +105,39 @@ contract ArtToken is IArtToken, ArtTokenBase, RoleSystem, EIP712("ArtToken", "1" /** * @inheritdoc IArtToken * - * @dev Mints `tokenId` and transfers it to `to`. Sets `_tokenURI` as the tokenURI of `tokenId`. - * Only account with a minting permission can invoke the method. + * @dev Only the {AUCTION_HOUSE} contract is authorized to call this function. + * The call will revert if `_tokenURI` is empty or if `tokenId` has already been minted. */ - function mint(address to, uint256 tokenId, string memory _tokenURI) external canMint { + function mint(address to, uint256 tokenId, string memory _tokenURI) external onlyAuctionHouse { + if (bytes(_tokenURI).length == 0) { + revert ArtTokenEmptyTokenURI(); + } + _safeMintAndSetTokenURI(to, tokenId, _tokenURI); } /** * @inheritdoc IArtToken * - * @dev Mints `tokenId` and transfers it to `msg.sender` (buyer), charges `price` and `fee` from `msg.sender`, - * distributes `price` between `participants` according to `shares`, and sends `fee` to a platform account. + * @dev Workflow: + * 1. Recreates the EIP-712 digest for the supplied {BuyParams} and verifies + * the signature via {_requireAuthorizedAction}. + * 2. Performs runtime checks listed below; any failure reverts with a + * contract-specific error. + * 3. Mints the token directly to `msg.sender` (buyer). + * 4. Pulls `price + fee` USDC from the buyer. + * 5. Splits `price` among `participants` according to `shares` via + * {Distribution.safeDistribute}. + * 6. Sends `fee` to the protocol treasury (owner of {Roles.FINANCIAL_ROLE}). + * + * Runtime requirements: + * - `params.tokenURI` must be non-empty → {ArtTokenEmptyTokenURI}. + * - `params.price` ≥ {MIN_PRICE} → {ArtTokenInvalidPrice}. + * - `params.fee` ≥ {MIN_FEE} → {ArtTokenInvalidFee}. + * - `AUCTION_HOUSE.tokenReserved(tokenId)` must be false → {ArtTokenTokenReserved}. + * + * @param params Packed struct containing all buy parameters + * (see {IArtToken.BuyParams}). */ function buy(BuyParams calldata params) external { bytes32 structHash = keccak256( @@ -113,80 +154,80 @@ contract ArtToken is IArtToken, ArtTokenBase, RoleSystem, EIP712("ArtToken", "1" ) ); - _requireValidSignature(uniqueRoleAccount(ADMIN_ROLE), structHash, params.deadline, params.signature); + _requireAuthorizedAction(structHash, params.deadline, params.signature); if (bytes(params.tokenURI).length == 0) { revert ArtTokenEmptyTokenURI(); } if (params.price < MIN_PRICE) { - revert ArtTokenInvalidPrice(params.price); + revert ArtTokenInvalidPrice(); } if (params.fee < MIN_FEE) { - revert ArtTokenInvalidFee(params.fee); + revert ArtTokenInvalidFee(); } if (AUCTION_HOUSE.tokenReserved(params.tokenId)) { - revert ArtTokenReserved(params.tokenId); + revert ArtTokenTokenReserved(); } - uint256 payment = params.price + params.fee; + _safeMintAndSetTokenURI(msg.sender, params.tokenId, params.tokenURI); - USDC.safeTransferFrom(msg.sender, address(this), payment); + USDC.safeTransferFrom(msg.sender, address(this), params.price + params.fee); Distribution.safeDistribute(USDC, params.price, params.participants, params.shares); - USDC.safeTransfer(uniqueRoleAccount(FINANCIAL_ROLE), params.fee); - - _safeMintAndSetTokenURI(msg.sender, params.tokenId, params.tokenURI); + USDC.safeTransfer(uniqueRoleOwner(Roles.FINANCIAL_ROLE), params.fee); } /** * @inheritdoc IArtToken */ - function tokenReserved(uint256 tokenId) external view returns (bool) { + function tokenReserved(uint256 tokenId) external view returns (bool reserved) { return _ownerOf(tokenId) != address(0); } /** * @inheritdoc IArtToken */ - function recipientAuthorized(address account) external view returns (bool) { + function recipientAuthorized(address account) public view returns (bool authorized) { if (REGULATED) { - return account.code.length == 0 || hasRole(PARTNER_ROLE, account); + return account.code.length == 0 || hasRole(Roles.PARTNER_ROLE, account); } else { return true; } } - /** - * @dev Throws if the account is not authorized. - */ + /// @dev Reverts unless `account` passes {recipientAuthorized}. function _requireAuthorizedRecipient(address account) private view { - if (REGULATED && account.code.length != 0) _requireRole(PARTNER_ROLE, account); + if (!recipientAuthorized(account)) { + revert ArtTokenUnauthorizedAccount(account); + } } /** - * @dev Overriding the hook. Extends the token-transferring logic, - * checks if a token recipient is authorized. + * @dev Ensures both recipient and authorizing address are compliant before + * any transfer. */ - function _beforeTransfer(address to, uint256 /* tokenId */) internal view override { + function _beforeTransfer(address to, uint256 /* tokenId */, address auth) internal view override { _requireAuthorizedRecipient(to); + _requireAuthorizedRecipient(auth); } /** - * @dev Overriding the hook. Extends the approval-providing logic, - * checks if an approval recipient is authorized. + * @dev Ensures the approval recipient is compliant. */ function _beforeApprove(address to, uint256 /* tokenId */) internal view override { _requireAuthorizedRecipient(to); } /** - * @dev Overriding the hook. Forbids the logic of approval-providing for all tokens. + * @dev Ensures the operator is compliant when `approved` is set to true. */ - function _beforeSetApprovalForAll(address /* operator */, bool /* approved */) internal pure override { - revert ArtTokenForbiddenAction(); + function _beforeSetApprovalForAll(address operator, bool approved) internal view override { + if (approved) { + _requireAuthorizedRecipient(operator); + } } } diff --git a/contracts/art-token/ArtTokenBase.sol b/contracts/art-token/ArtTokenBase.sol index 7d7726b..1a322de 100644 --- a/contracts/art-token/ArtTokenBase.sol +++ b/contracts/art-token/ArtTokenBase.sol @@ -2,48 +2,36 @@ pragma solidity ^0.8.20; import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; -import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; -import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import { + ERC721URIStorageUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; +import { + ERC721EnumerableUpgradeable +} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; /** * @title ArtTokenBase * - * @notice Abstract contract provides a basic, upgradeable implementation of the ERC721 standard. - * @notice The implementation is based on [OpenZeppelin](https://docs.openzeppelin.com/) library - * and includes Enumerable and URIStorage extensions. + * @notice Upgradeable, abstract ERC-721 implementation used as a building block + * for the protocol's ArtToken contracts. + * @notice Relies on OpenZeppelin upgradeable libraries and bundles the + * Enumerable and URIStorage extensions in a single inheritance tree. */ abstract contract ArtTokenBase is ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable { /** - * @dev Initializes the contract by setting a `name` and a `symbol`. + * @notice Initializes the token with a `name` and a `symbol`. + * + * @param _name Token collection name. + * @param _symbol Token collection symbol. */ function initialize(string memory _name, string memory _symbol) external initializer { __ERC721_init(_name, _symbol); } /** - * @dev Mints `tokenId` and transfers it to `to`. Sets `_tokenURI` as the tokenURI of `tokenId`. - */ - function _safeMintAndSetTokenURI(address to, uint256 tokenId, string memory _tokenURI) internal { - _safeMint(to, tokenId); - _setTokenURI(tokenId, _tokenURI); - } - - /** - * @dev Overriding the hook. Adds `_beforeTransfer` hook for extending the token-transferring logic. - */ - function _update( - address to, - uint256 tokenId, - address auth - ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) returns (address) { - _beforeTransfer(to, tokenId); - - return super._update(to, tokenId, auth); - } - - /** - * @dev Overriding the method. Adds `_beforeApprove` hook for extending the approval-providing logic. + * @dev Overrides {ERC721.approve}. Adds the `_beforeApprove` hook so that + * inheriting contracts can introduce custom approval rules. */ function approve(address to, uint256 tokenId) public override(ERC721Upgradeable, IERC721) { _beforeApprove(to, tokenId); @@ -52,8 +40,9 @@ abstract contract ArtTokenBase is ERC721EnumerableUpgradeable, ERC721URIStorageU } /** - * @dev Overriding the method. Adds `_beforeSetApprovalForAll` hook for extending - * the logic of approval-providing for all tokens. + * @dev Overrides {ERC721.setApprovalForAll}. Adds the + * `_beforeSetApprovalForAll` hook so that inheriting contracts can + * introduce custom operator-approval rules. */ function setApprovalForAll(address operator, bool approved) public override(ERC721Upgradeable, IERC721) { _beforeSetApprovalForAll(operator, approved); @@ -61,21 +50,6 @@ abstract contract ArtTokenBase is ERC721EnumerableUpgradeable, ERC721URIStorageU super.setApprovalForAll(operator, approved); } - /** - * @dev The hook to extend the token token-transferring logic. - */ - function _beforeTransfer(address to, uint256 tokenId) internal virtual {} - - /** - * @dev The hook to extend the approval-providing logic. - */ - function _beforeApprove(address to, uint256 tokenId) internal virtual {} - - /** - * @dev The hook to extend the logic of approval-providing for all tokens. - */ - function _beforeSetApprovalForAll(address operator, bool approved) internal virtual {} - /** * @dev An override required by Solidity. */ @@ -94,6 +68,40 @@ abstract contract ArtTokenBase is ERC721EnumerableUpgradeable, ERC721URIStorageU return super.supportsInterface(interfaceId); } + /** + * @dev Helper that performs a safe mint and assigns a token URI in a single + * call. + * + * @param to Recipient of the newly minted token. + * @param tokenId Identifier of the token to mint. + * @param _tokenURI Metadata URI that will be associated with the token. + */ + function _safeMintAndSetTokenURI(address to, uint256 tokenId, string memory _tokenURI) internal { + _safeMint(to, tokenId); + _setTokenURI(tokenId, _tokenURI); + } + + /** + * @dev Overrides the OpenZeppelin internal `_update` function in order to + * plug the `_beforeTransfer` hook. + * + * @param to Address receiving the token. + * @param tokenId Identifier of the token being transferred. + * @param auth Address whose approval is being used for the transfer (may + * be the the owner of the token or an operator). + * + * @return from Address that previously owned the token. + */ + function _update( + address to, + uint256 tokenId, + address auth + ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) returns (address from) { + _beforeTransfer(to, tokenId, auth); + + return super._update(to, tokenId, auth); + } + /** * @dev An override required by Solidity. */ @@ -103,4 +111,30 @@ abstract contract ArtTokenBase is ERC721EnumerableUpgradeable, ERC721URIStorageU ) internal override(ERC721Upgradeable, ERC721EnumerableUpgradeable) { super._increaseBalance(account, amount); } + + /** + * @dev Hook called before any token transfer or mint. + * + * @param to The address receiving the token. + * @param tokenId Identifier of the token being transferred. + * @param auth Address whose approval is being used for the transfer. + */ + function _beforeTransfer(address to, uint256 tokenId, address auth) internal virtual {} + + /** + * @dev Hook called before an approval is granted for a single token. + * + * @param to Address that the approval will be granted to. + * @param tokenId Identifier of the token for which the approval is set. + */ + function _beforeApprove(address to, uint256 tokenId) internal virtual {} + + /** + * @dev Hook called before an operator approval is changed for an account. + * + * @param operator Address whose operator status is being updated. + * @param approved Boolean indicating whether the operator is being approved + * or revoked. + */ + function _beforeSetApprovalForAll(address operator, bool approved) internal virtual {} } diff --git a/contracts/art-token/IArtToken.sol b/contracts/art-token/IArtToken.sol index c834ecb..896f194 100644 --- a/contracts/art-token/IArtToken.sol +++ b/contracts/art-token/IArtToken.sol @@ -6,81 +6,82 @@ import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; /** * @title IArtToken * - * @notice ArtToken contract interface. - * @notice The interface extends ERC721 standard. + * @notice Interface of the DigitalOriginal ERC-721 ArtToken contracts. + * @notice Extends the ERC-721 standard with primary-sale logic, EIP-712 permits and + * compliance helpers used by the protocol. */ interface IArtToken is IERC721 { /** - * @notice Mints a new token. - */ - function mint(address to, uint256 tokenId, string memory _tokenURI) external; - - /** - * @dev Parameters for `buy` method + * @notice Parameters accepted by {buy}. + * + * @param tokenId Identifier of the token to be minted and purchased. + * @param tokenURI Metadata URI that will be permanently associated with the token. + * @param price Total purchase price denominated in the settlement token (USDC). + * @param fee Platform fee that will be additionally charged to the buyer. + * @param participants Addresses that will receive a portion of `price`. + * @param shares Number of shares assigned to each participant; must sum to + * {Distribution.TOTAL_SHARE} in the implementation. + * @param signature EIP-712 signature issued by the trusted signer authorizing the purchase. + * @param deadline Latest UNIX timestamp at which the signature remains valid. */ struct BuyParams { - uint256 tokenId; // Token ID - string tokenURI; // Token URI - uint256 price; // Token price - uint256 fee; // Platform fee - address[] participants; // Participants for reward distribution - uint256[] shares; // Shares for reward distribution - bytes signature; // Permit signed by Admin - uint256 deadline; // Signature expiration deadline in seconds + uint256 tokenId; + string tokenURI; + uint256 price; + uint256 fee; + address[] participants; + uint256[] shares; + bytes signature; + uint256 deadline; } /** - * @notice Mints a new token for a buyer and distributes rewards. + * @notice Mints `tokenId` and transfers it to `to`. + * + * @param to Address that will receive the newly minted token. + * @param tokenId Unique identifier of the token to mint. + * @param _tokenURI Metadata URI that will be associated with the token. */ - function buy(BuyParams calldata params) external; + function mint(address to, uint256 tokenId, string memory _tokenURI) external; /** - * @dev Returns true if the token is reserved. + * @notice Primary sale helper: mints the token and immediately transfers it to the caller. + * + * @param params See {BuyParams}. */ - function tokenReserved(uint256 tokenId) external view returns (bool); + function buy(BuyParams calldata params) external; /** - * @dev Returns true if the account is authorized. + * @notice Returns whether `tokenId` has already been minted (i.e., is reserved). + * + * @param tokenId Token identifier to query. + * + * @return reserved True if the token exists, false otherwise. */ - function recipientAuthorized(address account) external view returns (bool); + function tokenReserved(uint256 tokenId) external view returns (bool reserved); /** - * @dev The caller account is not authorized. + * @notice Checks whether `account` passes the collection's compliance rules. + * @param account Address to query. + * @return authorized True if the account can receive or manage tokens. */ + function recipientAuthorized(address account) external view returns (bool authorized); + + /// @dev Thrown when an action involves an account that is not authorized by the contract rules. error ArtTokenUnauthorizedAccount(address account); - /** - * @dev The token uri is an empty string. - */ + /// @dev Thrown when an empty string is passed as a token URI where a non-empty value is required. error ArtTokenEmptyTokenURI(); - /** - * @dev The price is less than min value. - */ - error ArtTokenInvalidPrice(uint256 value); - - /** - * @dev The fee is less than min value. - */ - error ArtTokenInvalidFee(uint256 value); - - /** - * @dev The token receiver is not valid. - */ - error ArtTokenInvalidReceiver(address receiver); + /// @dev Thrown when `price` supplied to {buy} is below the minimum configured price. + error ArtTokenInvalidPrice(); - /** - * @dev The token is reserved. - */ - error ArtTokenReserved(uint256 tokenId); + /// @dev Thrown when `fee` supplied to {buy} is below the minimum configured fee. + error ArtTokenInvalidFee(); - /** - * @dev The action is forbidden. - */ - error ArtTokenForbiddenAction(); + /// @dev Thrown when attempting to mint or purchase a token that is already owned / reserved. + error ArtTokenTokenReserved(); - /** - * @dev The constructor argument under index `argIndex` is invalid. - */ + /// @dev Thrown when a constructor argument under the provided `argIndex` is invalid (e.g., zero address). error ArtTokenMisconfiguration(uint256 argIndex); } diff --git a/contracts/auction-house/AuctionHouse.sol b/contracts/auction-house/AuctionHouse.sol index 6454d8a..111774c 100644 --- a/contracts/auction-house/AuctionHouse.sol +++ b/contracts/auction-house/AuctionHouse.sol @@ -3,9 +3,11 @@ pragma solidity ^0.8.20; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {EIP712Domain} from "../utils/EIP712Domain.sol"; import {RoleSystem} from "../utils/role-system/RoleSystem.sol"; -import {EIP712} from "../utils/EIP712.sol"; +import {Authorization} from "../utils/Authorization.sol"; import {Distribution} from "../utils/Distribution.sol"; +import {Roles} from "../utils/Roles.sol"; import {IArtToken} from "../art-token/IArtToken.sol"; import {AuctionHouseStorage} from "./AuctionHouseStorage.sol"; import {IAuctionHouse} from "./IAuctionHouse.sol"; @@ -13,144 +15,151 @@ import {IAuctionHouse} from "./IAuctionHouse.sol"; /** * @title AuctionHouse * - * @notice AuctionHouse contract provides functionality to sell Digital Original NFTs according to auction rules. + * @notice Upgradeable English-auction contract that conducts primary sales for + * NFTs minted by {ArtToken}. Users create auctions via an authorized + * EIP-712 permit, place bids in USDC and, after the auction ends, + * the highest bidder receives the token while funds are split between + * participants and the protocol treasury. + * + * @dev Implements {IAuctionHouse}. Uses mix-ins for EIP-712 domain + * separation, role management and signature authorization. */ -contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") { +contract AuctionHouse is IAuctionHouse, EIP712Domain, RoleSystem, Authorization { using SafeERC20 for IERC20; + /** + * @notice EIP-712 struct type-hash used to validate `CreatePermit` signatures + * supplied to {create}. + */ bytes32 public constant CREATE_PERMIT_TYPE_HASH = - // prettier-ignore keccak256( "CreatePermit(" - "uint256 auctionId," - "uint256 tokenId," - "string tokenURI," - "uint256 price," - "uint256 fee," - "uint256 step," - "uint256 endTime," - "address[] participants," - "uint256[] shares," - "uint256 deadline" + "uint256 auctionId," + "uint256 tokenId," + "string tokenURI," + "uint256 price," + "uint256 fee," + "uint256 step," + "uint256 endTime," + "address[] participants," + "uint256[] shares," + "uint256 deadline" ")" ); - IArtToken public immutable ART_TOKEN; // ArtToken contract address - IERC20 public immutable USDC; // USDC asset contract address + /// @notice Address of the associated {ArtToken} contract. + IArtToken public immutable ART_TOKEN; - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); - bytes32 public constant FINANCIAL_ROLE = keccak256("FINANCIAL_ROLE"); + /// @notice Settlement token (USDC) used for bidding and payouts. + IERC20 public immutable USDC; - uint256 public immutable MIN_DURATION; // Minimum auction duration - uint256 public constant MAX_DURATION = 21 days; // Maximum auction duration + /// @notice Minimum auction duration configured at deployment. + uint256 public immutable MIN_DURATION; - uint256 public immutable MIN_PRICE; // Minimum auction price value - uint256 public immutable MIN_FEE; // Minimum auction fee value + /// @notice Hard-coded upper bound for auction duration (21 days). + uint256 public constant MAX_DURATION = 21 days; - /** - * @dev Throws if the auction does not exist. - */ + /// @notice Minimal allowed starting price / bid value. + uint256 public immutable MIN_PRICE; + + /// @notice Minimal platform fee that must accompany each auction. + uint256 public immutable MIN_FEE; + + /// @notice Ensures that an auction with `auctionId` exists. + /// @dev Reverts with {AuctionHouseAuctionNotExists} otherwise. modifier auctionExists(uint256 auctionId) { - if (!_auctionExists(auctionId)) { - revert AuctionHouseAuctionNotExist(auctionId); + if (_auctionExists(auctionId)) { + _; + } else { + revert AuctionHouseAuctionNotExists(); } - - _; } - /** - * @dev Throws if the auction exists. - */ + /// @notice Ensures that no auction with `auctionId` exists yet. + /// @dev Reverts with {AuctionHouseAuctionExists} otherwise. modifier auctionNotExist(uint256 auctionId) { if (_auctionExists(auctionId)) { - revert AuctionHouseAuctionExists(auctionId); + revert AuctionHouseAuctionExists(); + } else { + _; } - - _; } - /** - * @dev Throws if the auction has not yet ended. - */ + /// @notice Ensures the auction has passed its `endTime`. + /// @dev Reverts with {AuctionHouseAuctionNotEnded} if still active. modifier auctionEnded(uint256 auctionId) { - if (!_auctionEnded(auctionId)) { - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - - revert AuctionHouseAuctionNotEnded(auctionId, $.auctions[auctionId].endTime, block.timestamp); + if (_auctionEnded(auctionId)) { + _; + } else { + revert AuctionHouseAuctionNotEnded(); } - - _; } - /** - * @dev Throws if the auction has already ended. - */ + /// @notice Ensures the auction is still active (not ended). + /// @dev Reverts with {AuctionHouseAuctionEnded} if the auction has ended. modifier auctionNotEnded(uint256 auctionId) { if (_auctionEnded(auctionId)) { - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - - revert AuctionHouseAuctionEnded(auctionId, $.auctions[auctionId].endTime, block.timestamp); - } - - _; - } - - /** - * @dev Throws if the token for the auction has already been sold. - */ - modifier notSold(uint256 auctionId) { - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - - if ($.auctions[auctionId].sold) { - revert AuctionHouseTokenSold(auctionId); + revert AuctionHouseAuctionEnded(); + } else { + _; } - - _; } - /** - * @dev Throws if the auction does not have a buyer. - */ + /// @notice Ensures the auction already has a highest bidder recorded. + /// @dev Reverts with {AuctionHouseBuyerNotExists} otherwise. modifier withBuyer(uint256 auctionId) { - if (!_auctionWithBuyer(auctionId)) { - revert AuctionHouseBuyerNotExists(auctionId); + if (_auctionWithBuyer(auctionId)) { + _; + } else { + revert AuctionHouseBuyerNotExists(); } - - _; } - /** - * @dev Throws if the auction has a buyer. - */ + /// @notice Ensures the auction currently has no buyer. + /// @dev Reverts with {AuctionHouseBuyerExists} if a buyer is present. modifier withoutBuyer(uint256 auctionId) { if (_auctionWithBuyer(auctionId)) { - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - - revert AuctionHouseBuyerExists(auctionId, $.auctions[auctionId].buyer); + revert AuctionHouseBuyerExists(); + } else { + _; } + } - _; + /// @notice Ensures `account` is authorized to receive tokens. + /// @dev Reverts with {AuctionHouseUnauthorizedAccount} for non-compliant addresses. + modifier authorizedBuyer(address account) { + if (ART_TOKEN.recipientAuthorized(account)) { + _; + } else { + revert AuctionHouseUnauthorizedAccount(account); + } } /** - * @param main The main account for managing the role system. - * @param artToken ArtToken contract address. - * @param usdc USDC asset contract address. - * @param minAuctionDuration Minimum auction duration in seconds. + * @notice Contract constructor. + * + * @param proxy Proxy address used for EIP-712 verifying contract. + * @param main Address that will be set as {RoleSystem.MAIN}. + * @param artToken Address of the {ArtToken} contract. + * @param usdc Address of the USDC ERC-20 token. + * @param minAuctionDuration Minimum auction duration (seconds). + * @param minPrice Minimum starting price/bid. + * @param minFee Minimum platform fee. */ constructor( + address proxy, address main, address artToken, address usdc, uint256 minAuctionDuration, uint256 minPrice, uint256 minFee - ) RoleSystem(main) { - if (artToken == address(0)) revert AuctionHouseMisconfiguration(1); - if (usdc == address(0)) revert AuctionHouseMisconfiguration(2); - if (minAuctionDuration == 0) revert AuctionHouseMisconfiguration(3); - if (minPrice == 0) revert AuctionHouseMisconfiguration(4); - if (minFee == 0) revert AuctionHouseMisconfiguration(5); + ) EIP712Domain(proxy, "AuctionHouse", "1") RoleSystem(main) { + if (artToken == address(0)) revert AuctionHouseMisconfiguration(2); + if (usdc == address(0)) revert AuctionHouseMisconfiguration(3); + if (minAuctionDuration == 0) revert AuctionHouseMisconfiguration(4); + if (minPrice == 0) revert AuctionHouseMisconfiguration(5); + if (minFee == 0) revert AuctionHouseMisconfiguration(6); ART_TOKEN = IArtToken(artToken); USDC = IERC20(usdc); @@ -162,8 +171,23 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") /** * @inheritdoc IAuctionHouse * - * @dev Creates new `Auction` without `buyer` and with initial `price`. - * Emits `Created` event. + * @dev Flow: + * 1. Validates `params` and the EIP-712 permit signed by the protocol signer. + * 2. Writes a new {IAuctionHouse.Auction} struct to storage and maps + * `params.tokenId` to `params.auctionId`. + * 3. Emits {Created}. + * + * Validation details: + * - Reverts {AuctionHouseEmptyTokenURI} when `tokenURI` is empty. + * - Reverts {AuctionHouseInvalidPrice}, {AuctionHouseInvalidFee}, + * {AuctionHouseInvalidStep} when monetary params are below minima. + * - Reverts {AuctionHouseInvalidEndTime} if `endTime` is not within the + * `[block.timestamp + MIN_DURATION, block.timestamp + MAX_DURATION]` window. + * - Reverts {AuctionHouseTokenReserved} when the token is already locked + * by another auction or minted. + * - Reverts {AuctionHouseAuctionExists} if `auctionId` is already used. + * + * @param params See {IAuctionHouse.CreateParams}. */ function create(CreateParams calldata params) external auctionNotExist(params.auctionId) { bytes32 structHash = keccak256( @@ -182,25 +206,45 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") ) ); - _requireValidSignature(uniqueRoleAccount(ADMIN_ROLE), structHash, params.deadline, params.signature); + _requireAuthorizedAction(structHash, params.deadline, params.signature); - _requireNotEmptyTokenURI(params.tokenURI); + if (bytes(params.tokenURI).length == 0) { + revert AuctionHouseEmptyTokenURI(); + } - _requireValidPrice(params.price); + if (params.price < MIN_PRICE) { + revert AuctionHouseInvalidPrice(); + } - _requireValidFee(params.fee); + if (params.fee < MIN_FEE) { + revert AuctionHouseInvalidFee(); + } - _requireValidStep(params.step); + if (params.step == 0) { + revert AuctionHouseInvalidStep(); + } - _requireValidEndTime(params.endTime); + if (params.endTime < block.timestamp + MIN_DURATION) { + revert AuctionHouseInvalidEndTime(); + } - _requireNotReservedToken(params.tokenId); + if (params.endTime > block.timestamp + MAX_DURATION) { + revert AuctionHouseInvalidEndTime(); + } + + if (tokenReserved(params.tokenId)) { + revert AuctionHouseTokenReserved(); + } + + if (ART_TOKEN.tokenReserved(params.tokenId)) { + revert AuctionHouseTokenReserved(); + } Distribution.requireValidConditions(params.participants, params.shares); AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - $.auctions[params.auctionId] = Auction({ + $.auction[params.auctionId] = Auction({ tokenId: params.tokenId, price: params.price, fee: params.fee, @@ -213,7 +257,7 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") shares: params.shares }); - $.tokenAuctionIds[params.tokenId] = params.auctionId; + $.tokenAuctionId[params.tokenId] = params.auctionId; emit Created(params.auctionId, params.tokenId, params.price, params.endTime); } @@ -221,78 +265,108 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") /** * @inheritdoc IAuctionHouse * - * @dev Charges `price` and `fee` from `msg.sender`, updates `buyer` and `price`. - * Emits `Raised` event. - * New `price` must be greater than or equal to initial `price`. + * @dev First bid path. The function: + * - Checks caller authorization via {authorizedBuyer}. + * - Transfers `newPrice + fee` USDC from the caller to the contract. + * - Stores the caller as `buyer` and `newPrice` as `price`. + * - Emits {Raised}. + * + * Reverts with {AuctionHouseRaiseTooLow} if `newPrice < initial price`. + * + * @param auctionId Identifier of the auction that has no current buyer. + * @param newPrice First bid amount in USDC. */ function raiseInitial( uint256 auctionId, - uint256 price - ) external auctionExists(auctionId) auctionNotEnded(auctionId) withoutBuyer(auctionId) { + uint256 newPrice + ) external authorizedBuyer(msg.sender) auctionExists(auctionId) auctionNotEnded(auctionId) withoutBuyer(auctionId) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - _requireValidRaise(price, $.auctions[auctionId].price, 0); + if (newPrice < $.auction[auctionId].price) { + revert AuctionHouseRaiseTooLow($.auction[auctionId].price); + } - _requireValidBuyer(msg.sender); + emit Raised(auctionId, msg.sender, newPrice); - _raise(auctionId, msg.sender, price); + $.auction[auctionId].buyer = msg.sender; + $.auction[auctionId].price = newPrice; - USDC.safeTransferFrom(msg.sender, address(this), price + $.auctions[auctionId].fee); + USDC.safeTransferFrom(msg.sender, address(this), newPrice + $.auction[auctionId].fee); } /** * @inheritdoc IAuctionHouse * - * @dev Charges `price` and `fee` from `msg.sender`, updates `buyer` and `price`. - * Refunds old `price` and `fee` to the previous `buyer`. Emits `Raised` event. - * New `price` must be greater than or equal to previous `price` plus `step`. + * @dev Subsequent bid path. The function: + * - Transfers `newPrice + fee` from the caller. + * - Refunds `oldPrice + fee` to the previously highest `buyer`. + * - Updates storage and emits {Raised}. + * + * Reverts with {AuctionHouseRaiseTooLow} when `newPrice` is less than + * `current price + step`. + * + * @param auctionId Identifier of the auction with an existing buyer. + * @param newPrice New highest bid in USDC. */ function raise( uint256 auctionId, - uint256 price - ) external auctionExists(auctionId) auctionNotEnded(auctionId) withBuyer(auctionId) { + uint256 newPrice + ) external authorizedBuyer(msg.sender) auctionExists(auctionId) auctionNotEnded(auctionId) withBuyer(auctionId) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - uint256 oldPrice = $.auctions[auctionId].price; - address oldBuyer = $.auctions[auctionId].buyer; + Auction memory _auction = $.auction[auctionId]; - _requireValidRaise(price, oldPrice, $.auctions[auctionId].step); + uint256 price = _auction.price; + address buyer = _auction.buyer; + uint256 step = _auction.step; + uint256 fee = _auction.fee; - _requireValidBuyer(msg.sender); + if (newPrice < price + step) { + revert AuctionHouseRaiseTooLow(price + step); + } - _raise(auctionId, msg.sender, price); + $.auction[auctionId].buyer = msg.sender; + $.auction[auctionId].price = newPrice; - uint256 fee = $.auctions[auctionId].fee; + emit Raised(auctionId, msg.sender, newPrice); - USDC.safeTransferFrom(msg.sender, address(this), price + fee); - USDC.safeTransfer(oldBuyer, oldPrice + fee); + USDC.safeTransferFrom(msg.sender, address(this), newPrice + fee); + USDC.safeTransfer(buyer, price + fee); } /** * @inheritdoc IAuctionHouse * - * @dev Mints a new token for `buyer`. Distributes reward according to `participants` and `shares`. - * Transfers `fee` to platform address. Marks the auction as sold. Emits `Sold` event. + * @dev Finalizes the auction after `endTime`: + * 1. Marks auction as sold and emits {Sold}. + * 2. Mints the NFT to the stored `buyer` via {ArtToken.mint}. + * 3. Transfers the platform `fee` to the treasury (owner of + * {Roles.FINANCIAL_ROLE}). + * 4. Splits the sale `price` among `participants` according to `shares` + * using {Distribution.distribute}. + * + * Reverts with {AuctionHouseTokenSold} if already settled. + * + * @param auctionId Identifier of the auction to settle. */ - function finish( - uint256 auctionId - ) external auctionExists(auctionId) auctionEnded(auctionId) withBuyer(auctionId) notSold(auctionId) { + function finish(uint256 auctionId) external auctionExists(auctionId) auctionEnded(auctionId) withBuyer(auctionId) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - $.auctions[auctionId].sold = true; + Auction memory _auction = $.auction[auctionId]; + + if (_auction.sold) { + revert AuctionHouseTokenSold(); + } + + $.auction[auctionId].sold = true; emit Sold(auctionId); - ART_TOKEN.mint($.auctions[auctionId].buyer, $.auctions[auctionId].tokenId, $.auctions[auctionId].tokenURI); + ART_TOKEN.mint(_auction.buyer, _auction.tokenId, _auction.tokenURI); - USDC.safeTransfer(uniqueRoleAccount(FINANCIAL_ROLE), $.auctions[auctionId].fee); + USDC.safeTransfer(uniqueRoleOwner(Roles.FINANCIAL_ROLE), _auction.fee); - Distribution.distribute( - USDC, - $.auctions[auctionId].price, - $.auctions[auctionId].participants, - $.auctions[auctionId].shares - ); + Distribution.distribute(USDC, _auction.price, _auction.participants, _auction.shares); } /** @@ -301,18 +375,21 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") function auction(uint256 auctionId) external view auctionExists(auctionId) returns (Auction memory) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - return $.auctions[auctionId]; + return $.auction[auctionId]; } /** * @inheritdoc IAuctionHouse + * + * @return reserved True if the token is currently locked by an active + * auction or an ended auction with a buyer. */ - function tokenReserved(uint256 tokenId) public view returns (bool) { + function tokenReserved(uint256 tokenId) public view returns (bool reserved) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - uint256 auctionId = $.tokenAuctionIds[tokenId]; + uint256 auctionId = $.tokenAuctionId[tokenId]; - if (auctionId == 0) { + if (!_auctionExists(auctionId)) { // The auction does not exist return false; } @@ -331,130 +408,24 @@ contract AuctionHouse is IAuctionHouse, RoleSystem, EIP712("AuctionHouse", "1") return false; } - /** - * @dev Returns true if the auction has ended. - */ + /// @dev Internal helper that returns true if `auctionId`'s `endTime` is in the past. function _auctionEnded(uint256 auctionId) private view returns (bool) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - return $.auctions[auctionId].endTime < block.timestamp; + return $.auction[auctionId].endTime <= block.timestamp; } - /** - * @dev Returns true if the auction exists. - */ + /// @dev Internal helper that checks whether an auction struct has been populated. function _auctionExists(uint256 auctionId) private view returns (bool) { - _requireNotZeroId(auctionId); - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - return $.auctions[auctionId].endTime != 0; + return $.auction[auctionId].endTime != 0; } - /** - * @dev Returns true if the auction is with a buyer. - */ + /// @dev Internal helper that returns true when an auction has a non-zero buyer. function _auctionWithBuyer(uint256 auctionId) private view returns (bool) { AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - return $.auctions[auctionId].buyer != address(0); - } - - /** - * @dev Throws if the tokenURI is an empty string. - */ - function _requireNotEmptyTokenURI(string memory tokenURI) private pure { - if (bytes(tokenURI).length == 0) { - revert AuctionHouseEmptyTokenURI(); - } - } - - /** - * @dev Throws if the price is less than min value. - */ - function _requireValidPrice(uint256 price) private view { - if (price < MIN_PRICE) { - revert AuctionHouseInvalidPrice(price); - } - } - - /** - * @dev Throws if the fee is less than min value. - */ - function _requireValidFee(uint256 fee) private view { - if (fee < MIN_FEE) { - revert AuctionHouseInvalidFee(fee); - } - } - - /** - * @dev Throws if the step is zero. - */ - function _requireValidStep(uint256 step) private pure { - if (step == 0) { - revert AuctionHouseInvalidStep(); - } - } - - /** - * @dev Throws if the auction end time is invalid. - */ - function _requireValidEndTime(uint256 endTime) private view { - if (endTime <= block.timestamp + MIN_DURATION) { - revert AuctionHouseInvalidEndTime(endTime, block.timestamp); - } - - if (endTime > block.timestamp + MAX_DURATION) { - revert AuctionHouseInvalidEndTime(endTime, block.timestamp); - } - } - - /** - * @dev Throws if the token is reserved. - */ - function _requireNotReservedToken(uint256 tokenId) private view { - if (tokenReserved(tokenId) || ART_TOKEN.tokenReserved(tokenId)) { - revert AuctionHouseTokenReserved(tokenId); - } - } - - /** - * @dev Throws if the buyer is invalid. - */ - function _requireValidBuyer(address buyer) private view { - if (!ART_TOKEN.recipientAuthorized(buyer)) { - revert AuctionHouseInvalidBuyer(buyer); - } - } - - /** - * @dev Throws if the auction id is zero. - */ - function _requireNotZeroId(uint256 auctionId) private pure { - if (auctionId == 0) { - revert AuctionHouseZeroId(); - } - } - - /** - * @dev Throws if the raise is less than the old price plus the price step. - */ - function _requireValidRaise(uint256 newPrice, uint256 oldPrice, uint256 step) private pure { - if (newPrice < oldPrice + step) { - revert AuctionHouseRaiseTooSmall(newPrice, oldPrice + step); - } - } - - /** - * @dev Updates `buyer` and `price` for the auction `auctionId`. - * Emits `Raised` event. - */ - function _raise(uint256 auctionId, address buyer, uint256 price) private { - AuctionHouseStorage.Layout storage $ = AuctionHouseStorage.layout(); - - $.auctions[auctionId].buyer = buyer; - $.auctions[auctionId].price = price; - - emit Raised(auctionId, buyer, price); + return $.auction[auctionId].buyer != address(0); } } diff --git a/contracts/auction-house/AuctionHouseStorage.sol b/contracts/auction-house/AuctionHouseStorage.sol index 2533d63..d621ac0 100644 --- a/contracts/auction-house/AuctionHouseStorage.sol +++ b/contracts/auction-house/AuctionHouseStorage.sol @@ -6,9 +6,12 @@ import {IAuctionHouse} from "./IAuctionHouse.sol"; /** * @title AuctionHouseStorage * - * @notice AuctionHouseStorage library provides access to AuctionHouse storage layout. + * @notice Defines the unstructured-storage layout for {AuctionHouse}. Using a + * deterministic slot makes the module safe for use behind proxies and + * alongside other upgradeable components. */ library AuctionHouseStorage { + /// @dev Unique storage slot for the layout, derived via EIP-7201 convention. bytes32 private constant STORAGE_SLOT = keccak256(abi.encode(uint256(keccak256("digital-original.storage.AuctionHouse")) - 1)) & ~bytes32(uint256(0xff)); @@ -17,12 +20,14 @@ library AuctionHouseStorage { * @custom:storage-location erc7201:digital-original.storage.AuctionHouse */ struct Layout { - mapping(uint256 auctionId => IAuctionHouse.Auction) auctions; - mapping(uint256 tokenId => uint256 auctionId) tokenAuctionIds; + mapping(uint256 auctionId => IAuctionHouse.Auction) auction; + mapping(uint256 tokenId => uint256) tokenAuctionId; } /** - * @dev Returns storage layout + * @notice Returns a pointer to the pre-allocated storage layout. + * + * @return $ Storage struct containing all auctions and reverse mappings. */ function layout() internal pure returns (Layout storage $) { bytes32 slot = STORAGE_SLOT; diff --git a/contracts/auction-house/IAuctionHouse.sol b/contracts/auction-house/IAuctionHouse.sol index 339418e..218becb 100644 --- a/contracts/auction-house/IAuctionHouse.sol +++ b/contracts/auction-house/IAuctionHouse.sol @@ -4,169 +4,166 @@ pragma solidity ^0.8.20; /** * @title IAuctionHouse * - * @notice AuctionHouse contract interface. + * @notice Interface for the protocol's English-auction module responsible for + * primary NFT sales. Allows creating auctions, placing bids (raises), + * and finalizing sales with revenue distribution. */ interface IAuctionHouse { /** - * @dev Auction storage struct. + * @notice In-memory representation of an auction. + * + * @param tokenId Identifier of the token being sold. + * @param price Current highest bid (or starting price). + * @param fee Platform fee that will be added to the final payment. + * @param step Minimum raise step expressed in settlement-token units. + * @param endTime UNIX timestamp after which the auction can be finalized. + * @param buyer Current highest bidder. + * @param sold Flag indicating whether `finish` has been called. + * @param tokenURI Metadata URI for lazy-minting upon settlement. + * @param participants Revenue-sharing recipients. + * @param shares Number of shares assigned to each participant. */ struct Auction { - uint256 tokenId; // Token ID - uint256 price; // Token price - uint256 fee; // Platform fee - uint256 step; // Price step - uint256 endTime; // Auction end time - address buyer; // Token buyer - bool sold; // Indicator of whether token has been sold - string tokenURI; // Token URI - address[] participants; // Participants for reward distribution - uint256[] shares; // Shares for reward distribution + uint256 tokenId; + uint256 price; + uint256 fee; + uint256 step; + uint256 endTime; + address buyer; + bool sold; + string tokenURI; + address[] participants; + uint256[] shares; } /** - * @dev Triggered when the auction was created. + * @notice Parameters accepted by {create}. + * + * @param auctionId Unique identifier chosen by the caller. + * @param tokenId Identifier of the token that will be minted/sold. + * @param tokenURI Metadata URI. + * @param price Starting price. + * @param fee Platform fee. + * @param step Minimum raise increment. + * @param endTime Auction end timestamp. + * @param participants Revenue-sharing recipients. + * @param shares Shares for each participant. + * @param signature EIP-712 signature issued by protocol signer authorizing the auction. + * @param deadline Expiration timestamp for the signature. */ - event Created(uint256 indexed auctionId, uint256 indexed tokenId, uint256 price, uint256 endTime); + struct CreateParams { + uint256 auctionId; + uint256 tokenId; + string tokenURI; + uint256 price; + uint256 fee; + uint256 step; + uint256 endTime; + address[] participants; + uint256[] shares; + bytes signature; + uint256 deadline; + } /** - * @dev Triggered when the token price was raised. + * @notice Emitted after a successful call to {create}. + * + * @param auctionId Identifier of the newly created auction. + * @param tokenId Token identifier associated with the auction. + * @param price Starting price. + * @param endTime Auction end timestamp. */ - event Raised(uint256 indexed auctionId, address indexed buyer, uint256 price); + event Created(uint256 indexed auctionId, uint256 indexed tokenId, uint256 price, uint256 endTime); /** - * @dev Triggered when the token was sold. + * @notice Emitted each time a new highest bid is placed. + * + * @param auctionId Identifier of the auction. + * @param buyer Address of the bidder. + * @param price New highest bid. */ - event Sold(uint256 indexed auctionId); + event Raised(uint256 indexed auctionId, address indexed buyer, uint256 price); /** - * @dev Parameters for `create` method. + * @notice Emitted when {finish} successfully settles the auction. */ - struct CreateParams { - uint256 auctionId; // Auction ID - uint256 tokenId; // Token ID - string tokenURI; // Token URI - uint256 price; // Token initial price - uint256 fee; // Platform fee - uint256 step; // Price step - uint256 endTime; // Auction end time - address[] participants; // Participants for reward distribution - uint256[] shares; // Shares for reward distribution - bytes signature; // Permit signed by Admin - uint256 deadline; // Signature expiration deadline in seconds - } + event Sold(uint256 indexed auctionId); /** - * @notice Creates a new auction. + * @notice Creates a new auction with parameters validated and authorized via an EIP-712 signature. */ function create(CreateParams calldata params) external; /** - * @notice Raises token price for auction without previous bids. + * @notice Places the first bid on an auction that has no current bidder. */ function raiseInitial(uint256 auctionId, uint256 price) external; /** - * @notice Raises token price for auction with previous bids. + * @notice Places a bid higher than the current highest bid by at least `step`. */ function raise(uint256 auctionId, uint256 price) external; /** - * @notice Mints a new token for a buyer and distributes rewards. + * @notice Finalizes the auction, mints the token to the highest bidder and distributes proceeds. */ function finish(uint256 auctionId) external; /** - * @notice Returns auction. + * @notice Returns the full auction struct for `auctionId`. */ function auction(uint256 auctionId) external view returns (Auction memory); /** - * @dev Returns true if an auction has reserved the token. + * @notice Indicates whether any active auction has reserved `tokenId`. */ - function tokenReserved(uint256 tokenId) external view returns (bool); + function tokenReserved(uint256 tokenId) external view returns (bool reserved); - /** - * @dev The token uri is an empty string. - */ + /// @dev Thrown when an action is attempted by an unauthorized account. + error AuctionHouseUnauthorizedAccount(address account); + + /// @dev Thrown when an empty string is supplied as `tokenURI`. error AuctionHouseEmptyTokenURI(); - /** - * @dev The price is less than min value. - */ - error AuctionHouseInvalidPrice(uint256 value); + /// @dev Thrown when `price` provided is below minimum allowed. + error AuctionHouseInvalidPrice(); - /** - * @dev The fee is less than min value. - */ - error AuctionHouseInvalidFee(uint256 value); + /// @dev Thrown when `fee` provided is below minimum allowed. + error AuctionHouseInvalidFee(); - /** - * @dev The step is zero. - */ + /// @dev Thrown when `step` parameter is zero. error AuctionHouseInvalidStep(); - /** - * @dev The auction end time is less than block time. - */ - error AuctionHouseInvalidEndTime(uint256 endTime, uint256 blockTime); + /// @dev Thrown when `endTime` is outside the permitted window. + error AuctionHouseInvalidEndTime(); - /** - * @dev The token is reserved. - */ - error AuctionHouseTokenReserved(uint256 tokenId); + /// @dev Thrown when the token is already reserved by an auction. + error AuctionHouseTokenReserved(); - /** - * @dev The auction id is zero. - */ - error AuctionHouseZeroId(); + /// @dev Thrown when trying to set a buyer but one already exists. + error AuctionHouseBuyerExists(); - /** - * @dev The token buyer must not exist. - */ - error AuctionHouseBuyerExists(uint256 auctionId, address buyer); + /// @dev Thrown when expected buyer does not exist. + error AuctionHouseBuyerNotExists(); - /** - * @dev The token buyer must exist. - */ - error AuctionHouseBuyerNotExists(uint256 auctionId); + /// @dev Thrown when creating an auction that already exists. + error AuctionHouseAuctionExists(); - /** - * @dev The token buyer is invalid. - */ - error AuctionHouseInvalidBuyer(address buyer); + /// @dev Thrown when referencing a non-existent auction. + error AuctionHouseAuctionNotExists(); - /** - * @dev The auction already exists. - */ - error AuctionHouseAuctionExists(uint256 auctionId); + /// @dev Thrown when the auction has already ended. + error AuctionHouseAuctionEnded(); - /** - * @dev The auction does not exist. - */ - error AuctionHouseAuctionNotExist(uint256 auctionId); + /// @dev Thrown when the auction has not yet ended. + error AuctionHouseAuctionNotEnded(); - /** - * @dev The auction has already ended. - */ - error AuctionHouseAuctionEnded(uint256 auctionId, uint256 endTime, uint256 blockTime); - - /** - * @dev The auction has not yet ended. - */ - error AuctionHouseAuctionNotEnded(uint256 auctionId, uint256 endTime, uint256 blockTime); + /// @dev Thrown when attempting to finish an auction whose token is already sold. + error AuctionHouseTokenSold(); - /** - * @dev The token for the auction has already been sold. - */ - error AuctionHouseTokenSold(uint256 auctionId); + /// @dev Thrown when a raise is below the minimum increment. + error AuctionHouseRaiseTooLow(uint256 minAmount); - /** - * @dev The raise amount is less than minimum raise amount. - */ - error AuctionHouseRaiseTooSmall(uint256 amount, uint256 minAmount); - - /** - * @dev The constructor argument under index `argIndex` is invalid. - */ + /// @dev Thrown when constructor argument at `argIndex` is invalid. error AuctionHouseMisconfiguration(uint256 argIndex); } diff --git a/contracts/tests/DeployerTest.sol b/contracts/tests/DeployerTest.sol new file mode 100644 index 0000000..807048e --- /dev/null +++ b/contracts/tests/DeployerTest.sol @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {Deployment} from "../utils/Deployment.sol"; +import {ArtToken} from "../art-token/ArtToken.sol"; +import {AuctionHouse} from "../auction-house/AuctionHouse.sol"; +import {Roles} from "../utils/Roles.sol"; +import {MarketMock} from "../tests/MarketMock.sol"; +import {USDC} from "../tests/USDC.sol"; + +contract DeployerTest { + event Deployed(address artToken, address auctionHouse, address marketMock, address usdc); + + constructor( + address signer, + address financier, + uint256 minPrice, + uint256 minFee, + uint256 minAuctionDuration, + bool regulated + ) { + address marketMock = address(new MarketMock()); + address usdc = address(new USDC()); + address calculatedArtTokenProxy = Deployment.calculateContractAddress(address(this), 5); + address calculatedAuctionHouseProxy = Deployment.calculateContractAddress(address(this), 6); + + { + address artTokenImpl = address( + new ArtToken( + address(calculatedArtTokenProxy), + address(this), + address(calculatedAuctionHouseProxy), + address(usdc), + minPrice, + minFee, + regulated + ) + ); + + address auctionHouseImpl = address( + new AuctionHouse( + address(calculatedAuctionHouseProxy), + address(this), + address(calculatedArtTokenProxy), + address(usdc), + minAuctionDuration, + minPrice, + minFee + ) + ); + + address artTokenProxy = Deployment.deployUpgradeableContract(artTokenImpl, address(this)); + address auctionHouseProxy = Deployment.deployUpgradeableContract(auctionHouseImpl, address(this)); + + if (artTokenProxy != calculatedArtTokenProxy) revert DeployerIncorrectAddress(); + if (auctionHouseProxy != calculatedAuctionHouseProxy) revert DeployerIncorrectAddress(); + + emit Deployed(artTokenProxy, auctionHouseProxy, marketMock, usdc); + } + + ArtToken(calculatedArtTokenProxy).transferUniqueRole(Roles.SIGNER_ROLE, signer); + ArtToken(calculatedArtTokenProxy).transferUniqueRole(Roles.FINANCIAL_ROLE, financier); + ArtToken(calculatedArtTokenProxy).grantRole(Roles.PARTNER_ROLE, address(calculatedAuctionHouseProxy)); + ArtToken(calculatedArtTokenProxy).grantRole(Roles.PARTNER_ROLE, address(marketMock)); + + AuctionHouse(calculatedAuctionHouseProxy).transferUniqueRole(Roles.FINANCIAL_ROLE, financier); + AuctionHouse(calculatedAuctionHouseProxy).transferUniqueRole(Roles.SIGNER_ROLE, signer); + } + + error DeployerIncorrectAddress(); +} diff --git a/contracts/tests/MarketMock.sol b/contracts/tests/MarketMock.sol new file mode 100644 index 0000000..5a80d25 --- /dev/null +++ b/contracts/tests/MarketMock.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +contract MarketMock { + string public constant NAME = "MarketMock"; +} diff --git a/contracts/tests/USDC.sol b/contracts/tests/USDC.sol index de79c7b..14669c1 100644 --- a/contracts/tests/USDC.sol +++ b/contracts/tests/USDC.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.20; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; @@ -10,7 +10,8 @@ contract USDC is ERC20 { return 6; } - function mint() external { - _mint(msg.sender, 50_000e6); + function mintAndApprove(address spender, uint256 value) external { + _mint(msg.sender, value); + _approve(msg.sender, spender, value); } } diff --git a/contracts/utils/Authorization.sol b/contracts/utils/Authorization.sol new file mode 100644 index 0000000..493eacd --- /dev/null +++ b/contracts/utils/Authorization.sol @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {EIP712Domain} from "./EIP712Domain.sol"; +import {EIP712Signature} from "./EIP712Signature.sol"; +import {RoleSystem} from "./role-system/RoleSystem.sol"; +import {Roles} from "./Roles.sol"; + +/** + * @title Authorization + * + * @notice Mixin that provides EIP-712 based action authorization using a + * dedicated `SIGNER_ROLE` account. Intended to be inherited by + * contracts that need off-chain signatures for sensitive operations. + * + * @dev Relies on {EIP712Domain} for the domain separator and on + * {RoleSystem} for role storage. The helper {_requireAuthorizedAction} + * validates both signature freshness and signer authenticity. + */ +abstract contract Authorization is EIP712Domain, RoleSystem { + /** + * @notice Verifies that `signature` is a valid authorization for + * `messageHash` and that it has not expired. + * + * @dev Reverts with {AuthorizationDeadlineExpired} if `deadline` has passed + * or with {AuthorizationUnauthorizedAction} if the recovered signer + * does not hold the `SIGNER_ROLE`. + * + * @param messageHash EIP-712 struct hash (already `keccak256`-encoded). + * @param deadline UNIX timestamp after which the signature is considered invalid. + * @param signature EIP-712 signature (65/64-byte format accepted by + * {EIP712Signature.recover}). + */ + function _requireAuthorizedAction(bytes32 messageHash, uint256 deadline, bytes calldata signature) internal view { + if (deadline < block.timestamp) { + revert AuthorizationDeadlineExpired(); + } + + address signer = EIP712Signature.recover(DOMAIN_SEPARATOR, messageHash, signature); + + if (uniqueRoleOwner(Roles.SIGNER_ROLE) != signer) { + revert AuthorizationUnauthorizedAction(); + } + } + + /// @dev Revert thrown when the recovered signer lacks `SIGNER_ROLE`. + error AuthorizationUnauthorizedAction(); + + /// @dev Revert thrown when `deadline` has already passed. + error AuthorizationDeadlineExpired(); +} diff --git a/contracts/utils/Deployer.sol b/contracts/utils/Deployer.sol index 551da17..f2e7f4f 100644 --- a/contracts/utils/Deployer.sol +++ b/contracts/utils/Deployer.sol @@ -1,15 +1,54 @@ // SPDX-License-Identifier: GPL-3.0-or-later pragma solidity ^0.8.20; -import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import {ArtToken} from "../art-token/ArtToken.sol"; import {AuctionHouse} from "../auction-house/AuctionHouse.sol"; +import {Deployment} from "./Deployment.sol"; +/** + * @title Deployer + * + * @notice Helper contract that deploys and wires together fresh instances of + * `ArtToken` and `AuctionHouse` behind transparent upgradeable + * proxies. Intended for deterministic deployments during initial + * protocol setup. + * + * @dev The contract self-destructs implicitly after construction (no storage is + * written). It relies on {Deployment.calculateContractAddress} to + * pre-compute the proxy addresses, ensuring that the implementation + * constructors can reference each other before the proxies exist. + */ contract Deployer { + /// @notice Emitted once the proxy contracts are deployed and initialised. + /// @param artToken Address of the newly deployed ArtToken proxy. + /// @param auctionHouse Address of the newly deployed AuctionHouse proxy. event Deployed(address artToken, address auctionHouse); - error DeployerIncorrectAddress(); - + /** + * @notice Deploys upgradeable `ArtToken` and `AuctionHouse` instances. + * + * @dev The constructor performs the following steps: + * 1. Computes the expected proxy addresses using the current + * contract nonce (deploy order is deterministic). + * 2. Deploys the implementation contracts, passing the computed + * proxy addresses so they can reference each other. + * 3. Deploys the transparent proxies via {Deployment.deployUpgradeableContract}. + * 4. Reverts with {DeployerIncorrectAddress} if the actual proxy + * addresses do not match the pre-computed ones (should never + * happen unless the deployment order changes). + * 5. Calls `initialize` on the ArtToken proxy to set `name` and + * `symbol`. + * 6. Emits {Deployed}. + * + * @param name ERC-721 collection name. + * @param symbol ERC-721 collection symbol. + * @param main Address that will be set as {RoleSystem.MAIN}. + * @param usdc Address of the USDC token contract. + * @param minPrice Global minimum primary-sale price. + * @param minFee Global minimum platform fee. + * @param minAuctionDuration Minimum auction duration (seconds) enforced by AuctionHouse. + * @param regulated Whether the ArtToken collection is transfer-restricted. + */ constructor( string memory name, string memory symbol, @@ -20,82 +59,44 @@ contract Deployer { uint256 minAuctionDuration, bool regulated ) { - address _artToken = _contractAddressFrom(address(this), 4); + address calculatedArtTokenProxy = Deployment.calculateContractAddress(address(this), 3); + address calculatedAuctionHouseProxy = Deployment.calculateContractAddress(address(this), 4); - address auctionHouseImpl = address( - new AuctionHouse(main, _artToken, usdc, minAuctionDuration, minPrice, minFee) + address artTokenImpl = address( + new ArtToken( + calculatedArtTokenProxy, + main, + calculatedAuctionHouseProxy, + usdc, + minPrice, + minFee, + regulated // + ) ); - address auctionHouse = _deployUpgradeable(auctionHouseImpl, main); - address artTokenImpl = address(new ArtToken(main, auctionHouse, usdc, minPrice, minFee, regulated)); - address artToken = _deployUpgradeable(artTokenImpl, main); + address auctionHouseImpl = address( + new AuctionHouse( + calculatedAuctionHouseProxy, + main, + calculatedArtTokenProxy, + usdc, + minAuctionDuration, + minPrice, + minFee + ) + ); - if (_artToken != artToken) { - revert DeployerIncorrectAddress(); - } + address artTokenProxy = Deployment.deployUpgradeableContract(artTokenImpl, main); + address auctionHouseProxy = Deployment.deployUpgradeableContract(auctionHouseImpl, main); - ArtToken(_artToken).initialize(name, symbol); + if (artTokenProxy != calculatedArtTokenProxy) revert DeployerIncorrectAddress(); + if (auctionHouseProxy != calculatedAuctionHouseProxy) revert DeployerIncorrectAddress(); - emit Deployed(_artToken, auctionHouse); - } + ArtToken(artTokenProxy).initialize(name, symbol); - function _deployUpgradeable(address impl, address owner) private returns (address) { - return address(new TransparentUpgradeableProxy(impl, owner, "")); + emit Deployed(artTokenProxy, auctionHouseProxy); } - function _contractAddressFrom(address deployer, uint256 nonce) private pure returns (address) { - if (nonce == 0x00) - return - address( - uint160(uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(0x80))))) - ); - if (nonce <= 0x7f) - return - address( - uint160( - uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), deployer, bytes1(uint8(nonce))))) - ) - ); - if (nonce <= 0xff) - return - address( - uint160( - uint256( - keccak256( - abi.encodePacked(bytes1(0xd7), bytes1(0x94), deployer, bytes1(0x81), uint8(nonce)) - ) - ) - ) - ); - if (nonce <= 0xffff) - return - address( - uint160( - uint256( - keccak256( - abi.encodePacked(bytes1(0xd8), bytes1(0x94), deployer, bytes1(0x82), uint16(nonce)) - ) - ) - ) - ); - if (nonce <= 0xffffff) - return - address( - uint160( - uint256( - keccak256( - abi.encodePacked(bytes1(0xd9), bytes1(0x94), deployer, bytes1(0x83), uint24(nonce)) - ) - ) - ) - ); - return - address( - uint160( - uint256( - keccak256(abi.encodePacked(bytes1(0xda), bytes1(0x94), deployer, bytes1(0x84), uint32(nonce))) - ) - ) - ); - } + /// @dev Thrown when the proxies are not deployed at the expected deterministic addresses. + error DeployerIncorrectAddress(); } diff --git a/contracts/utils/Deployment.sol b/contracts/utils/Deployment.sol new file mode 100644 index 0000000..b86fd9b --- /dev/null +++ b/contracts/utils/Deployment.sol @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; + +/** + * @title Deployment + * + * @notice Helper library that simplifies contract deployment logic used in the + * protocol scripts. + * + * @dev Currently exposes two low-level utilities: + * 1. {deployUpgradeableContract} — deploys an `TransparentUpgradeableProxy` + * pointing to an implementation contract. + * 2. {calculateContractAddress} — deterministic computation of the address + * of a contract that would be deployed by `account` at a given nonce + * (matching the algorithm used by the EVM). + */ +library Deployment { + /** + * @notice Deploys a `TransparentUpgradeableProxy` with the provided + * implementation and admin. + * + * @param impl Address of the implementation contract that the + * proxy will delegate‐call to. + * @param proxyAdminOwner Address that will become the owner of the proxy's + * admin contract. + * + * @return proxy Address of the newly deployed proxy. + */ + function deployUpgradeableContract(address impl, address proxyAdminOwner) internal returns (address proxy) { + return address(new TransparentUpgradeableProxy(impl, proxyAdminOwner, "")); + } + + /** + * @notice Predicts the address of a future deployment by `account` at the + * specified nonce. + * + * @dev Mirrors the algorithm used by the `CREATE` opcode. Only supports + * nonces up to `0xffffff` to avoid unnecessary dynamic memory in + * encoding logic. + * + * @param account Deployer address. + * @param nonce Nonce of the deploying account at the time of the future + * deployment. + * + * @return predicted Address the contract will be deployed to. + */ + function calculateContractAddress(address account, uint256 nonce) internal pure returns (address predicted) { + if (nonce == 0x00) { + return + address( + uint160(uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), account, bytes1(0x80))))) + ); + } else if (nonce <= 0x7f) { + return + address( + uint160( + uint256(keccak256(abi.encodePacked(bytes1(0xd6), bytes1(0x94), account, bytes1(uint8(nonce))))) + ) + ); + } else if (nonce <= 0xff) { + return + address( + uint160( + uint256( + keccak256(abi.encodePacked(bytes1(0xd7), bytes1(0x94), account, bytes1(0x81), uint8(nonce))) + ) + ) + ); + } else if (nonce <= 0xffff) { + return + address( + uint160( + uint256( + keccak256( + abi.encodePacked(bytes1(0xd8), bytes1(0x94), account, bytes1(0x82), uint16(nonce)) + ) + ) + ) + ); + } else if (nonce <= 0xffffff) { + return + address( + uint160( + uint256( + keccak256( + abi.encodePacked(bytes1(0xd9), bytes1(0x94), account, bytes1(0x83), uint24(nonce)) + ) + ) + ) + ); + } else { + return + address( + uint160( + uint256( + keccak256( + abi.encodePacked(bytes1(0xda), bytes1(0x94), account, bytes1(0x84), uint32(nonce)) + ) + ) + ) + ); + } + } +} diff --git a/contracts/utils/Distribution.sol b/contracts/utils/Distribution.sol index 71e5912..6849d90 100644 --- a/contracts/utils/Distribution.sol +++ b/contracts/utils/Distribution.sol @@ -3,30 +3,37 @@ pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; /** * @title Distribution * - * @notice Distribution library provides functionality to distribute reward - * and validate distribution conditions. + * @notice Library for deterministic ERC-20 reward splitting. + * + * @dev Provides helpers to safely distribute `reward` among `participants` + * given a {TOTAL_SHARE}-denominated `shares` array (10,000 — + * i.e. basis points). */ library Distribution { using SafeERC20 for IERC20; /** - * @dev Maximum total share. + * @dev Denominator used for share calculations (basis points). */ uint256 internal constant TOTAL_SHARE = 10_000; /** - * @notice Distributes reward between participants according to shares. + * @notice Performs a validation pass and then distributes `reward` between + * `participants` according to `shares`. * - * @dev Validates conditions before distribution. + * @dev Reverts with one of the custom errors declared at the bottom of the + * contract if validation fails. Uses {SafeERC20.safeTransfer} to guard + * against non-standard ERC-20s. * * @param asset ERC20 asset address. * @param reward Amount to distribute. - * @param participants Array with participants address. - * @param shares Array with shares. + * @param participants Addresses that will receive a portion of `reward`. + * @param shares Shares (in basis points) assigned to each participant. */ function safeDistribute( IERC20 asset, @@ -39,19 +46,23 @@ library Distribution { } /** - * @notice Distributes reward between participants according to shares. + * @notice Distributes `reward` between `participants` according to `shares`. + * + * @dev Performs **no** parameter validation — callers MUST ensure that + * {requireValidConditions} has been invoked prior to calling this + * function. * * @param asset ERC20 asset address. * @param reward Amount to distribute. - * @param participants Array with participants address. - * @param shares Array with shares. + * @param participants Addresses that will receive a portion of `reward`. + * @param shares Shares (in basis points) assigned to each participant. */ function distribute(IERC20 asset, uint256 reward, address[] memory participants, uint256[] memory shares) internal { uint256 lastShareIndex = shares.length - 1; - uint256 distributed; + uint256 distributed = 0; for (uint256 i = 0; i < lastShareIndex; ) { - uint256 value = (reward * shares[i]) / TOTAL_SHARE; + uint256 value = Math.mulDiv(reward, shares[i], TOTAL_SHARE); distributed += value; @@ -67,14 +78,25 @@ library Distribution { } /** - * @notice Checks that shares count is equal participants count, - * and sum of shares is equal maximum share. Throws if data is invalid. + * @notice Validates distribution parameters. + * + * @dev Reverts with a custom error if: + * - `participants` and `shares` lengths mismatch; + * - Any participant is the zero address; + * - Any share is zero (via {_sumShares}); + * - Sum of shares exceeds {TOTAL_SHARE} or is below it. * * @param participants Array with participants address. - * @param shares Array with shares. + * @param shares Shares (in basis points) corresponding to each participant. */ function requireValidConditions(address[] memory participants, uint256[] memory shares) internal pure { - for (uint256 i = 0; i < participants.length; ) { + uint256 participantsLen = participants.length; + + if (participantsLen != shares.length) { + revert DistributionParticipantsSharesMismatch(); + } + + for (uint256 i = 0; i < participantsLen; ) { if (participants[i] == address(0)) { revert DistributionZeroAddress(); } @@ -84,37 +106,76 @@ library Distribution { } } - if (shares.length != participants.length) { - revert DistributionInvalidSharesCount(); + uint256 sharesSum = _sumShares(shares); + + if (sharesSum < TOTAL_SHARE) { + revert DistributionSharesSumTooLow(sharesSum); } + } - uint256 sharesSum; + /** + * @notice Calculates the unallocated share given an array of `shares`. + * + * @dev Useful for determining the last participant's share when the + * other shares are known but do not yet sum to {TOTAL_SHARE}. + * + * @param shares Array containing shares expressed in basis points. + * + * @return remaining The difference between {TOTAL_SHARE} and the sum + * of provided `shares`. + */ + function remainingShare(uint256[] memory shares) internal pure returns (uint256 remaining) { + return TOTAL_SHARE - _sumShares(shares); + } - for (uint256 i = 0; i < shares.length; ) { - sharesSum += shares[i]; + /** + * @dev Internal helper that sums the `shares` array while enforcing + * invariants. + * + * Requirements: + * - Every share must be non-zero ({DistributionZeroShare}); + * - Running total must not exceed {TOTAL_SHARE} ({DistributionSharesSumTooBig}). + * + * @param shares Array of shares in basis points. + * + * @return sharesSum Cumulative sum of the shares. + */ + function _sumShares(uint256[] memory shares) private pure returns (uint256 sharesSum) { + uint256 sharesLen = shares.length; + + for (uint256 i = 0; i < sharesLen; ) { + uint256 share = shares[i]; + + if (share == 0) { + revert DistributionZeroShare(); + } + + sharesSum += share; unchecked { i++; } } - if (sharesSum != TOTAL_SHARE) { - revert DistributionInvalidSharesSum(); + if (sharesSum > TOTAL_SHARE) { + revert DistributionSharesSumTooBig(sharesSum); } } /** - * @dev Shares count is not equal participants count. + * @dev Thrown when `participants.length != shares.length`. */ - error DistributionInvalidSharesCount(); + error DistributionParticipantsSharesMismatch(); - /** - * @dev Shares sum is not equal maximum share. - */ - error DistributionInvalidSharesSum(); + /// @dev Thrown when a share value of zero is encountered. + error DistributionZeroShare(); - /** - * @dev Zero address among participants. - */ + /// @dev Thrown when a participant address is the zero address. error DistributionZeroAddress(); + + /// @dev Thrown when `sum(shares) < TOTAL_SHARE`. + error DistributionSharesSumTooLow(uint256 shareSum); + + /// @dev Thrown when `sum(shares) > TOTAL_SHARE`. + error DistributionSharesSumTooBig(uint256 shareSum); } diff --git a/contracts/utils/EIP712.sol b/contracts/utils/EIP712.sol deleted file mode 100644 index 20ce9d4..0000000 --- a/contracts/utils/EIP712.sol +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -pragma solidity ^0.8.20; - -import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; -import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; - -/** - * @title EIP712 - * - * @notice The contract provides signature verification functionality built according - * to [EIP712](https://eips.ethereum.org/EIPS/eip-712) standard. - */ -abstract contract EIP712 { - bytes32 private constant EIP712_TYPE_HASH = - // prettier-ignore - keccak256( - "EIP712Domain(" - "string name," - "string version," - "uint256 chainId," - "address verifyingContract" - ")" - ); - - bytes32 private immutable HASHED_NAME; - bytes32 private immutable HASHED_VERSION; - - /** - * @dev `name` and `version` according to EIP712 - */ - constructor(string memory name, string memory version) { - HASHED_NAME = keccak256(bytes(name)); - HASHED_VERSION = keccak256(bytes(version)); - } - - /** - * @dev Throws if a signature is invalid. - * - * @param signer Expected signer. - * @param structHash Hash of typed structured data, according to EIP712. - * @param deadline Signature. - * @param signature Signature built according to EIP712. - */ - function _requireValidSignature( - address signer, - bytes32 structHash, - uint256 deadline, - bytes memory signature - ) internal view { - if (signer == address(0)) { - revert EIP712SignerZeroAddress(); - } - - if (deadline < block.timestamp) { - revert EIP712ExpiredSignature(); - } - - bytes32 digest = MessageHashUtils.toTypedDataHash(_buildDomainSeparator(), structHash); - address recovered = ECDSA.recover(digest, signature); - - if (recovered != signer) { - revert EIP712InvalidSignature(); - } - } - - /** - * @dev Builds the domain separator. - */ - function _buildDomainSeparator() private view returns (bytes32) { - return keccak256(abi.encode(EIP712_TYPE_HASH, HASHED_NAME, HASHED_VERSION, block.chainid, address(this))); - } - - /** - * @dev The signature expired. - */ - error EIP712ExpiredSignature(); - - /** - * @dev The signature derives an invalid signer. - */ - error EIP712InvalidSignature(); - - /** - * @dev The signer is invalid. - */ - error EIP712SignerZeroAddress(); -} diff --git a/contracts/utils/EIP712Domain.sol b/contracts/utils/EIP712Domain.sol new file mode 100644 index 0000000..aa4779e --- /dev/null +++ b/contracts/utils/EIP712Domain.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +/** + * @title EIP712Domain + * + * @notice Minimal helper that constructs an EIP-712 domain separator once at + * deployment time and exposes it as an immutable constant. + * + * @dev Designed to be inherited by contracts that need typed-data signatures. + * Follows the standard domain schema: + * `EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)`. + */ +contract EIP712Domain { + /** + * @dev Type-hash of the canonical EIP-712 domain. + */ + // prettier-ignore + bytes32 public constant DOMAIN_TYPE_HASH = + keccak256( + "EIP712Domain(" + "string name," + "string version," + "uint256 chainId," + "address verifyingContract" + ")" + ); + + /** + * @notice Fully-qualified EIP-712 domain separator for this contract. + */ + bytes32 public immutable DOMAIN_SEPARATOR; + + /** + * @param verifyingContract Address of the contract that will verify signatures (usually the proxy). + * @param name Human-readable name of the signing domain. + * @param version Current major version of the signing domain. + */ + constructor(address verifyingContract, string memory name, string memory version) { + if (verifyingContract == address(0)) revert EIP712DomainMisconfiguration(0); + if (bytes(name).length == 0) revert EIP712DomainMisconfiguration(1); + if (bytes(version).length == 0) revert EIP712DomainMisconfiguration(2); + + DOMAIN_SEPARATOR = keccak256( + abi.encode( + DOMAIN_TYPE_HASH, + keccak256(bytes(name)), + keccak256(bytes(version)), + block.chainid, + verifyingContract + ) + ); + } + + /** + * @dev Thrown when a constructor argument at position `argIndex` is invalid + * (zero address or empty string). + */ + error EIP712DomainMisconfiguration(uint256 argIndex); +} diff --git a/contracts/utils/EIP712Signature.sol b/contracts/utils/EIP712Signature.sol new file mode 100644 index 0000000..39c7e25 --- /dev/null +++ b/contracts/utils/EIP712Signature.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {MessageHashUtils} from "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; + +/** + * @title EIP712Signature + * + * @notice Lightweight helper for recovering the signer of an EIP-712 typed-data + * signature. Combines OpenZeppelin's {ECDSA} and {MessageHashUtils}. + * + * @dev Reverts with {EIP712SignatureZeroAddress} if signature recovery yields + * the zero address (which indicates an invalid signature). + */ +library EIP712Signature { + /** + * @notice Recovers the signer of an EIP-712 `{structHash}` bound to the + * provided `domainSeparator`. + * + * @param domainSeparator The domain separator used when signing. + * @param structHash Hash of the typed data structure being signed. + * @param signature 65/64-byte ECDSA signature produced by the signer. + * + * @return signer Address that produced the signature. + */ + function recover( + bytes32 domainSeparator, + bytes32 structHash, + bytes calldata signature + ) internal pure returns (address signer) { + bytes32 digest = MessageHashUtils.toTypedDataHash(domainSeparator, structHash); + + signer = ECDSA.recover(digest, signature); + + if (signer == address(0)) { + revert EIP712SignatureZeroAddress(); + } + } + + /// @dev Thrown when signature recovery returns the zero address. + error EIP712SignatureZeroAddress(); +} diff --git a/contracts/utils/Roles.sol b/contracts/utils/Roles.sol new file mode 100644 index 0000000..66e4732 --- /dev/null +++ b/contracts/utils/Roles.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +pragma solidity ^0.8.20; + +/** + * @title Roles + * + * @notice Defines keccak256 hashed identifiers for role-based access control + * used across the protocol. These identifiers are consumed by the + * {RoleSystem} mix-in and contracts that inherit from it. + */ +library Roles { + /// @notice Role that owns protocol fees and treasury funds. + bytes32 internal constant FINANCIAL_ROLE = keccak256("FINANCIAL_ROLE"); + + /// @notice Whitelist role for regulated ArtToken transfers. + bytes32 internal constant PARTNER_ROLE = keccak256("PARTNER_ROLE"); + + /// @notice Role allowed to sign off-chain permits and other authorizations. + bytes32 internal constant SIGNER_ROLE = keccak256("SIGNER_ROLE"); +} diff --git a/contracts/utils/role-system/IRoleSystem.sol b/contracts/utils/role-system/IRoleSystem.sol index 93a0f59..b8abd6a 100644 --- a/contracts/utils/role-system/IRoleSystem.sol +++ b/contracts/utils/role-system/IRoleSystem.sol @@ -4,30 +4,42 @@ pragma solidity ^0.8.20; /** * @title IRoleSystem * - * @notice RoleSystem contract interface. + * @notice Interface describing the on-chain role-based access-control system + * used by the protocol. Provides both multi-owner roles (grant/revoke) + * and unique roles (single owner, transferable). */ interface IRoleSystem { - /* ############################################################ - ROLES - ############################################################ */ - /** - * @dev Emitted when `account` is granted `role`. + * @notice Emitted when `role` is granted to `account`. + * + * @param role Identifier of the role granted. + * @param account Recipient account that now possesses the role. */ event RoleGranted(bytes32 indexed role, address indexed account); /** - * @dev Emitted when `account` is revoked `role`. + * @notice Emitted when `role` is revoked from `account`. + * + * @param role Identifier of the role revoked. + * @param account Account that lost the role. */ event RoleRevoked(bytes32 indexed role, address indexed account); + /** + * @notice Emitted when ownership of a unique role is transferred. + * + * @param role Identifier of the unique role. + * @param newOwner Address that becomes the new (sole) owner of the role. + */ + event UniqueRoleTransferred(bytes32 indexed role, address indexed newOwner); + /** * @notice Grants `role` to `account`. * * @param role The role to be granted. * @param account The account for granting the role. */ - function grandRole(bytes32 role, address account) external; + function grantRole(bytes32 role, address account) external; /** * @notice Revokes `role` from `account`. @@ -38,64 +50,51 @@ interface IRoleSystem { function revokeRole(bytes32 role, address account) external; /** - * @notice Returns true if the account is granted the role, false in if not granted. + * @notice Transfers `uniqueRole` from the previous role owner to `newOwner`. * - * @param role The role to check. - * @param account The account to check. + * @dev Passing the zero address as `newOwner` will effectively revoke the + * role without assigning it to anyone. * - * @dev Throws if the account is zero account. - */ - function hasRole(bytes32 role, address account) external view returns (bool); - - /* ############################################################ - UNIQUE_ROLES - ############################################################ */ - - /** - * @dev Emitted when `role` is transferred form `from` account to `to` account + * @param uniqueRole The role to be transferred. + * @param newOwner The new owner of the unique role (may be address(0)). */ - event UniqueRoleTransferred(address indexed from, address indexed to, bytes32 indexed role); + function transferUniqueRole(bytes32 uniqueRole, address newOwner) external; /** - * @notice Transfers `uniqueRole` from the previous role owner to `account`. + * @notice Checks if `account` has been granted `role`. * - * @dev Transfer a unique role to zero account to revoke the role. + * @dev Reverts with {RoleSystemZeroAddress} when `account` is the zero address. * - * @param uniqueRole The role to be transferred. - * @param to The account of the new role owner. + * @param role The role to query. + * @param account The account to query. + * @return true if `account` possesses `role`, false otherwise. */ - function transferUniqueRole(bytes32 uniqueRole, address to) external; + function hasRole(bytes32 role, address account) external view returns (bool); /** - * @notice Returns the account of the unique role owner. + * @notice Returns the sole owner of `uniqueRole`. * - * @param uniqueRole The unique role of the wanted account. + * @dev Reverts with {RoleSystemZeroAddress} when the role is currently + * unassigned. * - * @dev Throws if the wanted account is zero account. + * @param uniqueRole The unique role to query. + * @return owner Address of the current role owner. */ - function uniqueRoleAccount(bytes32 uniqueRole) external view returns (address account); - - /* ############################################################ - ERRORS - ############################################################ */ + function uniqueRoleOwner(bytes32 uniqueRole) external view returns (address owner); /** - * @dev The sender is not the main account. + * @dev Thrown when a function restricted to the main role owner is called + * by another account. */ error RoleSystemNotMain(); /** - * @dev Zero address was detected. + * @dev Thrown when the zero address is supplied where a non-zero address is required. */ error RoleSystemZeroAddress(); /** - * @dev The account does not have the needed role. - */ - error RoleSystemUnauthorizedAccount(address account, bytes32 neededRole); - - /** - * @dev The constructor argument under index `argIndex` is invalid. + * @dev Thrown when a constructor argument at index `argIndex` is invalid. */ error RoleSystemMisconfiguration(uint256 argIndex); } diff --git a/contracts/utils/role-system/RoleSystem.sol b/contracts/utils/role-system/RoleSystem.sol index 068a229..0fea6a4 100644 --- a/contracts/utils/role-system/RoleSystem.sol +++ b/contracts/utils/role-system/RoleSystem.sol @@ -7,27 +7,21 @@ import {IRoleSystem} from "./IRoleSystem.sol"; /** * @title RoleSystem * - * @notice The contract provides the roles system to control access and get accounts by role. + * @notice Concrete implementation of {IRoleSystem}. Stores role mappings in an + * unstructured-storage slot defined by {RoleSystemStorage} and exposes + * simple grant/revoke/transfer helpers restricted to the immutable + * {MAIN} administrator. */ -abstract contract RoleSystem is IRoleSystem { +contract RoleSystem is IRoleSystem { /** - * @dev The main account. The account can grant and revoke roles and transfer unique roles. + * @notice Account endowed with full administrative privileges over the + * role system (grant, revoke, transfer unique roles). */ address public immutable MAIN; /** - * @dev Sets the main account. - * - * @param main The main account for managing the role system. - */ - constructor(address main) { - if (main == address(0)) revert RoleSystemMisconfiguration(0); - - MAIN = main; - } - - /** - * @dev Throws if sender is not the main account + * @dev Restricts a function so it can only be executed by {MAIN}. Reverts + * with {RoleSystemNotMain} otherwise. */ modifier onlyMain() { if (msg.sender != MAIN) { @@ -37,94 +31,80 @@ abstract contract RoleSystem is IRoleSystem { _; } - /* ############################################################ - ROLES - ############################################################ */ - /** - * @inheritdoc IRoleSystem + * @param main Address that will be set as {MAIN}. Cannot be zero. + * + * @dev Reverts with {RoleSystemMisconfiguration} if `main` is the zero address. */ - function grandRole(bytes32 role, address account) external onlyMain { - if (!hasRole(role, account)) { - RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - - $._roles[role][account] = true; + constructor(address main) { + if (main == address(0)) revert RoleSystemMisconfiguration(0); - emit RoleGranted(role, account); - } + MAIN = main; } /** * @inheritdoc IRoleSystem */ - function revokeRole(bytes32 role, address account) external onlyMain { - if (hasRole(role, account)) { - RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); + function grantRole(bytes32 role, address account) external onlyMain { + _requireNotZeroAddress(account); - $._roles[role][account] = false; + RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - emit RoleRevoked(role, account); - } + $.hasRole[role][account] = true; + + emit RoleGranted(role, account); } /** * @inheritdoc IRoleSystem */ - function hasRole(bytes32 role, address account) public view returns (bool) { - if (account == address(0)) { - revert RoleSystemZeroAddress(); - } + function revokeRole(bytes32 role, address account) external onlyMain { + _requireNotZeroAddress(account); RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - return $._roles[role][account]; + $.hasRole[role][account] = false; + + emit RoleRevoked(role, account); } /** - * @dev Throws if `account` does not have `role`. + * @inheritdoc IRoleSystem */ - function _requireRole(bytes32 role, address account) internal view { - if (!hasRole(role, account)) { - revert RoleSystemUnauthorizedAccount(account, role); - } - } + function transferUniqueRole(bytes32 uniqueRole, address newOwner) external onlyMain { + RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - /* ############################################################ - UNIQUE_ROLES - ############################################################ */ + $.uniqueRoleOwner[uniqueRole] = newOwner; + + emit UniqueRoleTransferred(uniqueRole, newOwner); + } /** * @inheritdoc IRoleSystem */ - function transferUniqueRole(bytes32 uniqueRole, address to) external onlyMain { - RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - - address from = $._uniqueRoles[uniqueRole]; + function hasRole(bytes32 role, address account) public view returns (bool) { + _requireNotZeroAddress(account); - $._uniqueRoles[uniqueRole] = to; + RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - emit UniqueRoleTransferred(from, to, uniqueRole); + return $.hasRole[role][account]; } /** * @inheritdoc IRoleSystem */ - function uniqueRoleAccount(bytes32 uniqueRole) public view returns (address account) { + function uniqueRoleOwner(bytes32 uniqueRole) public view returns (address owner) { RoleSystemStorage.Layout storage $ = RoleSystemStorage.layout(); - account = $._uniqueRoles[uniqueRole]; + owner = $.uniqueRoleOwner[uniqueRole]; - if (account == address(0)) { - revert RoleSystemZeroAddress(); - } + _requireNotZeroAddress(owner); } - /** - * @dev Throws if `account` does not have `uniqueRole`. - */ - function _requireUniqueRole(bytes32 uniqueRole, address account) internal view { - if (uniqueRoleAccount(uniqueRole) != account) { - revert RoleSystemUnauthorizedAccount(account, uniqueRole); + function _requireNotZeroAddress(address account) private pure { + // Internal helper that standardises zero-address checks across the contract. + if (account == address(0)) { + revert RoleSystemZeroAddress(); } } } diff --git a/contracts/utils/role-system/RoleSystemStorage.sol b/contracts/utils/role-system/RoleSystemStorage.sol index c4dfc7c..26249b6 100644 --- a/contracts/utils/role-system/RoleSystemStorage.sol +++ b/contracts/utils/role-system/RoleSystemStorage.sol @@ -4,9 +4,13 @@ pragma solidity ^0.8.20; /** * @title RoleSystemStorage * - * @notice The library provides access to RoleSystem storage layout. + * @notice Defines the unstructured storage layout for {RoleSystem}. Using a + * dedicated storage slot allows the role system to be used behind + * proxies and composed with other modules without risk of slot + * collisions. */ library RoleSystemStorage { + /// @dev Unique storage slot for the layout, computed using EIP-7201 convention. bytes32 private constant STORAGE_SLOT = keccak256(abi.encode(uint256(keccak256("digital-original.storage.RoleSystem")) - 1)) & ~bytes32(uint256(0xff)); @@ -14,12 +18,14 @@ library RoleSystemStorage { * @custom:storage-location erc7201:digital-original.storage.RoleSystem */ struct Layout { - mapping(bytes32 role => mapping(address account => bool)) _roles; - mapping(bytes32 role => address account) _uniqueRoles; + mapping(bytes32 role => mapping(address => bool)) hasRole; + mapping(bytes32 role => address) uniqueRoleOwner; } /** - * @dev Returns storage layout + * @notice Returns a pointer to the pre-allocated storage layout. + * + * @return $ Storage struct with role mappings. */ function layout() internal pure returns (Layout storage $) { bytes32 slot = STORAGE_SLOT; diff --git a/hardhat.config.ts b/hardhat.config.ts index 8c2d5de..1bdba02 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -2,23 +2,23 @@ import fs from 'fs'; import yaml from 'js-yaml'; import dotenv from 'dotenv'; -import { ethers } from 'ethers'; +import { parseEther } from 'ethers'; import '@nomicfoundation/hardhat-toolbox'; import './tasks'; import type { HardhatUserConfig } from 'hardhat/config'; +import type { NetworksUserConfig } from 'hardhat/types'; import type { RecordConfigCollection, RecordConfigEnv } from './types/environment'; -import { NetworksUserConfig } from 'hardhat/types'; dotenv.config(); const configEnv = yaml.load(fs.readFileSync('./config.env.yaml', 'utf8')); const configDo = yaml.load(fs.readFileSync('./config.do.yaml', 'utf8')); -const configDc = yaml.load(fs.readFileSync('./config.dc.yaml', 'utf8')); +const configDn = yaml.load(fs.readFileSync('./config.dn.yaml', 'utf8')); const ENV_MODE = String(process.env.ENV_MODE); -const COLLECTION = <'do' | 'dc'>String(process.env.COLLECTION); +const COLLECTION = <'do' | 'dn'>String(process.env.COLLECTION); const CHAIN_TO_FORK = String(process.env.CHAIN_TO_FORK); const FORKED_CHAIN = String(process.env.FORKED_CHAIN); const FORKED_CHAIN_URL = String(process.env.FORKED_CHAIN_URL); @@ -72,8 +72,8 @@ function buildHardhatConfig(): HardhatUserConfig { if (COLLECTION == 'do') { configCollection = configDo; - } else if (COLLECTION == 'dc') { - configCollection = configDc; + } else if (COLLECTION == 'dn') { + configCollection = configDn; } else { throw new Error(`Invalid 'COLLECTION' value: ${COLLECTION}`); } @@ -120,7 +120,7 @@ function buildHardhatConfig(): HardhatUserConfig { accounts: [ { privateKey: configEnv[CHAIN_TO_FORK].deployerPrivateKey, - balance: ethers.parseEther('100').toString(), + balance: parseEther('100').toString(), }, ], }; diff --git a/package-lock.json b/package-lock.json index 0ba2ee4..504b133 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,21 +13,21 @@ "@openzeppelin/contracts": "^5.0.2", "@openzeppelin/contracts-upgradeable": "^5.0.2", "@types/js-yaml": "^4.0.9", - "dotenv": "^16.4.5", - "hardhat": "^2.22.13", - "husky": "^9.0.11", + "dotenv": "^16.5.0", + "ethers": "^6.14.3", + "hardhat": "^2.24.1", + "husky": "^9.1.7", "js-yaml": "^4.1.0", - "lint-staged": "^15.2.2", - "prettier": "^3.2.5", - "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.3" + "lint-staged": "^16.1.0", + "prettier": "^3.5.3", + "prettier-plugin-solidity": "^2.0.0", + "solhint": "^5.1.0" } }, "node_modules/@adraffy/ens-normalize": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz", - "integrity": "sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==", - "peer": true + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==" }, "node_modules/@babel/code-frame": { "version": "7.22.13", @@ -62,6 +62,12 @@ "node": ">=6.9.0" } }, + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.17.2", + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.2.tgz", + "integrity": "sha512-mNm/lblgES8UkVle8rGImXOz4TtL3eU3inHay/7TVchkKrb/lgcVvTK0+VAw8p5zQ0rgQsXm1j5dOlAAd+MeoA==", + "license": "(Apache-2.0 WITH LLVM-exception)" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -137,9 +143,9 @@ } }, "node_modules/@ethersproject/abi": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.7.0.tgz", - "integrity": "sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", "funding": [ { "type": "individual", @@ -150,22 +156,23 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, "node_modules/@ethersproject/abstract-provider": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz", - "integrity": "sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", "funding": [ { "type": "individual", @@ -176,20 +183,21 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" } }, "node_modules/@ethersproject/abstract-signer": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz", - "integrity": "sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", "funding": [ { "type": "individual", @@ -200,18 +208,19 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" } }, "node_modules/@ethersproject/address": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.7.0.tgz", - "integrity": "sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", "funding": [ { "type": "individual", @@ -222,18 +231,19 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/rlp": "^5.7.0" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" } }, "node_modules/@ethersproject/base64": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.7.0.tgz", - "integrity": "sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", "funding": [ { "type": "individual", @@ -244,14 +254,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0" + "@ethersproject/bytes": "^5.8.0" } }, "node_modules/@ethersproject/basex": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.7.0.tgz", - "integrity": "sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", + "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", "funding": [ { "type": "individual", @@ -262,16 +273,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/properties": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/properties": "^5.8.0" } }, "node_modules/@ethersproject/bignumber": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.7.0.tgz", - "integrity": "sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", "funding": [ { "type": "individual", @@ -282,16 +294,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", "bn.js": "^5.2.1" } }, "node_modules/@ethersproject/bytes": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.7.0.tgz", - "integrity": "sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", "funding": [ { "type": "individual", @@ -302,14 +315,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/constants": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.7.0.tgz", - "integrity": "sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", "funding": [ { "type": "individual", @@ -320,14 +334,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bignumber": "^5.7.0" + "@ethersproject/bignumber": "^5.8.0" } }, "node_modules/@ethersproject/contracts": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.7.0.tgz", - "integrity": "sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", + "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", "funding": [ { "type": "individual", @@ -338,24 +353,25 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/transactions": "^5.7.0" + "@ethersproject/abi": "^5.8.0", + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0" } }, "node_modules/@ethersproject/hash": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.7.0.tgz", - "integrity": "sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", "funding": [ { "type": "individual", @@ -366,22 +382,23 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, "node_modules/@ethersproject/hdnode": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.7.0.tgz", - "integrity": "sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", + "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", "funding": [ { "type": "individual", @@ -392,26 +409,27 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" } }, "node_modules/@ethersproject/json-wallets": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz", - "integrity": "sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", + "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", "funding": [ { "type": "individual", @@ -422,19 +440,20 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/pbkdf2": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", "aes-js": "3.0.0", "scrypt-js": "3.0.1" } @@ -443,12 +462,13 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "license": "MIT", "peer": true }, "node_modules/@ethersproject/keccak256": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.7.0.tgz", - "integrity": "sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", "funding": [ { "type": "individual", @@ -459,15 +479,16 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", + "@ethersproject/bytes": "^5.8.0", "js-sha3": "0.8.0" } }, "node_modules/@ethersproject/logger": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.7.0.tgz", - "integrity": "sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", "funding": [ { "type": "individual", @@ -477,12 +498,13 @@ "type": "individual", "url": "https://www.buymeacoffee.com/ricmoo" } - ] + ], + "license": "MIT" }, "node_modules/@ethersproject/networks": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.7.1.tgz", - "integrity": "sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", "funding": [ { "type": "individual", @@ -493,14 +515,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/pbkdf2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz", - "integrity": "sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", + "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", "funding": [ { "type": "individual", @@ -511,16 +534,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/sha2": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/sha2": "^5.8.0" } }, "node_modules/@ethersproject/properties": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.7.0.tgz", - "integrity": "sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", "funding": [ { "type": "individual", @@ -531,14 +555,15 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/logger": "^5.7.0" + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/providers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.7.2.tgz", - "integrity": "sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", + "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", "funding": [ { "type": "individual", @@ -549,41 +574,43 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/base64": "^5.7.0", - "@ethersproject/basex": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/networks": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/web": "^5.7.0", + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0", "bech32": "1.1.4", - "ws": "7.4.6" + "ws": "8.18.0" } }, "node_modules/@ethersproject/providers/node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "license": "MIT", "peer": true, "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -595,9 +622,9 @@ } }, "node_modules/@ethersproject/random": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.7.0.tgz", - "integrity": "sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", + "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", "funding": [ { "type": "individual", @@ -608,16 +635,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/rlp": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.7.0.tgz", - "integrity": "sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", "funding": [ { "type": "individual", @@ -628,15 +656,16 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/sha2": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.7.0.tgz", - "integrity": "sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", + "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", "funding": [ { "type": "individual", @@ -647,17 +676,18 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", "hash.js": "1.1.7" } }, "node_modules/@ethersproject/signing-key": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.7.0.tgz", - "integrity": "sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", "funding": [ { "type": "individual", @@ -668,19 +698,20 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", "bn.js": "^5.2.1", - "elliptic": "6.5.4", + "elliptic": "6.6.1", "hash.js": "1.1.7" } }, "node_modules/@ethersproject/solidity": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.7.0.tgz", - "integrity": "sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", + "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", "funding": [ { "type": "individual", @@ -691,20 +722,21 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/sha2": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, "node_modules/@ethersproject/strings": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.7.0.tgz", - "integrity": "sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", "funding": [ { "type": "individual", @@ -715,16 +747,17 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/transactions": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.7.0.tgz", - "integrity": "sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", "funding": [ { "type": "individual", @@ -735,22 +768,23 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/rlp": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0" + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" } }, "node_modules/@ethersproject/units": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.7.0.tgz", - "integrity": "sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", + "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", "funding": [ { "type": "individual", @@ -761,17 +795,18 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/constants": "^5.7.0", - "@ethersproject/logger": "^5.7.0" + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" } }, "node_modules/@ethersproject/wallet": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.7.0.tgz", - "integrity": "sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", + "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", "funding": [ { "type": "individual", @@ -782,29 +817,30 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, - "dependencies": { - "@ethersproject/abstract-provider": "^5.7.0", - "@ethersproject/abstract-signer": "^5.7.0", - "@ethersproject/address": "^5.7.0", - "@ethersproject/bignumber": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/hdnode": "^5.7.0", - "@ethersproject/json-wallets": "^5.7.0", - "@ethersproject/keccak256": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/random": "^5.7.0", - "@ethersproject/signing-key": "^5.7.0", - "@ethersproject/transactions": "^5.7.0", - "@ethersproject/wordlists": "^5.7.0" + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/json-wallets": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" } }, "node_modules/@ethersproject/web": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.7.1.tgz", - "integrity": "sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", "funding": [ { "type": "individual", @@ -815,18 +851,19 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "dependencies": { - "@ethersproject/base64": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, "node_modules/@ethersproject/wordlists": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.7.0.tgz", - "integrity": "sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", + "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", "funding": [ { "type": "individual", @@ -837,13 +874,14 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], + "license": "MIT", "peer": true, "dependencies": { - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/hash": "^5.7.0", - "@ethersproject/logger": "^5.7.0", - "@ethersproject/properties": "^5.7.0", - "@ethersproject/strings": "^5.7.0" + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" } }, "node_modules/@fastify/busboy": { @@ -879,53 +917,10 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@metamask/eth-sig-util": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz", - "integrity": "sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ==", - "dependencies": { - "ethereumjs-abi": "^0.6.8", - "ethereumjs-util": "^6.2.1", - "ethjs-util": "^0.1.6", - "tweetnacl": "^1.0.3", - "tweetnacl-util": "^0.15.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@metamask/eth-sig-util/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/@metamask/eth-sig-util/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, "node_modules/@noble/curves": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", - "peer": true, "dependencies": { "@noble/hashes": "1.3.2" }, @@ -937,7 +932,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", - "peer": true, "engines": { "node": ">= 16" }, @@ -992,143 +986,91 @@ } }, "node_modules/@nomicfoundation/edr": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.6.4.tgz", - "integrity": "sha512-YgrSuT3yo5ZQkbvBGqQ7hG+RDvz3YygSkddg4tb1Z0Y6pLXFzwrcEwWaJCFAVeeZxdxGfCgGMUYgRVneK+WXkw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.11.0.tgz", + "integrity": "sha512-36WERf8ldvyHR6UAbcYsa+vpbW7tCrJGBwF4gXSsb8+STj1n66Hz85Y/O7B9+8AauX3PhglvV5dKl91tk43mWw==", + "license": "MIT", "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.6.4", - "@nomicfoundation/edr-darwin-x64": "0.6.4", - "@nomicfoundation/edr-linux-arm64-gnu": "0.6.4", - "@nomicfoundation/edr-linux-arm64-musl": "0.6.4", - "@nomicfoundation/edr-linux-x64-gnu": "0.6.4", - "@nomicfoundation/edr-linux-x64-musl": "0.6.4", - "@nomicfoundation/edr-win32-x64-msvc": "0.6.4" + "@nomicfoundation/edr-darwin-arm64": "0.11.0", + "@nomicfoundation/edr-darwin-x64": "0.11.0", + "@nomicfoundation/edr-linux-arm64-gnu": "0.11.0", + "@nomicfoundation/edr-linux-arm64-musl": "0.11.0", + "@nomicfoundation/edr-linux-x64-gnu": "0.11.0", + "@nomicfoundation/edr-linux-x64-musl": "0.11.0", + "@nomicfoundation/edr-win32-x64-msvc": "0.11.0" }, "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.4.tgz", - "integrity": "sha512-QNQErISLgssV9+qia8sIjRANqtbW8snSDvjspixT/kSQ5ZSGxxctTg7x72wPSrcu8+EBEveIe5uqENIp5GH8HQ==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.11.0.tgz", + "integrity": "sha512-aYTVdcSs27XG7ayTzvZ4Yn9z/ABSaUwicrtrYK2NR8IH0ik4N4bWzo/qH8rax6rewVLbHUkGyGYnsy5ZN4iiMw==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.4.tgz", - "integrity": "sha512-cjVmREiwByyc9+oGfvAh49IAw+oVJHF9WWYRD+Tm/ZlSpnEVWxrGNBak2bd/JSYjn+mZE7gmWS4SMRi4nKaLUg==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.11.0.tgz", + "integrity": "sha512-RxX7UYgvJrfcyT/uHUn44Nsy1XaoW+Q1khKMdHKxeW7BrgIi+Lz+siz3bX5vhSoAnKilDPhIVLrnC8zxQhjR2A==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.4.tgz", - "integrity": "sha512-96o9kRIVD6W5VkgKvUOGpWyUGInVQ5BRlME2Fa36YoNsRQMaKtmYJEU0ACosYES6ZTpYC8U5sjMulvPtVoEfOA==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.11.0.tgz", + "integrity": "sha512-J0j+rs0s11FuSipt/ymqrFmpJ7c0FSz1/+FohCIlUXDxFv//+1R/8lkGPjEYFmy8DPpk/iO8mcpqHTGckREbqA==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.4.tgz", - "integrity": "sha512-+JVEW9e5plHrUfQlSgkEj/UONrIU6rADTEk+Yp9pbe+mzNkJdfJYhs5JYiLQRP4OjxH4QOrXI97bKU6FcEbt5Q==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.11.0.tgz", + "integrity": "sha512-4r32zkGMN7WT/CMEuW0VjbuEdIeCskHNDMW4SSgQSJOE/N9L1KSLJCSsAbPD3aYE+e4WRDTyOwmuLjeUTcLZKQ==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.4.tgz", - "integrity": "sha512-nzYWW+fO3EZItOeP4CrdMgDXfaGBIBkKg0Y/7ySpUxLqzut40O4Mb0/+quqLAFkacUSWMlFp8nsmypJfOH5zoA==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.11.0.tgz", + "integrity": "sha512-SmdncQHLYtVNWLIMyGaY6LpAfamzTDe3fxjkirmJv3CWR5tcEyC6LMui/GsIVnJzXeNJBXAzwl8hTUAxHTM6kQ==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.4.tgz", - "integrity": "sha512-QFRoE9qSQ2boRrVeQ1HdzU+XN7NUgwZ1SIy5DQt4d7jCP+5qTNsq8LBNcqhRBOATgO63nsweNUhxX/Suj5r1Sw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.11.0.tgz", + "integrity": "sha512-w6hUqpn/trwiH6SRuRGysj37LsQVCX5XDCA3Xi81sbOaLhbHrNvK9TXWyZmcuzbdTKQQW6VNywcSxDdOiChcJg==", + "license": "MIT", "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.4.tgz", - "integrity": "sha512-2yopjelNkkCvIjUgBGhrn153IBPLwnsDeNiq6oA0WkeM8tGmQi4td+PGi9jAriUDAkc59Yoi2q9hYA6efiY7Zw==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.11.0.tgz", + "integrity": "sha512-BLmULjRKoH9BsX+c4Na2ypV7NGeJ+M6Zpqj/faPOwleVscDdSr/IhriyPaXCe8dyfwbge7lWsbekiADtPSnB2Q==", + "license": "MIT", "engines": { "node": ">= 18" } }, - "node_modules/@nomicfoundation/ethereumjs-common": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", - "integrity": "sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==", - "dependencies": { - "@nomicfoundation/ethereumjs-util": "9.0.4" - } - }, - "node_modules/@nomicfoundation/ethereumjs-rlp": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz", - "integrity": "sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==", - "bin": { - "rlp": "bin/rlp.cjs" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@nomicfoundation/ethereumjs-tx": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz", - "integrity": "sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==", - "dependencies": { - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, - "node_modules/@nomicfoundation/ethereumjs-util": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz", - "integrity": "sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==", - "dependencies": { - "@nomicfoundation/ethereumjs-rlp": "5.0.4", - "ethereum-cryptography": "0.1.3" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "c-kzg": "^2.1.2" - }, - "peerDependenciesMeta": { - "c-kzg": { - "optional": true - } - } - }, "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.2.tgz", - "integrity": "sha512-9Wu9mRtkj0U9ohgXYFbB/RQDa+PcEdyBm2suyEtsJf3PqzZEEjLUZgWnMjlFhATMk/fp3BjmnYVPrwl+gr8oEw==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.0.8.tgz", + "integrity": "sha512-Z5PiCXH4xhNLASROlSUOADfhfpfhYO6D7Hn9xp8PddmHey0jq704cr6kfU8TRrQ4PUZbpfsZadPj+pCfZdjPIg==", + "license": "MIT", "peer": true, "dependencies": { "@types/chai-as-promised": "^7.1.3", @@ -1144,9 +1086,10 @@ } }, "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.4.tgz", - "integrity": "sha512-k9qbLoY7qn6C6Y1LI0gk2kyHXil2Tauj4kGzQ8pgxYXIGw8lWn8tuuL72E11CrlKaXRUvOgF0EXrv/msPI2SbA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.0.8.tgz", + "integrity": "sha512-zhOZ4hdRORls31DTOqg+GmEZM0ujly8GGIuRY7t7szEk2zW/arY1qDug/py8AEktT00v5K+b6RvbVog+va51IA==", + "license": "MIT", "peer": true, "dependencies": { "debug": "^4.1.1", @@ -1158,16 +1101,18 @@ } }, "node_modules/@nomicfoundation/hardhat-ignition": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.0.tgz", - "integrity": "sha512-GbAe90O22uM67U/JnffXX+mBMn0HqCKSH+D98Tb5uWqR1N/M00cB3yY8OdqzVai7I6SuIKTc91mPdvtWt8R3MA==", + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition/-/hardhat-ignition-0.15.11.tgz", + "integrity": "sha512-OXebmK9FCMwwbb4mIeHBbVFFicAGgyGKJT2zrONrpixrROxrVs6KEi1gzsiN25qtQhCQePt8BTjjYrgy86Dfxg==", + "license": "MIT", "peer": true, "dependencies": { - "@nomicfoundation/ignition-core": "^0.15.0", - "@nomicfoundation/ignition-ui": "^0.15.0", + "@nomicfoundation/ignition-core": "^0.15.11", + "@nomicfoundation/ignition-ui": "^0.15.11", "chalk": "^4.0.0", "debug": "^4.3.2", "fs-extra": "^10.0.0", + "json5": "^2.2.3", "prompts": "^2.4.2" }, "peerDependencies": { @@ -1176,14 +1121,15 @@ } }, "node_modules/@nomicfoundation/hardhat-ignition-ethers": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.0.tgz", - "integrity": "sha512-KmMNUc/jptfwdPA9ukQf+Ajon+m2vLBjDL2ze7d/vQdrS+fDxmoVwmbbEk4GOjianZcwgQOWD9dEWaj04QiowA==", + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ignition-ethers/-/hardhat-ignition-ethers-0.15.11.tgz", + "integrity": "sha512-srXzvf7qCDHLrnvQWtpVA9gWpcbp4BcnsOqJt6ISet9OlUnxk4GgRMbdFq4YpM48bHQTX397jS9yk1AtJCjt/g==", + "license": "MIT", "peer": true, "peerDependencies": { "@nomicfoundation/hardhat-ethers": "^3.0.4", - "@nomicfoundation/hardhat-ignition": "^0.15.0", - "@nomicfoundation/ignition-core": "^0.15.0", + "@nomicfoundation/hardhat-ignition": "^0.15.11", + "@nomicfoundation/ignition-core": "^0.15.11", "ethers": "^6.7.0", "hardhat": "^2.18.0" } @@ -1273,9 +1219,10 @@ } }, "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.9.tgz", - "integrity": "sha512-OXWCv0cHpwLUO2u7bFxBna6dQtCC2Gg/aN/KtJLO7gmuuA28vgmVKYFRCDUqrbjujzgfwQ2aKyZ9Y3vSmDqS7Q==", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.12.tgz", + "integrity": "sha512-xTNQNI/9xkHvjmCJnJOTyqDSl8uq1rKb2WOVmixQxFtRd7Oa3ecO8zM0cyC2YmOK+jHB9WPZ+F/ijkHg1CoORA==", + "license": "MIT", "peer": true, "dependencies": { "ethereumjs-util": "^7.1.4" @@ -1288,6 +1235,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-5.0.0.tgz", "integrity": "sha512-FnUtUC5PsakCbwiVNsqlXVIWG5JIb5CEZoSXbJUsEBun22Bivx2jhF1/q9iQbzuaGpJKFQyOhemPB2+XlEE6pQ==", + "license": "MIT", "peerDependencies": { "@nomicfoundation/hardhat-chai-matchers": "^2.0.0", "@nomicfoundation/hardhat-ethers": "^3.0.0", @@ -1310,32 +1258,35 @@ } }, "node_modules/@nomicfoundation/hardhat-verify": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.3.tgz", - "integrity": "sha512-ESbRu9by53wu6VvgwtMtm108RSmuNsVqXtzg061D+/4R7jaWh/Wl/8ve+p6SdDX7vA1Z3L02hDO1Q3BY4luLXQ==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.14.tgz", + "integrity": "sha512-z3iVF1WYZHzcdMMUuureFpSAfcnlfJbJx3faOnGrOYg6PRTki1Ut9JAuRccnFzMHf1AmTEoSUpWcyvBCoxL5Rg==", + "license": "MIT", "peer": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^8.1.0", - "chalk": "^2.4.2", "debug": "^4.1.1", "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", "semver": "^6.3.0", "table": "^6.8.0", "undici": "^5.14.0" }, "peerDependencies": { - "hardhat": "^2.0.4" + "hardhat": "^2.24.1" } }, "node_modules/@nomicfoundation/ignition-core": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.0.tgz", - "integrity": "sha512-d/h8jgJHY4xIroHqdaGeTkTqjQeuzmU759AOn1Fg88cuxVhS7JM22ZI0bQWyLNSMsVstHBIo+lSMIsvm9jBF2w==", + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-core/-/ignition-core-0.15.11.tgz", + "integrity": "sha512-PeYKRlrQ0koT72yRnlyyG66cXMFiv5X/cIB8hBFPl3ekeg5tPXcHAgs/VZhOsgwEox4ejphTtItLESb1IDBw0w==", + "license": "MIT", "peer": true, "dependencies": { "@ethersproject/address": "5.6.1", + "@nomicfoundation/solidity-analyzer": "^0.1.1", "cbor": "^9.0.0", "debug": "^4.3.2", "ethers": "^6.7.0", @@ -1395,11 +1346,20 @@ } }, "node_modules/@nomicfoundation/ignition-ui": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.0.tgz", - "integrity": "sha512-RBvvQ0e8RcEc/LoSzNTPVKZZ5vEwlmxt7PXG278+6DqCrOqxqmh6W9PtK/4mwwvnTeBqds+8j81jDf6vJbOVBQ==", + "version": "0.15.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/ignition-ui/-/ignition-ui-0.15.11.tgz", + "integrity": "sha512-VPOVl5xqCKhYCyPOQlposx+stjCwqXQ+BCs5lnw/f2YUfgII+G5Ye0JfHiJOfCJGmqyS03WertBslcj9zQg50A==", "peer": true }, + "node_modules/@nomicfoundation/slang": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-1.1.0.tgz", + "integrity": "sha512-g2BofMUq1qCP22L/ksOftScrCxjdHTxgg8ch5PYon2zfSSKGCMwE4TgIC64CuorMcSsvCmqNNFEWR/fwFcMeTw==", + "license": "MIT", + "dependencies": { + "@bytecodealliance/preview2-shim": "0.17.2" + } + }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", @@ -1621,9 +1581,10 @@ } }, "node_modules/@scure/base": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.3.tgz", - "integrity": "sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q==", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "license": "MIT", "funding": { "url": "https://paulmillr.com/funding/" } @@ -1948,7 +1909,8 @@ "node_modules/@types/js-yaml": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", - "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==" + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "license": "MIT" }, "node_modules/@types/lru-cache": { "version": "5.1.1", @@ -1968,17 +1930,18 @@ "peer": true }, "node_modules/@types/node": { - "version": "20.8.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz", - "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==", + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", "dependencies": { - "undici-types": "~5.25.1" + "undici-types": "~6.19.2" } }, "node_modules/@types/pbkdf2": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.1.tgz", "integrity": "sha512-4HCoGwR3221nOc7G0Z/6KgTNGgaaFGkbGrtUJsB+zlKX2LBVjFHHIUkieMBgHHXgBH5Gq6dZHJKdBYdtlhBQvw==", + "peer": true, "dependencies": { "@types/node": "*" } @@ -1999,6 +1962,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.5.tgz", "integrity": "sha512-aIonTBMErtE3T9MxDvTZRzcrT/mCqpEZBw3CCY/i+oG9n57N/+7obBkhFgavUAIrX21bU0LHg1XRgtaLdelBhA==", + "peer": true, "dependencies": { "@types/node": "*" } @@ -2030,15 +1994,6 @@ "node": ">=0.4.0" } }, - "node_modules/address": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", - "peer": true, - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/adm-zip": { "version": "0.4.16", "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", @@ -2050,8 +2005,7 @@ "node_modules/aes-js": { "version": "4.0.0-beta.5", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", - "peer": true + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==" }, "node_modules/agent-base": { "version": "6.0.2", @@ -2285,12 +2239,13 @@ } }, "node_modules/axios": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", - "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.9.0.tgz", + "integrity": "sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==", + "license": "MIT", "peer": true, "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } @@ -2301,9 +2256,11 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "peer": true, "dependencies": { "safe-buffer": "^5.0.1" } @@ -2312,6 +2269,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "license": "MIT", "peer": true }, "node_modules/binary-extensions": { @@ -2325,7 +2283,8 @@ "node_modules/blakejs": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==" + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "peer": true }, "node_modules/bn.js": { "version": "5.2.1", @@ -2453,17 +2412,18 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "peer": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2483,6 +2443,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "peer": true, "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -2496,6 +2457,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "peer": true, "dependencies": { "base-x": "^3.0.2" } @@ -2504,6 +2466,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "peer": true, "dependencies": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -2518,7 +2481,8 @@ "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==" + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "peer": true }, "node_modules/bytes": { "version": "3.1.2", @@ -2714,6 +2678,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "peer": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -2739,14 +2704,15 @@ } }, "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", "dependencies": { - "restore-cursor": "^4.0.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -2772,6 +2738,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "license": "MIT", "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" @@ -2784,9 +2751,10 @@ } }, "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2798,6 +2766,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2806,14 +2775,16 @@ } }, "node_modules/cli-truncate/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" }, "node_modules/cli-truncate/node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -2825,6 +2796,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" @@ -2837,9 +2809,10 @@ } }, "node_modules/cli-truncate/node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -2856,6 +2829,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -2913,7 +2887,8 @@ "node_modules/colorette": { "version": "2.0.20", "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "license": "MIT" }, "node_modules/colors": { "version": "1.4.0", @@ -3000,7 +2975,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "peer": true }, "node_modules/concat-stream": { "version": "1.6.2", @@ -3099,6 +3075,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "peer": true, "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -3111,6 +3088,7 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "peer": true, "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -3126,33 +3104,6 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "peer": true }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", @@ -3169,11 +3120,12 @@ "peer": true }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -3285,24 +3237,11 @@ "node": ">= 0.8" } }, - "node_modules/detect-port": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", - "peer": true, - "dependencies": { - "address": "^1.0.1", - "debug": "4" - }, - "bin": { - "detect": "bin/detect-port.js", - "detect-port": "bin/detect-port.js" - } - }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -3332,9 +3271,10 @@ } }, "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, @@ -3343,9 +3283,10 @@ } }, "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "license": "MIT", "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", @@ -3357,9 +3298,10 @@ } }, "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", + "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "license": "MIT" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -3386,6 +3328,18 @@ "node": ">=6" } }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3550,9 +3504,9 @@ } }, "node_modules/eth-gas-reporter/node_modules/ethers": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.7.2.tgz", - "integrity": "sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==", + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", "funding": [ { "type": "individual", @@ -3563,38 +3517,39 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, - "dependencies": { - "@ethersproject/abi": "5.7.0", - "@ethersproject/abstract-provider": "5.7.0", - "@ethersproject/abstract-signer": "5.7.0", - "@ethersproject/address": "5.7.0", - "@ethersproject/base64": "5.7.0", - "@ethersproject/basex": "5.7.0", - "@ethersproject/bignumber": "5.7.0", - "@ethersproject/bytes": "5.7.0", - "@ethersproject/constants": "5.7.0", - "@ethersproject/contracts": "5.7.0", - "@ethersproject/hash": "5.7.0", - "@ethersproject/hdnode": "5.7.0", - "@ethersproject/json-wallets": "5.7.0", - "@ethersproject/keccak256": "5.7.0", - "@ethersproject/logger": "5.7.0", - "@ethersproject/networks": "5.7.1", - "@ethersproject/pbkdf2": "5.7.0", - "@ethersproject/properties": "5.7.0", - "@ethersproject/providers": "5.7.2", - "@ethersproject/random": "5.7.0", - "@ethersproject/rlp": "5.7.0", - "@ethersproject/sha2": "5.7.0", - "@ethersproject/signing-key": "5.7.0", - "@ethersproject/solidity": "5.7.0", - "@ethersproject/strings": "5.7.0", - "@ethersproject/transactions": "5.7.0", - "@ethersproject/units": "5.7.0", - "@ethersproject/wallet": "5.7.0", - "@ethersproject/web": "5.7.1", - "@ethersproject/wordlists": "5.7.0" + "license": "MIT", + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" } }, "node_modules/ethereum-bloom-filters": { @@ -3610,6 +3565,7 @@ "version": "0.1.3", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "peer": true, "dependencies": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", @@ -3628,42 +3584,6 @@ "setimmediate": "^1.0.5" } }, - "node_modules/ethereumjs-abi": { - "version": "0.6.8", - "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", - "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dependencies": { - "bn.js": "^4.11.8", - "ethereumjs-util": "^6.0.0" - } - }, - "node_modules/ethereumjs-abi/node_modules/@types/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/ethereumjs-abi/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" - }, - "node_modules/ethereumjs-abi/node_modules/ethereumjs-util": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", - "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dependencies": { - "@types/bn.js": "^4.11.3", - "bn.js": "^4.11.0", - "create-hash": "^1.1.2", - "elliptic": "^6.5.2", - "ethereum-cryptography": "^0.1.3", - "ethjs-util": "0.1.6", - "rlp": "^2.2.3" - } - }, "node_modules/ethereumjs-util": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", @@ -3681,9 +3601,9 @@ } }, "node_modules/ethers": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.8.0.tgz", - "integrity": "sha512-zrFbmQRlraM+cU5mE4CZTLBurZTs2gdp2ld0nG/f3ecBK+x6lZ69KSxBqZ4NjclxwfTxl5LeNufcBbMsTdY53Q==", + "version": "6.14.3", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.14.3.tgz", + "integrity": "sha512-qq7ft/oCJohoTcsNPFaXSQUm457MA5iWqkf1Mb11ujONdg7jBI6sAOrHaTi3j0CBqIGFSCeR/RMc+qwRRub7IA==", "funding": [ { "type": "individual", @@ -3694,26 +3614,20 @@ "url": "https://www.buymeacoffee.com/ricmoo" } ], - "peer": true, + "license": "MIT", "dependencies": { - "@adraffy/ens-normalize": "1.10.0", + "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", - "@types/node": "18.15.13", + "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", - "tslib": "2.4.0", - "ws": "8.5.0" + "tslib": "2.7.0", + "ws": "8.17.1" }, "engines": { "node": ">=14.0.0" } }, - "node_modules/ethers/node_modules/@types/node": { - "version": "18.15.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.13.tgz", - "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==", - "peer": true - }, "node_modules/ethjs-unit": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", @@ -3734,55 +3648,22 @@ "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", "peer": true }, - "node_modules/ethjs-util": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dependencies": { - "is-hex-prefixed": "1.0.0", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, "node_modules/eventemitter3": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" }, "node_modules/evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "peer": true, "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" } }, - "node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3830,9 +3711,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3853,14 +3734,18 @@ } }, "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dependencies": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/flat": { @@ -3872,15 +3757,16 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.3", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", - "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3974,9 +3860,10 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", - "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "license": "MIT", "engines": { "node": ">=18" }, @@ -4017,17 +3904,6 @@ "node": ">=4" } }, - "node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ghost-testrpc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", @@ -4045,6 +3921,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "peer": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4199,16 +4076,14 @@ } }, "node_modules/hardhat": { - "version": "2.22.13", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.13.tgz", - "integrity": "sha512-psVJX4FSXDpSXwsU8OcKTJN04pQEj9cFBMX5OPko+OFwbIoiOpvRmafa954/UaA1934npTj8sV3gaTSdx9bPbA==", + "version": "2.24.1", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.24.1.tgz", + "integrity": "sha512-3iwrO2liEGCw1rz/l/mlB1rSNexCc4CFcMj0DlvjXGChzmD3sGUgLwWDOZPf+ya8MEm5ZhO1oprRVmb/wVi0YA==", + "license": "MIT", "dependencies": { + "@ethereumjs/util": "^9.1.0", "@ethersproject/abi": "^5.1.2", - "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.6.3", - "@nomicfoundation/ethereumjs-common": "4.0.4", - "@nomicfoundation/ethereumjs-tx": "5.0.4", - "@nomicfoundation/ethereumjs-util": "9.0.4", + "@nomicfoundation/edr": "^0.11.0", "@nomicfoundation/solidity-analyzer": "^0.1.0", "@sentry/node": "^5.18.1", "@types/bn.js": "^5.1.0", @@ -4217,32 +4092,32 @@ "aggregate-error": "^3.0.0", "ansi-escapes": "^4.3.0", "boxen": "^5.1.2", - "chalk": "^2.4.2", "chokidar": "^4.0.0", "ci-info": "^2.0.0", "debug": "^4.1.1", "enquirer": "^2.3.0", "env-paths": "^2.2.0", "ethereum-cryptography": "^1.0.3", - "ethereumjs-abi": "^0.6.8", - "find-up": "^2.1.0", + "find-up": "^5.0.0", "fp-ts": "1.19.3", "fs-extra": "^7.0.1", - "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", "json-stream-stringify": "^3.1.4", "keccak": "^3.0.2", "lodash": "^4.17.11", + "micro-eth-signer": "^0.14.0", "mnemonist": "^0.38.0", "mocha": "^10.0.0", "p-map": "^4.0.0", + "picocolors": "^1.1.0", "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", "solc": "0.8.26", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", + "tinyglobby": "^0.2.6", "tsort": "0.0.1", "undici": "^5.14.0", "uuid": "^8.3.2", @@ -4265,9 +4140,10 @@ } }, "node_modules/hardhat-gas-reporter": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz", - "integrity": "sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "license": "MIT", "peer": true, "dependencies": { "array-uniq": "1.0.3", @@ -4278,44 +4154,144 @@ "hardhat": "^2.0.2" } }, - "node_modules/hardhat/node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ] + "node_modules/hardhat/node_modules/@ethereumjs/rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", + "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } }, - "node_modules/hardhat/node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "node_modules/hardhat/node_modules/@ethereumjs/util": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-9.1.0.tgz", + "integrity": "sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==", + "license": "MPL-2.0", "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" + "@ethereumjs/rlp": "^5.0.2", + "ethereum-cryptography": "^2.2.1" + }, + "engines": { + "node": ">=18" } }, - "node_modules/hardhat/node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "dependencies": { + "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/hardhat/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@noble/curves/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { "@noble/hashes": "~1.2.0", "@scure/base": "~1.1.0" } @@ -4387,9 +4363,10 @@ } }, "node_modules/hardhat/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -4454,6 +4431,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "peer": true, "dependencies": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -4582,20 +4560,13 @@ "node": ">= 6" } }, - "node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "engines": { - "node": ">=16.17.0" - } - }, "node_modules/husky": { - "version": "9.0.11", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", - "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", + "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", + "license": "MIT", "bin": { - "husky": "bin.mjs" + "husky": "bin.js" }, "engines": { "node": ">=18" @@ -4753,6 +4724,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "peer": true, "engines": { "node": ">=6.5.0", "npm": ">=3" @@ -4774,17 +4746,6 @@ "node": ">=8" } }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -4805,7 +4766,8 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "peer": true }, "node_modules/js-sha3": { "version": "0.8.0", @@ -4821,6 +4783,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4857,6 +4820,19 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "peer": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -4946,11 +4922,14 @@ } }, "node_modules/lilconfig": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz", - "integrity": "sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "engines": { "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" } }, "node_modules/lines-and-columns": { @@ -4959,35 +4938,36 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, "node_modules/lint-staged": { - "version": "15.2.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.2.tgz", - "integrity": "sha512-TiTt93OPh1OZOsb5B7k96A/ATl2AjIZo+vnzFZ6oHK5FuTk63ByDtxGQpHm+kFETjEWqgkF95M8FRXKR/LEBcw==", - "dependencies": { - "chalk": "5.3.0", - "commander": "11.1.0", - "debug": "4.3.4", - "execa": "8.0.1", - "lilconfig": "3.0.0", - "listr2": "8.0.1", - "micromatch": "4.0.5", - "pidtree": "0.6.0", - "string-argv": "0.3.2", - "yaml": "2.3.4" + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.0.tgz", + "integrity": "sha512-HkpQh69XHxgCjObjejBT3s2ILwNjFx8M3nw+tJ/ssBauDlIpkx2RpqWSi1fBgkXLSSXnbR3iEq1NkVtpvV+FLQ==", + "license": "MIT", + "dependencies": { + "chalk": "^5.4.1", + "commander": "^14.0.0", + "debug": "^4.4.1", + "lilconfig": "^3.1.3", + "listr2": "^8.3.3", + "micromatch": "^4.0.8", + "nano-spawn": "^1.0.2", + "pidtree": "^0.6.0", + "string-argv": "^0.3.2", + "yaml": "^2.8.0" }, "bin": { "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=18.12.0" + "node": ">=20.17" }, "funding": { "url": "https://opencollective.com/lint-staged" } }, "node_modules/lint-staged/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -4996,23 +4976,25 @@ } }, "node_modules/lint-staged/node_modules/commander": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", - "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", + "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "license": "MIT", "engines": { - "node": ">=16" + "node": ">=20" } }, "node_modules/listr2": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.0.1.tgz", - "integrity": "sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==", + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.3.3.tgz", + "integrity": "sha512-LWzX2KsqcB1wqQ4AHgYb4RsDXauQiqhjLk+6hjbaeHG4zpjjVAB6wC/gz6X0l+Du1cN3pUB5ZlrvTbhGSNnUQQ==", + "license": "MIT", "dependencies": { "cli-truncate": "^4.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", - "log-update": "^6.0.0", - "rfdc": "^1.3.0", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" }, "engines": { @@ -5020,9 +5002,10 @@ } }, "node_modules/listr2/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5034,6 +5017,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5042,14 +5026,16 @@ } }, "node_modules/listr2/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" }, "node_modules/listr2/node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -5066,6 +5052,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5080,6 +5067,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -5093,15 +5081,17 @@ } }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lodash": { @@ -5212,13 +5202,14 @@ } }, "node_modules/log-update": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", - "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "license": "MIT", "dependencies": { - "ansi-escapes": "^6.2.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^7.0.0", + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" }, @@ -5230,20 +5221,25 @@ } }, "node_modules/log-update/node_modules/ansi-escapes": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", - "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, "engines": { - "node": ">=14.16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/log-update/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5255,6 +5251,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5263,14 +5260,16 @@ } }, "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", - "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==" + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" }, "node_modules/log-update/node_modules/is-fullwidth-code-point": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "license": "MIT", "dependencies": { "get-east-asian-width": "^1.0.0" }, @@ -5285,6 +5284,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" @@ -5297,9 +5297,10 @@ } }, "node_modules/log-update/node_modules/string-width": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", - "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", @@ -5316,6 +5317,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -5330,6 +5332,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", @@ -5383,6 +5386,7 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -5397,11 +5401,6 @@ "node": ">= 0.10.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5411,18 +5410,77 @@ "node": ">= 8" } }, + "node_modules/micro-eth-signer": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", + "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "micro-packed": "~0.7.2" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/curves": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", + "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.7.2" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/hashes": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", + "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/micro-ftch": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", "peer": true }, + "node_modules/micro-packed": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", + "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", + "license": "MIT", + "dependencies": { + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-packed/node_modules/@scure/base": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.5.tgz", + "integrity": "sha512-9rE6EOVeIQzt5TSu4v+K523F8u6DhBsoZWPGKlnCshhlDhy0kJzUX4V+tr2dWmzF1GdekvThABoEQBGBQI7xZw==", + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -5450,12 +5508,13 @@ "node": ">= 0.6" } }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5486,6 +5545,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "peer": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5522,31 +5582,31 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", @@ -5554,24 +5614,13 @@ }, "engines": { "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" - } - }, - "node_modules/mocha/node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "engines": { - "node": ">=6" } }, "node_modules/mocha/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -5587,19 +5636,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/has-flag": { @@ -5610,24 +5664,11 @@ "node": ">=8" } }, - "node_modules/mocha/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -5635,47 +5676,6 @@ "node": ">=10" } }, - "node_modules/mocha/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/mocha/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mocha/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -5691,19 +5691,21 @@ } }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, + "node_modules/nano-spawn": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nano-spawn/-/nano-spawn-1.0.2.tgz", + "integrity": "sha512-21t+ozMQDAL/UGgQVBbZ/xXvNO10++ZPuTmKRO8k9V3AClVRht49ahtDjfY8l1q6nSHOrE5ASfthzH3ol6R/hg==", + "license": "MIT", "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=20.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/nano-spawn?sponsor=1" } }, "node_modules/ndjson": { @@ -5795,31 +5797,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "dependencies": { - "path-key": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", @@ -5872,14 +5849,15 @@ } }, "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", "dependencies": { - "mimic-fn": "^4.0.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5925,25 +5903,31 @@ } }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-map": { @@ -5960,14 +5944,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "engines": { - "node": ">=4" - } - }, "node_modules/package-json": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", @@ -6050,29 +6026,22 @@ } }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "peer": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -6099,6 +6068,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "peer": true, "dependencies": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -6110,6 +6080,11 @@ "node": ">=0.12" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -6159,9 +6134,10 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -6173,44 +6149,32 @@ } }, "node_modules/prettier-plugin-solidity": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.3.1.tgz", - "integrity": "sha512-MN4OP5I2gHAzHZG1wcuJl0FsLS3c4Cc5494bbg+6oQWBPuEamjwDvmGfFMZ6NFzsh3Efd9UUxeT7ImgjNH4ozA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-2.0.0.tgz", + "integrity": "sha512-tis3SwLSrYKDzzRFle48fjPM4GQKBtkVBUajAkt4b75/cc6zojFP7qjz6fDxKfup+34q0jKeSM3QeP9flJFXWw==", + "license": "MIT", "dependencies": { - "@solidity-parser/parser": "^0.17.0", - "semver": "^7.5.4", - "solidity-comments-extractor": "^0.0.8" + "@nomicfoundation/slang": "1.1.0", + "@solidity-parser/parser": "^0.20.1", + "semver": "^7.7.1" }, "engines": { - "node": ">=16" + "node": ">=18" }, "peerDependencies": { - "prettier": ">=2.3.0" + "prettier": ">=3.0.0" } }, "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.17.0.tgz", - "integrity": "sha512-Nko8R0/kUo391jsEHHxrGM07QFdnPGvlmox4rmH0kNiNAashItAilhy4Mv4pK5gQmW5f4sXAF58fwJbmlkGcVw==" - }, - "node_modules/prettier-plugin-solidity/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.1.tgz", + "integrity": "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw==", + "license": "MIT" }, "node_modules/prettier-plugin-solidity/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dependencies": { - "lru-cache": "^6.0.0" - }, + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "bin": { "semver": "bin/semver.js" }, @@ -6218,11 +6182,6 @@ "node": ">=10" } }, - "node_modules/prettier-plugin-solidity/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -6522,47 +6481,21 @@ } }, "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", "dependencies": { - "mimic-fn": "^2.1.0" + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" }, "engines": { - "node": ">=6" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -6574,14 +6507,16 @@ } }, "node_modules/rfdc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.1.tgz", - "integrity": "sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==" + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" }, "node_modules/ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "peer": true, "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -6591,6 +6526,7 @@ "version": "2.2.7", "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "peer": true, "dependencies": { "bn.js": "^5.2.0" }, @@ -6751,22 +6687,32 @@ "node_modules/scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "peer": true }, "node_modules/secp256k1": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz", - "integrity": "sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", "hasInstallScript": true, + "license": "MIT", + "peer": true, "dependencies": { - "elliptic": "^6.5.4", - "node-addon-api": "^2.0.0", + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", "node-gyp-build": "^4.2.0" }, "engines": { - "node": ">=10.0.0" + "node": ">=18.0.0" } }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT", + "peer": true + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -6776,9 +6722,10 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } @@ -6801,7 +6748,8 @@ "node_modules/setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==" + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "peer": true }, "node_modules/setprototypeof": { "version": "1.2.0", @@ -6812,6 +6760,7 @@ "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "peer": true, "dependencies": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -6833,25 +6782,6 @@ "node": "*" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, "node_modules/shelljs": { "version": "0.8.5", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", @@ -6887,6 +6817,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", "engines": { "node": ">=14" }, @@ -6992,11 +6923,12 @@ } }, "node_modules/solhint": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-5.0.3.tgz", - "integrity": "sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-5.1.0.tgz", + "integrity": "sha512-KWg4gnOnznxHXzH0fUvnhnxnk+1R50GiPChcPeQgA7SKQTSF1LLIEh8R1qbkCEn/fFzz4CfJs+Gh7Rl9uhHy+g==", + "license": "MIT", "dependencies": { - "@solidity-parser/parser": "^0.18.0", + "@solidity-parser/parser": "^0.20.0", "ajv": "^6.12.6", "antlr4": "^4.13.1-patch-1", "ast-parents": "^0.0.1", @@ -7023,9 +6955,10 @@ } }, "node_modules/solhint/node_modules/@solidity-parser/parser": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.18.0.tgz", - "integrity": "sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==" + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.1.tgz", + "integrity": "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw==", + "license": "MIT" }, "node_modules/solhint/node_modules/ajv": { "version": "6.12.6", @@ -7201,30 +7134,25 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, - "node_modules/solidity-comments-extractor": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.8.tgz", - "integrity": "sha512-htM7Vn6LhHreR+EglVMd2s+sZhcXAirB1Zlyrv5zBuTxieCvjfnRpd7iZk75m/u6NOlEyQ94C6TWbBn2cY7w8g==" - }, "node_modules/solidity-coverage": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.5.tgz", - "integrity": "sha512-6C6N6OV2O8FQA0FWA95FdzVH+L16HU94iFgg5wAFZ29UpLFkgNI/DRR2HotG1bC0F4gAc/OMs2BJI44Q/DYlKQ==", + "version": "0.8.16", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.16.tgz", + "integrity": "sha512-qKqgm8TPpcnCK0HCDLJrjbOA2tQNEJY4dHX/LSSQ9iwYFS973MwjtgYn2Iv3vfCEQJTj5xtm4cuUMzlJsJSMbg==", + "license": "ISC", "peer": true, "dependencies": { "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.16.0", + "@solidity-parser/parser": "^0.20.1", "chalk": "^2.4.2", "death": "^1.1.0", - "detect-port": "^1.3.0", "difflib": "^0.2.4", "fs-extra": "^8.1.0", "ghost-testrpc": "^0.0.2", "global-modules": "^2.0.0", "globby": "^10.0.1", "jsonschema": "^1.2.4", - "lodash": "^4.17.15", - "mocha": "10.2.0", + "lodash": "^4.17.21", + "mocha": "^10.2.0", "node-emoji": "^1.10.0", "pify": "^4.0.1", "recursive-readdir": "^2.2.2", @@ -7241,13 +7169,11 @@ } }, "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.1.tgz", - "integrity": "sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw==", - "peer": true, - "dependencies": { - "antlr4ts": "^0.5.0-alpha.4" - } + "version": "0.20.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.1.tgz", + "integrity": "sha512-58I2sRpzaQUN+jJmWbHfbWf9AKfzqCI8JAdFB0vbyY+u8tBRcuTt9LxzasvR0LGQpcRv97eyV7l61FQ3Ib7zVw==", + "license": "MIT", + "peer": true }, "node_modules/solidity-coverage/node_modules/fs-extra": { "version": "8.1.0", @@ -7453,21 +7379,11 @@ "node": ">=8" } }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strip-hex-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "peer": true, "dependencies": { "is-hex-prefixed": "1.0.0" }, @@ -7646,6 +7562,45 @@ "readable-stream": "3" } }, + "node_modules/tinyglobby": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", + "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", + "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -7823,26 +7778,15 @@ } }, "node_modules/tslib": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", - "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", - "peer": true + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" }, "node_modules/tsort": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==" }, - "node_modules/tweetnacl": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", - "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" - }, - "node_modules/tweetnacl-util": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", - "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==" - }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -8020,9 +7964,10 @@ } }, "node_modules/undici": { - "version": "5.26.4", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.4.tgz", - "integrity": "sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==", + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "license": "MIT", "dependencies": { "@fastify/busboy": "^2.0.0" }, @@ -8031,9 +7976,9 @@ } }, "node_modules/undici-types": { - "version": "5.25.3", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz", - "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, "node_modules/universalify": { "version": "2.0.1", @@ -8222,9 +8167,10 @@ } }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==" + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -8299,16 +8245,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "peer": true, + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "engines": { "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -8328,11 +8273,15 @@ } }, "node_modules/yaml": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz", - "integrity": "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz", + "integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, "engines": { - "node": ">= 14" + "node": ">= 14.6" } }, "node_modules/yargs": { @@ -8353,9 +8302,10 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "license": "ISC", "engines": { "node": ">=10" } diff --git a/package.json b/package.json index ce1d4fd..e3b3ff1 100644 --- a/package.json +++ b/package.json @@ -17,13 +17,14 @@ "@openzeppelin/contracts": "^5.0.2", "@openzeppelin/contracts-upgradeable": "^5.0.2", "@types/js-yaml": "^4.0.9", - "dotenv": "^16.4.5", - "hardhat": "^2.22.13", - "husky": "^9.0.11", + "dotenv": "^16.5.0", + "ethers": "^6.14.3", + "hardhat": "^2.24.1", + "husky": "^9.1.7", "js-yaml": "^4.1.0", - "lint-staged": "^15.2.2", - "prettier": "^3.2.5", - "prettier-plugin-solidity": "^1.3.1", - "solhint": "^5.0.3" + "lint-staged": "^16.1.0", + "prettier": "^3.5.3", + "prettier-plugin-solidity": "^2.0.0", + "solhint": "^5.1.0" } } diff --git a/requirements.txt b/requirements.txt index a3ce8af..33117c2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ aiohappyeyeballs==2.6.1 -aiohttp==3.11.18 +aiohttp==3.12.4 aiosignal==1.3.2 annotated-types==0.7.0 attrs==25.3.0 -bitarray==3.4.0 +bitarray==3.4.2 cbor2==5.6.5 certifi==2025.4.26 charset-normalizer==3.4.2 @@ -19,15 +19,15 @@ eth-typing==5.2.1 eth-utils==5.3.0 eth_abi==5.2.0 frozenlist==1.6.0 -hexbytes==1.3.0 +hexbytes==1.3.1 idna==3.10 -multidict==6.4.3 +multidict==6.4.4 packaging==25.0 parsimonious==0.10.0 prettytable==3.16.0 propcache==0.3.1 -pycryptodome==3.22.0 -pydantic==2.11.4 +pycryptodome==3.23.0 +pydantic==2.11.5 pydantic_core==2.33.2 pyunormalize==16.0.0 regex==2024.11.6 @@ -36,11 +36,11 @@ rlp==4.1.0 slither-analyzer==0.11.3 solc-select==1.1.0 toolz==1.0.0 -types-requests==2.32.0.20250328 -typing-inspection==0.4.0 +types-requests==2.32.0.20250515 +typing-inspection==0.4.1 typing_extensions==4.13.2 urllib3==2.4.0 wcwidth==0.2.13 -web3==7.11.0 +web3==7.12.0 websockets==15.0.1 yarl==1.20.0 diff --git a/scripts/deploy-protocol.ts b/scripts/deploy-protocol.ts index c1af9ca..0e3d809 100644 --- a/scripts/deploy-protocol.ts +++ b/scripts/deploy-protocol.ts @@ -1,22 +1,21 @@ -import { AddressParam, Signer } from '../types/environment'; +import { AddressLike, Numeric, Signer } from 'ethers'; import { UpgradedEvent, AdminChangedEvent, } from '../typechain-types/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy'; import { OwnershipTransferredEvent } from '../typechain-types/@openzeppelin/contracts/proxy/transparent/ProxyAdmin'; import { DeployedEvent } from '../typechain-types/contracts/utils/Deployer'; -import { deployClassic } from './deploy-classic'; -import { USDC_DECIMALS } from '../constants/usdc'; +import { deploy } from './deploy'; type Params = { name: string; symbol: string; - main: AddressParam; - usdc: AddressParam; - minPriceUsd: number; - minFeeUsd: number; + main: AddressLike; + usdc: AddressLike; + minPrice: Numeric; + minFee: Numeric; regulated: boolean; - minAuctionDurationHours: number; + minAuctionDuration: number; }; // prettier-ignore @@ -26,22 +25,18 @@ export async function deployProtocol(params: Params, deployer?: Signer) { symbol, main, usdc, - minPriceUsd, - minFeeUsd, + minPrice, + minFee, regulated, - minAuctionDurationHours, + minAuctionDuration, } = params; const { ethers } = await import('hardhat'); - const minAuctionDurationSeconds = minAuctionDurationHours * 60 * 60; - const mainPrice = minPriceUsd * 10**USDC_DECIMALS - const minFee = minFeeUsd * 10**USDC_DECIMALS - - const { receipt } = await deployClassic( + const { receipt } = await deploy( { name: 'Deployer', - constructorArgs: [name, symbol, main, usdc, mainPrice, minFee, minAuctionDurationSeconds, regulated], + constructorArgs: [name, symbol, main, usdc, minPrice, minFee, minAuctionDuration, regulated], }, deployer, ); @@ -50,27 +45,27 @@ export async function deployProtocol(params: Params, deployer?: Signer) { const ProxyAdmin = await ethers.getContractFactory('ProxyAdmin'); const Deployer = await ethers.getContractFactory('Deployer'); - const AuctionHouse_Proxy_UpgradedEvent = < + const ArtToken_Proxy_UpgradedEvent = < UpgradedEvent.LogDescription >(Proxy.interface.parseLog(receipt.logs[0])); - const AuctionHouse_ProxyAdmin_OwnershipTransferredEvent = < + const ArtToken_ProxyAdmin_OwnershipTransferredEvent = < OwnershipTransferredEvent.LogDescription >(ProxyAdmin.interface.parseLog(receipt.logs[1])); - const AuctionHouse_Proxy_AdminChangedEvent = < + const ArtToken_Proxy_AdminChangedEvent = < AdminChangedEvent.LogDescription >(Proxy.interface.parseLog(receipt.logs[2])); - const ArtToken_Proxy_UpgradedEvent = < + const AuctionHouse_Proxy_UpgradedEvent = < UpgradedEvent.LogDescription >(Proxy.interface.parseLog(receipt.logs[3])); - const ArtToken_ProxyAdmin_OwnershipTransferredEvent = < + const AuctionHouse_ProxyAdmin_OwnershipTransferredEvent = < OwnershipTransferredEvent.LogDescription >(ProxyAdmin.interface.parseLog(receipt.logs[4])); - const ArtToken_Proxy_AdminChangedEvent = < + const AuctionHouse_Proxy_AdminChangedEvent = < AdminChangedEvent.LogDescription >(Proxy.interface.parseLog(receipt.logs[5])); diff --git a/scripts/deploy-upgrade.ts b/scripts/deploy-upgrade.ts deleted file mode 100644 index edb848c..0000000 --- a/scripts/deploy-upgrade.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { deployClassic } from './deploy-classic'; -import { AddressParam, ContractConstructorArgs, Signer } from '../types/environment'; - -interface Params { - implName: string; - implConstructorArgs: ContractConstructorArgs; - proxyAdminAddr: AddressParam; - proxyAddr: AddressParam; - proxyAdminOwner: Signer; -} - -export async function deployUpgrade(params: Params, deployer?: Signer) { - const { ethers } = await import('hardhat'); - - const implName = params.implName; - const implConstructorArgs = params.implConstructorArgs; - - const { contract: impl, contractAddr: implAddr } = await deployClassic( - { - name: implName, - constructorArgs: implConstructorArgs, - }, - deployer, - ); - - const proxyAdminAddr = params.proxyAdminAddr; - const proxyAdminOwner = params.proxyAdminOwner; - const proxyAdmin = await ethers.getContractAt('ProxyAdmin', proxyAdminAddr, proxyAdminOwner); - - const proxyAddr = params.proxyAddr; - const response = await proxyAdmin.upgradeAndCall(proxyAddr, impl, new Uint8Array(0)); - const receipt = (await response.wait())!; - - return { - receipt, - implAddr, - }; -} diff --git a/scripts/deploy-upgradeable.ts b/scripts/deploy-upgradeable.ts deleted file mode 100644 index aec5cfd..0000000 --- a/scripts/deploy-upgradeable.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { deployClassic } from './deploy-classic'; -import { AddressParam, ContractConstructorArgs, Signer } from '../types/environment'; - -interface Params { - implName: string; - implConstructorArgs: ContractConstructorArgs; - proxyAdminOwnerAddr: AddressParam; - initialize?: boolean; -} - -export async function deployUpgradeable(params: Params, deployer?: Signer) { - const implName = params.implName; - const implConstructorArgs = params.implConstructorArgs; - - const { contract: impl, contractAddr: implAddr } = await deployClassic( - { - name: implName, - constructorArgs: implConstructorArgs, - }, - deployer, - ); - - const proxyName = `TransparentUpgradeableProxy`; - const proxyAdminOwner = params.proxyAdminOwnerAddr; - const initializationData = params.initialize - ? impl.interface.encodeFunctionData('initialize') - : new Uint8Array(0); - const proxyConstructorArgs: ContractConstructorArgs = [ - impl, - proxyAdminOwner, - initializationData, - ]; - - const { - receipt, - contract: proxy, - contractAddr: proxyAddr, - } = await deployClassic( - { - name: proxyName, - constructorArgs: proxyConstructorArgs, - }, - deployer, - ); - - return { - receipt, - proxy, - proxyAddr, - implAddr, - }; -} diff --git a/scripts/deploy-classic.ts b/scripts/deploy.ts similarity index 71% rename from scripts/deploy-classic.ts rename to scripts/deploy.ts index d79f368..9c648f2 100644 --- a/scripts/deploy-classic.ts +++ b/scripts/deploy.ts @@ -1,11 +1,11 @@ -import { ContractConstructorArgs, Signer } from '../types/environment'; +import { Signer } from 'ethers'; interface Params { name: string; - constructorArgs: ContractConstructorArgs; + constructorArgs: any[]; } -export async function deployClassic(params: Params, deployer?: Signer) { +export async function deploy(params: Params, deployer?: Signer) { const { ethers } = await import('hardhat'); const { name, constructorArgs } = params; diff --git a/slither.db.json b/slither.db.json index 2249fe5..b353254 100644 --- a/slither.db.json +++ b/slither.db.json @@ -2,162 +2,262 @@ { "elements": [ { - "type": "variable", - "name": "sharesSum", + "type": "function", + "name": "auctionExists", "source_mapping": { - "start": 2831, - "length": 17, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", + "start": 2688, + "length": 183, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [91], - "starting_column": 9, - "ending_column": 26 + "lines": [70, 71, 72, 73, 74, 75, 76], + "starting_column": 5, + "ending_column": 6 }, "type_specific_fields": { "parent": { - "type": "function", - "name": "requireValidConditions", + "type": "contract", + "name": "AuctionHouse", "source_mapping": { - "start": 2362, - "length": 753, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", + "start": 1203, + "length": 14191, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "Distribution", - "source_mapping": { - "start": 377, - "length": 3068, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", - "is_dependency": false, - "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "requireValidConditions(address[],uint256[])" + "starting_column": 1, + "ending_column": 2 } - } + }, + "signature": "auctionExists(uint256)" } } ], - "description": "Distribution.requireValidConditions(address[],uint256[]).sharesSum (contracts/utils/Distribution.sol#91) is a local variable never initialized\n", - "markdown": "[Distribution.requireValidConditions(address[],uint256[]).sharesSum](contracts/utils/Distribution.sol#L91) is a local variable never initialized\n", - "first_markdown_element": "contracts/utils/Distribution.sol#L91", - "id": "ca8bb528b2cbfaeb97d8e66c089e7c7fcad59efd5cdd2e2dfda76912bd14add9", - "check": "uninitialized-local", - "impact": "Medium", - "confidence": "Medium" + "description": "Modifier AuctionHouse.auctionExists(uint256) (contracts/auction-house/AuctionHouse.sol#70-76) does not always execute _; or revert\n", + "markdown": "Modifier [AuctionHouse.auctionExists(uint256)](contracts/auction-house/AuctionHouse.sol#L70-L76) does not always execute _; or revert\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L70-L76", + "id": "df77d86e81ab2e43df564de9204b5e212fdb053cced7d8363e9cf429b00d05c3", + "check": "incorrect-modifier", + "impact": "Low", + "confidence": "High" }, { "elements": [ { - "type": "variable", - "name": "distributed", + "type": "function", + "name": "auctionEnded", "source_mapping": { - "start": 1624, - "length": 19, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", + "start": 3334, + "length": 180, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [51], - "starting_column": 9, - "ending_column": 28 + "lines": [90, 91, 92, 93, 94, 95, 96], + "starting_column": 5, + "ending_column": 6 }, "type_specific_fields": { "parent": { - "type": "function", - "name": "distribute", + "type": "contract", + "name": "AuctionHouse", "source_mapping": { - "start": 1447, - "length": 639, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", + "start": 1203, + "length": 14191, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "Distribution", - "source_mapping": { - "start": 377, - "length": 3068, - "filename_relative": "contracts/utils/Distribution.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Distribution.sol", - "filename_short": "contracts/utils/Distribution.sol", - "is_dependency": false, - "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "distribute(IERC20,uint256,address[],uint256[])" + "starting_column": 1, + "ending_column": 2 } - } + }, + "signature": "auctionEnded(uint256)" } } ], - "description": "Distribution.distribute(IERC20,uint256,address[],uint256[]).distributed (contracts/utils/Distribution.sol#51) is a local variable never initialized\n", - "markdown": "[Distribution.distribute(IERC20,uint256,address[],uint256[]).distributed](contracts/utils/Distribution.sol#L51) is a local variable never initialized\n", - "first_markdown_element": "contracts/utils/Distribution.sol#L51", - "id": "cca565d30e6948145943276e902e77665412bd118d8e2b9706446743c886cf84", - "check": "uninitialized-local", - "impact": "Medium", - "confidence": "Medium" + "description": "Modifier AuctionHouse.auctionEnded(uint256) (contracts/auction-house/AuctionHouse.sol#90-96) does not always execute _; or revert\n", + "markdown": "Modifier [AuctionHouse.auctionEnded(uint256)](contracts/auction-house/AuctionHouse.sol#L90-L96) does not always execute _; or revert\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L90-L96", + "id": "231e15bbc53bb317ba18ba7a532fc08f0aeab95b6e8a391e84eefe681b37b13e", + "check": "incorrect-modifier", + "impact": "Low", + "confidence": "High" }, { "elements": [ { "type": "function", - "name": "_auctionEnded", + "name": "withBuyer", "source_mapping": { - "start": 10663, - "length": 219, + "start": 3991, + "length": 180, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [337, 338, 339, 340, 341], + "lines": [ + 110, 111, 112, 113, 114, 115, 116 + ], "starting_column": 5, "ending_column": 6 }, @@ -166,163 +266,256 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_auctionEnded(uint256)" + "signature": "withBuyer(uint256)" } - }, + } + ], + "description": "Modifier AuctionHouse.withBuyer(uint256) (contracts/auction-house/AuctionHouse.sol#110-116) does not always execute _; or revert\n", + "markdown": "Modifier [AuctionHouse.withBuyer(uint256)](contracts/auction-house/AuctionHouse.sol#L110-L116) does not always execute _; or revert\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L110-L116", + "id": "128d5b812b57359a56062cf3a9b43628ab98d0de6b09df9fdaa3697aefe12bc7", + "check": "incorrect-modifier", + "impact": "Low", + "confidence": "High" + }, + { + "elements": [ { - "type": "node", - "name": "$.auctions[auctionId].endTime < block.timestamp", + "type": "function", + "name": "authorizedBuyer", "source_mapping": { - "start": 10821, - "length": 54, + "start": 4654, + "length": 206, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [340], - "starting_column": 9, - "ending_column": 63 + "lines": [ + 130, 131, 132, 133, 134, 135, 136 + ], + "starting_column": 5, + "ending_column": 6 }, "type_specific_fields": { "parent": { - "type": "function", - "name": "_auctionEnded", + "type": "contract", + "name": "AuctionHouse", "source_mapping": { - "start": 10663, - "length": 219, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [337, 338, 339, 340, 341], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "AuctionHouse", - "source_mapping": { - "start": 706, - "length": 13608, - "filename_relative": "contracts/auction-house/AuctionHouse.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", - "filename_short": "contracts/auction-house/AuctionHouse.sol", - "is_dependency": false, - "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "_auctionEnded(uint256)" + "lines": [ + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 + ], + "starting_column": 1, + "ending_column": 2 } - } + }, + "signature": "authorizedBuyer(address)" } } ], - "description": "AuctionHouse._auctionEnded(uint256) (contracts/auction-house/AuctionHouse.sol#337-341) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- $.auctions[auctionId].endTime < block.timestamp (contracts/auction-house/AuctionHouse.sol#340)\n", - "markdown": "[AuctionHouse._auctionEnded(uint256)](contracts/auction-house/AuctionHouse.sol#L337-L341) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [$.auctions[auctionId].endTime < block.timestamp](contracts/auction-house/AuctionHouse.sol#L340)\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L337-L341", - "id": "18352b9e5f8181e95de950e2d218cdf65cfebeb3f736cc54c1d42379fedda6c0", - "check": "timestamp", + "description": "Modifier AuctionHouse.authorizedBuyer(address) (contracts/auction-house/AuctionHouse.sol#130-136) does not always execute _; or revert\n", + "markdown": "Modifier [AuctionHouse.authorizedBuyer(address)](contracts/auction-house/AuctionHouse.sol#L130-L136) does not always execute _; or revert\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L130-L136", + "id": "44596abc779becc714ceca96ccacdc0a13e2cb26cde89bd96cbe5d21e7dc5f1b", + "check": "incorrect-modifier", "impact": "Low", - "confidence": "Medium" + "confidence": "High" }, { "elements": [ { "type": "function", - "name": "_requireValidEndTime", + "name": "create", "source_mapping": { - "start": 12489, - "length": 347, + "start": 7202, + "length": 2267, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [402, 403, 404, 405, 406, 407, 408, 409, 410], + "lines": [ + 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, + 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, + 262, 263 + ], "starting_column": 5, "ending_column": 6 }, @@ -331,80 +524,140 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_requireValidEndTime(uint256)" + "signature": "create(IAuctionHouse.CreateParams)" } }, { "type": "node", - "name": "endTime <= block.timestamp + MIN_DURATION", + "name": "params.endTime < block.timestamp + MIN_DURATION", "source_mapping": { - "start": 12563, - "length": 41, + "start": 8300, + "length": 47, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [403], + "lines": [227], "starting_column": 13, - "ending_column": 54 + "ending_column": 60 }, "type_specific_fields": { "parent": { "type": "function", - "name": "_requireValidEndTime", + "name": "create", "source_mapping": { - "start": 12489, - "length": 347, + "start": 7202, + "length": 2267, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [402, 403, 404, 405, 406, 407, 408, 409, 410], + "lines": [ + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, + 262, 263 + ], "starting_column": 5, "ending_column": 6 }, @@ -413,85 +666,163 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, + 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140, + 141, 142, 143, 144, + 145, 146, 147, 148, + 149, 150, 151, 152, + 153, 154, 155, 156, + 157, 158, 159, 160, + 161, 162, 163, 164, + 165, 166, 167, 168, + 169, 170, 171, 172, + 173, 174, 175, 176, + 177, 178, 179, 180, + 181, 182, 183, 184, + 185, 186, 187, 188, + 189, 190, 191, 192, + 193, 194, 195, 196, + 197, 198, 199, 200, + 201, 202, 203, 204, + 205, 206, 207, 208, + 209, 210, 211, 212, + 213, 214, 215, 216, + 217, 218, 219, 220, + 221, 222, 223, 224, + 225, 226, 227, 228, + 229, 230, 231, 232, + 233, 234, 235, 236, + 237, 238, 239, 240, + 241, 242, 243, 244, + 245, 246, 247, 248, + 249, 250, 251, 252, + 253, 254, 255, 256, + 257, 258, 259, 260, + 261, 262, 263, 264, + 265, 266, 267, 268, + 269, 270, 271, 272, + 273, 274, 275, 276, + 277, 278, 279, 280, + 281, 282, 283, 284, + 285, 286, 287, 288, + 289, 290, 291, 292, + 293, 294, 295, 296, + 297, 298, 299, 300, + 301, 302, 303, 304, + 305, 306, 307, 308, + 309, 310, 311, 312, + 313, 314, 315, 316, + 317, 318, 319, 320, + 321, 322, 323, 324, + 325, 326, 327, 328, + 329, 330, 331, 332, + 333, 334, 335, 336, + 337, 338, 339, 340, + 341, 342, 343, 344, + 345, 346, 347, 348, + 349, 350, 351, 352, + 353, 354, 355, 356, + 357, 358, 359, 360, + 361, 362, 363, 364, + 365, 366, 367, 368, + 369, 370, 371, 372, + 373, 374, 375, 376, + 377, 378, 379, 380, + 381, 382, 383, 384, + 385, 386, 387, 388, + 389, 390, 391, 392, + 393, 394, 395, 396, + 397, 398, 399, 400, + 401, 402, 403, 404, + 405, 406, 407, 408, + 409, 410, 411, 412, + 413, 414, 415, 416, + 417, 418, 419, 420, + 421, 422, 423, 424, + 425, 426, 427, 428, + 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_requireValidEndTime(uint256)" + "signature": "create(IAuctionHouse.CreateParams)" } } } }, { "type": "node", - "name": "endTime > block.timestamp + MAX_DURATION", + "name": "params.endTime > block.timestamp + MAX_DURATION", "source_mapping": { - "start": 12704, - "length": 40, + "start": 8423, + "length": 47, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [407], + "lines": [231], "starting_column": 13, - "ending_column": 53 + "ending_column": 60 }, "type_specific_fields": { "parent": { "type": "function", - "name": "_requireValidEndTime", + "name": "create", "source_mapping": { - "start": 12489, - "length": 347, + "start": 7202, + "length": 2267, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [402, 403, 404, 405, 406, 407, 408, 409, 410], + "lines": [ + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, + 262, 263 + ], "starting_column": 5, "ending_column": 6 }, @@ -500,64 +831,126 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, - 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, + 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140, + 141, 142, 143, 144, + 145, 146, 147, 148, + 149, 150, 151, 152, + 153, 154, 155, 156, + 157, 158, 159, 160, + 161, 162, 163, 164, + 165, 166, 167, 168, + 169, 170, 171, 172, + 173, 174, 175, 176, + 177, 178, 179, 180, + 181, 182, 183, 184, + 185, 186, 187, 188, + 189, 190, 191, 192, + 193, 194, 195, 196, + 197, 198, 199, 200, + 201, 202, 203, 204, + 205, 206, 207, 208, + 209, 210, 211, 212, + 213, 214, 215, 216, + 217, 218, 219, 220, + 221, 222, 223, 224, + 225, 226, 227, 228, + 229, 230, 231, 232, + 233, 234, 235, 236, + 237, 238, 239, 240, + 241, 242, 243, 244, + 245, 246, 247, 248, + 249, 250, 251, 252, + 253, 254, 255, 256, + 257, 258, 259, 260, + 261, 262, 263, 264, + 265, 266, 267, 268, + 269, 270, 271, 272, + 273, 274, 275, 276, + 277, 278, 279, 280, + 281, 282, 283, 284, + 285, 286, 287, 288, + 289, 290, 291, 292, + 293, 294, 295, 296, + 297, 298, 299, 300, + 301, 302, 303, 304, + 305, 306, 307, 308, + 309, 310, 311, 312, + 313, 314, 315, 316, + 317, 318, 319, 320, + 321, 322, 323, 324, + 325, 326, 327, 328, + 329, 330, 331, 332, + 333, 334, 335, 336, + 337, 338, 339, 340, + 341, 342, 343, 344, + 345, 346, 347, 348, + 349, 350, 351, 352, + 353, 354, 355, 356, + 357, 358, 359, 360, + 361, 362, 363, 364, + 365, 366, 367, 368, + 369, 370, 371, 372, + 373, 374, 375, 376, + 377, 378, 379, 380, + 381, 382, 383, 384, + 385, 386, 387, 388, + 389, 390, 391, 392, + 393, 394, 395, 396, + 397, 398, 399, 400, + 401, 402, 403, 404, + 405, 406, 407, 408, + 409, 410, 411, 412, + 413, 414, 415, 416, + 417, 418, 419, 420, + 421, 422, 423, 424, + 425, 426, 427, 428, + 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_requireValidEndTime(uint256)" + "signature": "create(IAuctionHouse.CreateParams)" } } } } ], - "description": "AuctionHouse._requireValidEndTime(uint256) (contracts/auction-house/AuctionHouse.sol#402-410) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- endTime <= block.timestamp + MIN_DURATION (contracts/auction-house/AuctionHouse.sol#403)\n\t- endTime > block.timestamp + MAX_DURATION (contracts/auction-house/AuctionHouse.sol#407)\n", - "markdown": "[AuctionHouse._requireValidEndTime(uint256)](contracts/auction-house/AuctionHouse.sol#L402-L410) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [endTime <= block.timestamp + MIN_DURATION](contracts/auction-house/AuctionHouse.sol#L403)\n\t- [endTime > block.timestamp + MAX_DURATION](contracts/auction-house/AuctionHouse.sol#L407)\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L402-L410", - "id": "6f35c4ab7c9dcf17bdda161718b11cfc5b26b159edbf5d922f8b54ee7d88c8c8", + "description": "AuctionHouse.create(IAuctionHouse.CreateParams) (contracts/auction-house/AuctionHouse.sol#192-263) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- params.endTime < block.timestamp + MIN_DURATION (contracts/auction-house/AuctionHouse.sol#227)\n\t- params.endTime > block.timestamp + MAX_DURATION (contracts/auction-house/AuctionHouse.sol#231)\n", + "markdown": "[AuctionHouse.create(IAuctionHouse.CreateParams)](contracts/auction-house/AuctionHouse.sol#L192-L263) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [params.endTime < block.timestamp + MIN_DURATION](contracts/auction-house/AuctionHouse.sol#L227)\n\t- [params.endTime > block.timestamp + MAX_DURATION](contracts/auction-house/AuctionHouse.sol#L231)\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L192-L263", + "id": "0ac89c334de63341c678377f56114fff1f81dadfa04803f7f138da0d4aa1822b", "check": "timestamp", "impact": "Low", "confidence": "Medium" @@ -566,17 +959,290 @@ "elements": [ { "type": "function", - "name": "_requireValidSignature", + "name": "_auctionEnded", "source_mapping": { - "start": 1354, - "length": 609, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 14567, + "length": 219, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", + "is_dependency": false, + "lines": [412, 413, 414, 415, 416], + "starting_column": 5, + "ending_column": 6 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "AuctionHouse", + "source_mapping": { + "start": 1203, + "length": 14191, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", + "is_dependency": false, + "lines": [ + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 + ], + "starting_column": 1, + "ending_column": 2 + } + }, + "signature": "_auctionEnded(uint256)" + } + }, + { + "type": "node", + "name": "$.auction[auctionId].endTime <= block.timestamp", + "source_mapping": { + "start": 14725, + "length": 54, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", + "is_dependency": false, + "lines": [415], + "starting_column": 9, + "ending_column": 63 + }, + "type_specific_fields": { + "parent": { + "type": "function", + "name": "_auctionEnded", + "source_mapping": { + "start": 14567, + "length": 219, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", + "is_dependency": false, + "lines": [ + 412, 413, 414, 415, 416 + ], + "starting_column": 5, + "ending_column": 6 + }, + "type_specific_fields": { + "parent": { + "type": "contract", + "name": "AuctionHouse", + "source_mapping": { + "start": 1203, + "length": 14191, + "filename_relative": "contracts/auction-house/AuctionHouse.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", + "filename_short": "contracts/auction-house/AuctionHouse.sol", + "is_dependency": false, + "lines": [ + 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, + 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140, + 141, 142, 143, 144, + 145, 146, 147, 148, + 149, 150, 151, 152, + 153, 154, 155, 156, + 157, 158, 159, 160, + 161, 162, 163, 164, + 165, 166, 167, 168, + 169, 170, 171, 172, + 173, 174, 175, 176, + 177, 178, 179, 180, + 181, 182, 183, 184, + 185, 186, 187, 188, + 189, 190, 191, 192, + 193, 194, 195, 196, + 197, 198, 199, 200, + 201, 202, 203, 204, + 205, 206, 207, 208, + 209, 210, 211, 212, + 213, 214, 215, 216, + 217, 218, 219, 220, + 221, 222, 223, 224, + 225, 226, 227, 228, + 229, 230, 231, 232, + 233, 234, 235, 236, + 237, 238, 239, 240, + 241, 242, 243, 244, + 245, 246, 247, 248, + 249, 250, 251, 252, + 253, 254, 255, 256, + 257, 258, 259, 260, + 261, 262, 263, 264, + 265, 266, 267, 268, + 269, 270, 271, 272, + 273, 274, 275, 276, + 277, 278, 279, 280, + 281, 282, 283, 284, + 285, 286, 287, 288, + 289, 290, 291, 292, + 293, 294, 295, 296, + 297, 298, 299, 300, + 301, 302, 303, 304, + 305, 306, 307, 308, + 309, 310, 311, 312, + 313, 314, 315, 316, + 317, 318, 319, 320, + 321, 322, 323, 324, + 325, 326, 327, 328, + 329, 330, 331, 332, + 333, 334, 335, 336, + 337, 338, 339, 340, + 341, 342, 343, 344, + 345, 346, 347, 348, + 349, 350, 351, 352, + 353, 354, 355, 356, + 357, 358, 359, 360, + 361, 362, 363, 364, + 365, 366, 367, 368, + 369, 370, 371, 372, + 373, 374, 375, 376, + 377, 378, 379, 380, + 381, 382, 383, 384, + 385, 386, 387, 388, + 389, 390, 391, 392, + 393, 394, 395, 396, + 397, 398, 399, 400, + 401, 402, 403, 404, + 405, 406, 407, 408, + 409, 410, 411, 412, + 413, 414, 415, 416, + 417, 418, 419, 420, + 421, 422, 423, 424, + 425, 426, 427, 428, + 429, 430, 431 + ], + "starting_column": 1, + "ending_column": 2 + } + }, + "signature": "_auctionEnded(uint256)" + } + } + } + } + ], + "description": "AuctionHouse._auctionEnded(uint256) (contracts/auction-house/AuctionHouse.sol#412-416) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- $.auction[auctionId].endTime <= block.timestamp (contracts/auction-house/AuctionHouse.sol#415)\n", + "markdown": "[AuctionHouse._auctionEnded(uint256)](contracts/auction-house/AuctionHouse.sol#L412-L416) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [$.auction[auctionId].endTime <= block.timestamp](contracts/auction-house/AuctionHouse.sol#L415)\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L412-L416", + "id": "9eaae547ddec8db6f10af3058810828a88af986f9782af472a5d58ca21237c57", + "check": "timestamp", + "impact": "Low", + "confidence": "Medium" + }, + { + "elements": [ + { + "type": "function", + "name": "_requireAuthorizedAction", + "source_mapping": { + "start": 1464, + "length": 441, + "filename_relative": "contracts/utils/Authorization.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Authorization.sol", + "filename_short": "contracts/utils/Authorization.sol", "is_dependency": false, "lines": [ - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64 + 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44 ], "starting_column": 5, "ending_column": 6 @@ -584,56 +1250,56 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "EIP712", + "name": "Authorization", "source_mapping": { - "start": 425, - "length": 2072, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 740, + "length": 1393, + "filename_relative": "contracts/utils/Authorization.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Authorization.sol", + "filename_short": "contracts/utils/Authorization.sol", "is_dependency": false, "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87 + 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_requireValidSignature(address,bytes32,uint256,bytes)" + "signature": "_requireAuthorizedAction(bytes32,uint256,bytes)" } }, { "type": "node", "name": "deadline < block.timestamp", "source_mapping": { - "start": 1623, + "start": 1591, "length": 26, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "filename_relative": "contracts/utils/Authorization.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Authorization.sol", + "filename_short": "contracts/utils/Authorization.sol", "is_dependency": false, - "lines": [54], + "lines": [35], "starting_column": 13, "ending_column": 39 }, "type_specific_fields": { "parent": { "type": "function", - "name": "_requireValidSignature", + "name": "_requireAuthorizedAction", "source_mapping": { - "start": 1354, - "length": 609, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 1464, + "length": 441, + "filename_relative": "contracts/utils/Authorization.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Authorization.sol", + "filename_short": "contracts/utils/Authorization.sol", "is_dependency": false, "lines": [ - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64 + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44 ], "starting_column": 5, "ending_column": 6 @@ -641,35 +1307,37 @@ "type_specific_fields": { "parent": { "type": "contract", - "name": "EIP712", + "name": "Authorization", "source_mapping": { - "start": 425, - "length": 2072, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 740, + "length": 1393, + "filename_relative": "contracts/utils/Authorization.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/Authorization.sol", + "filename_short": "contracts/utils/Authorization.sol", "is_dependency": false, "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87 + 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, + 50, 51 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_requireValidSignature(address,bytes32,uint256,bytes)" + "signature": "_requireAuthorizedAction(bytes32,uint256,bytes)" } } } } ], - "description": "EIP712._requireValidSignature(address,bytes32,uint256,bytes) (contracts/utils/EIP712.sol#44-64) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- deadline < block.timestamp (contracts/utils/EIP712.sol#54)\n", - "markdown": "[EIP712._requireValidSignature(address,bytes32,uint256,bytes)](contracts/utils/EIP712.sol#L44-L64) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [deadline < block.timestamp](contracts/utils/EIP712.sol#L54)\n", - "first_markdown_element": "contracts/utils/EIP712.sol#L44-L64", - "id": "e782ec4ebae2fe586d812ede7ced1de770abf2ae05c22c3fdf4dc8c2003dfd81", + "description": "Authorization._requireAuthorizedAction(bytes32,uint256,bytes) (contracts/utils/Authorization.sol#34-44) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- deadline < block.timestamp (contracts/utils/Authorization.sol#35)\n", + "markdown": "[Authorization._requireAuthorizedAction(bytes32,uint256,bytes)](contracts/utils/Authorization.sol#L34-L44) uses timestamp for comparisons\n\tDangerous comparisons:\n\t- [deadline < block.timestamp](contracts/utils/Authorization.sol#L35)\n", + "first_markdown_element": "contracts/utils/Authorization.sol#L34-L44", + "id": "0ab54036e1970b1ccef6d1e540f052283408c22e46489be98f5c540b586b5f7f", "check": "timestamp", "impact": "Low", "confidence": "Medium" @@ -680,13 +1348,15 @@ "type": "function", "name": "layout", "source_mapping": { - "start": 777, + "start": 1089, "length": 197, "filename_relative": "contracts/auction-house/AuctionHouseStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouseStorage.sol", "filename_short": "contracts/auction-house/AuctionHouseStorage.sol", "is_dependency": false, - "lines": [27, 28, 29, 30, 31, 32, 33, 34], + "lines": [ + 32, 33, 34, 35, 36, 37, 38, 39 + ], "starting_column": 5, "ending_column": 6 }, @@ -695,15 +1365,17 @@ "type": "contract", "name": "AuctionHouseStorage", "source_mapping": { - "start": 251, - "length": 725, + "start": 373, + "length": 915, "filename_relative": "contracts/auction-house/AuctionHouseStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouseStorage.sol", "filename_short": "contracts/auction-house/AuctionHouseStorage.sol", "is_dependency": false, "lines": [ - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35 + 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40 ], "starting_column": 1, "ending_column": 2 @@ -716,13 +1388,13 @@ "type": "node", "name": "", "source_mapping": { - "start": 921, + "start": 1233, "length": 47, "filename_relative": "contracts/auction-house/AuctionHouseStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouseStorage.sol", "filename_short": "contracts/auction-house/AuctionHouseStorage.sol", "is_dependency": false, - "lines": [31, 32, 33], + "lines": [36, 37, 38], "starting_column": 9, "ending_column": 10 }, @@ -731,13 +1403,16 @@ "type": "function", "name": "layout", "source_mapping": { - "start": 777, + "start": 1089, "length": 197, "filename_relative": "contracts/auction-house/AuctionHouseStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouseStorage.sol", "filename_short": "contracts/auction-house/AuctionHouseStorage.sol", "is_dependency": false, - "lines": [27, 28, 29, 30, 31, 32, 33, 34], + "lines": [ + 32, 33, 34, 35, 36, 37, 38, + 39 + ], "starting_column": 5, "ending_column": 6 }, @@ -746,15 +1421,19 @@ "type": "contract", "name": "AuctionHouseStorage", "source_mapping": { - "start": 251, - "length": 725, + "start": 373, + "length": 915, "filename_relative": "contracts/auction-house/AuctionHouseStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouseStorage.sol", "filename_short": "contracts/auction-house/AuctionHouseStorage.sol", "is_dependency": false, "lines": [ - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 + 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, + 38, 39, 40 ], "starting_column": 1, "ending_column": 2 @@ -766,10 +1445,10 @@ } } ], - "description": "AuctionHouseStorage.layout() (contracts/auction-house/AuctionHouseStorage.sol#27-34) uses assembly\n\t- INLINE ASM (contracts/auction-house/AuctionHouseStorage.sol#31-33)\n", - "markdown": "[AuctionHouseStorage.layout()](contracts/auction-house/AuctionHouseStorage.sol#L27-L34) uses assembly\n\t- [INLINE ASM](contracts/auction-house/AuctionHouseStorage.sol#L31-L33)\n", - "first_markdown_element": "contracts/auction-house/AuctionHouseStorage.sol#L27-L34", - "id": "7269137036d9609cd8f7f31efb2759060a9541d57d5db49b3553db5dd4485fa3", + "description": "AuctionHouseStorage.layout() (contracts/auction-house/AuctionHouseStorage.sol#32-39) uses assembly\n\t- INLINE ASM (contracts/auction-house/AuctionHouseStorage.sol#36-38)\n", + "markdown": "[AuctionHouseStorage.layout()](contracts/auction-house/AuctionHouseStorage.sol#L32-L39) uses assembly\n\t- [INLINE ASM](contracts/auction-house/AuctionHouseStorage.sol#L36-L38)\n", + "first_markdown_element": "contracts/auction-house/AuctionHouseStorage.sol#L32-L39", + "id": "7c5313869be12a01a9e8b45aeaa345a7ecfb1a70c94b5ba9f2d516064a0d6453", "check": "assembly", "impact": "Informational", "confidence": "High" @@ -780,13 +1459,15 @@ "type": "function", "name": "layout", "source_mapping": { - "start": 683, + "start": 1028, "length": 197, "filename_relative": "contracts/utils/role-system/RoleSystemStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystemStorage.sol", "filename_short": "contracts/utils/role-system/RoleSystemStorage.sol", "is_dependency": false, - "lines": [24, 25, 26, 27, 28, 29, 30, 31], + "lines": [ + 30, 31, 32, 33, 34, 35, 36, 37 + ], "starting_column": 5, "ending_column": 6 }, @@ -795,15 +1476,17 @@ "type": "contract", "name": "RoleSystemStorage", "source_mapping": { - "start": 179, - "length": 703, + "start": 357, + "length": 870, "filename_relative": "contracts/utils/role-system/RoleSystemStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystemStorage.sol", "filename_short": "contracts/utils/role-system/RoleSystemStorage.sol", "is_dependency": false, "lines": [ - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32 + 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38 ], "starting_column": 1, "ending_column": 2 @@ -816,13 +1499,13 @@ "type": "node", "name": "", "source_mapping": { - "start": 827, + "start": 1172, "length": 47, "filename_relative": "contracts/utils/role-system/RoleSystemStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystemStorage.sol", "filename_short": "contracts/utils/role-system/RoleSystemStorage.sol", "is_dependency": false, - "lines": [28, 29, 30], + "lines": [34, 35, 36], "starting_column": 9, "ending_column": 10 }, @@ -831,13 +1514,16 @@ "type": "function", "name": "layout", "source_mapping": { - "start": 683, + "start": 1028, "length": 197, "filename_relative": "contracts/utils/role-system/RoleSystemStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystemStorage.sol", "filename_short": "contracts/utils/role-system/RoleSystemStorage.sol", "is_dependency": false, - "lines": [24, 25, 26, 27, 28, 29, 30, 31], + "lines": [ + 30, 31, 32, 33, 34, 35, 36, + 37 + ], "starting_column": 5, "ending_column": 6 }, @@ -846,15 +1532,19 @@ "type": "contract", "name": "RoleSystemStorage", "source_mapping": { - "start": 179, - "length": 703, + "start": 357, + "length": 870, "filename_relative": "contracts/utils/role-system/RoleSystemStorage.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystemStorage.sol", "filename_short": "contracts/utils/role-system/RoleSystemStorage.sol", "is_dependency": false, "lines": [ - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32 + 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, + 37, 38 ], "starting_column": 1, "ending_column": 2 @@ -866,10 +1556,10 @@ } } ], - "description": "RoleSystemStorage.layout() (contracts/utils/role-system/RoleSystemStorage.sol#24-31) uses assembly\n\t- INLINE ASM (contracts/utils/role-system/RoleSystemStorage.sol#28-30)\n", - "markdown": "[RoleSystemStorage.layout()](contracts/utils/role-system/RoleSystemStorage.sol#L24-L31) uses assembly\n\t- [INLINE ASM](contracts/utils/role-system/RoleSystemStorage.sol#L28-L30)\n", - "first_markdown_element": "contracts/utils/role-system/RoleSystemStorage.sol#L24-L31", - "id": "ad9f7d71641e87eed62c8d6918634b4af93b96f2640685b060848a86617dbf69", + "description": "RoleSystemStorage.layout() (contracts/utils/role-system/RoleSystemStorage.sol#30-37) uses assembly\n\t- INLINE ASM (contracts/utils/role-system/RoleSystemStorage.sol#34-36)\n", + "markdown": "[RoleSystemStorage.layout()](contracts/utils/role-system/RoleSystemStorage.sol#L30-L37) uses assembly\n\t- [INLINE ASM](contracts/utils/role-system/RoleSystemStorage.sol#L34-L36)\n", + "first_markdown_element": "contracts/utils/role-system/RoleSystemStorage.sol#L30-L37", + "id": "425f82cf0c54febf3b13a7efb0d1d6908f0fa90dab5121a1b884dd4ce010f315", "check": "assembly", "impact": "Informational", "confidence": "High" @@ -880,13 +1570,13 @@ "type": "function", "name": "_beforeApprove", "source_mapping": { - "start": 2749, + "start": 4734, "length": 72, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [72], + "lines": [130], "starting_column": 5, "ending_column": 77 }, @@ -895,19 +1585,33 @@ "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106 + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, + 139, 140 ], "starting_column": 1, "ending_column": 2 @@ -917,9 +1621,9 @@ } } ], - "description": "ArtTokenBase._beforeApprove(address,uint256) (contracts/art-token/ArtTokenBase.sol#72) is never used and should be removed\n", - "markdown": "[ArtTokenBase._beforeApprove(address,uint256)](contracts/art-token/ArtTokenBase.sol#L72) is never used and should be removed\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L72", + "description": "ArtTokenBase._beforeApprove(address,uint256) (contracts/art-token/ArtTokenBase.sol#130) is never used and should be removed\n", + "markdown": "[ArtTokenBase._beforeApprove(address,uint256)](contracts/art-token/ArtTokenBase.sol#L130) is never used and should be removed\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L130", "id": "5f92f43cb8301f0cfb6f065cce61d7ef313093cc529cd8c8fe8f4cd4faf86348", "check": "dead-code", "impact": "Informational", @@ -931,13 +1635,13 @@ "type": "function", "name": "_beforeSetApprovalForAll", "source_mapping": { - "start": 2922, + "start": 5101, "length": 86, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [77], + "lines": [139], "starting_column": 5, "ending_column": 91 }, @@ -946,19 +1650,33 @@ "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106 + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, + 139, 140 ], "starting_column": 1, "ending_column": 2 @@ -968,9 +1686,9 @@ } } ], - "description": "ArtTokenBase._beforeSetApprovalForAll(address,bool) (contracts/art-token/ArtTokenBase.sol#77) is never used and should be removed\n", - "markdown": "[ArtTokenBase._beforeSetApprovalForAll(address,bool)](contracts/art-token/ArtTokenBase.sol#L77) is never used and should be removed\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L77", + "description": "ArtTokenBase._beforeSetApprovalForAll(address,bool) (contracts/art-token/ArtTokenBase.sol#139) is never used and should be removed\n", + "markdown": "[ArtTokenBase._beforeSetApprovalForAll(address,bool)](contracts/art-token/ArtTokenBase.sol#L139) is never used and should be removed\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L139", "id": "a420cad121b9863c5420ce936be50fdafcc2fed508ef19dcffff8371fe270809", "check": "dead-code", "impact": "Informational", @@ -982,47 +1700,61 @@ "type": "function", "name": "_beforeTransfer", "source_mapping": { - "start": 2593, - "length": 73, + "start": 4399, + "length": 87, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [67], + "lines": [122], "starting_column": 5, - "ending_column": 78 + "ending_column": 92 }, "type_specific_fields": { "parent": { "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106 + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, + 139, 140 ], "starting_column": 1, "ending_column": 2 } }, - "signature": "_beforeTransfer(address,uint256)" + "signature": "_beforeTransfer(address,uint256,address)" } } ], - "description": "ArtTokenBase._beforeTransfer(address,uint256) (contracts/art-token/ArtTokenBase.sol#67) is never used and should be removed\n", - "markdown": "[ArtTokenBase._beforeTransfer(address,uint256)](contracts/art-token/ArtTokenBase.sol#L67) is never used and should be removed\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L67", - "id": "0f2414e90978dc80c15a29a747466b586ad02112c6ea551926dea32a52dda4de", + "description": "ArtTokenBase._beforeTransfer(address,uint256,address) (contracts/art-token/ArtTokenBase.sol#122) is never used and should be removed\n", + "markdown": "[ArtTokenBase._beforeTransfer(address,uint256,address)](contracts/art-token/ArtTokenBase.sol#L122) is never used and should be removed\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L122", + "id": "ad65513af2c3915ae9fabe63dd9779aed68f1f812699652736ac1b68a790ddd6", "check": "dead-code", "impact": "Informational", "confidence": "Medium" @@ -1033,13 +1765,13 @@ "type": "function", "name": "_increaseBalance", "source_mapping": { - "start": 3616, + "start": 3911, "length": 203, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [100, 101, 102, 103, 104, 105], + "lines": [108, 109, 110, 111, 112, 113], "starting_column": 5, "ending_column": 6 }, @@ -1048,19 +1780,33 @@ "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106 + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, + 139, 140 ], "starting_column": 1, "ending_column": 2 @@ -1070,80 +1816,27 @@ } } ], - "description": "ArtTokenBase._increaseBalance(address,uint128) (contracts/art-token/ArtTokenBase.sol#100-105) is never used and should be removed\n", - "markdown": "[ArtTokenBase._increaseBalance(address,uint128)](contracts/art-token/ArtTokenBase.sol#L100-L105) is never used and should be removed\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L100-L105", + "description": "ArtTokenBase._increaseBalance(address,uint128) (contracts/art-token/ArtTokenBase.sol#108-113) is never used and should be removed\n", + "markdown": "[ArtTokenBase._increaseBalance(address,uint128)](contracts/art-token/ArtTokenBase.sol#L108-L113) is never used and should be removed\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L108-L113", "id": "a548e9dd0856e89fbbade6fefa791dda22cc4edc39e8e8cbd15b1a088281bdf8", "check": "dead-code", "impact": "Informational", "confidence": "Medium" }, - { - "elements": [ - { - "type": "function", - "name": "_requireUniqueRole", - "source_mapping": { - "start": 3401, - "length": 223, - "filename_relative": "contracts/utils/role-system/RoleSystem.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystem.sol", - "filename_short": "contracts/utils/role-system/RoleSystem.sol", - "is_dependency": false, - "lines": [125, 126, 127, 128, 129], - "starting_column": 5, - "ending_column": 6 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "RoleSystem", - "source_mapping": { - "start": 304, - "length": 3322, - "filename_relative": "contracts/utils/role-system/RoleSystem.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystem.sol", - "filename_short": "contracts/utils/role-system/RoleSystem.sol", - "is_dependency": false, - "lines": [ - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130 - ], - "starting_column": 1, - "ending_column": 2 - } - }, - "signature": "_requireUniqueRole(bytes32,address)" - } - } - ], - "description": "RoleSystem._requireUniqueRole(bytes32,address) (contracts/utils/role-system/RoleSystem.sol#125-129) is never used and should be removed\n", - "markdown": "[RoleSystem._requireUniqueRole(bytes32,address)](contracts/utils/role-system/RoleSystem.sol#L125-L129) is never used and should be removed\n", - "first_markdown_element": "contracts/utils/role-system/RoleSystem.sol#L125-L129", - "id": "76977acc3809473162c23b8d070c8359c53ebd48db799cc2923f0989e4124b32", - "check": "dead-code", - "impact": "Informational", - "confidence": "Medium" - }, { "elements": [ { "type": "variable", "name": "_tokenURI", "source_mapping": { - "start": 3139, + "start": 4165, "length": 23, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [91], + "lines": [111], "starting_column": 48, "ending_column": 71 }, @@ -1152,13 +1845,16 @@ "type": "function", "name": "mint", "source_mapping": { - "start": 3096, - "length": 149, + "start": 4122, + "length": 257, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [91, 92, 93], + "lines": [ + 111, 112, 113, 114, 115, + 116, 117 + ], "starting_column": 5, "ending_column": 6 }, @@ -1167,27 +1863,62 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192 + 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140, + 141, 142, 143, 144, + 145, 146, 147, 148, + 149, 150, 151, 152, + 153, 154, 155, 156, + 157, 158, 159, 160, + 161, 162, 163, 164, + 165, 166, 167, 168, + 169, 170, 171, 172, + 173, 174, 175, 176, + 177, 178, 179, 180, + 181, 182, 183, 184, + 185, 186, 187, 188, + 189, 190, 191, 192, + 193, 194, 195, 196, + 197, 198, 199, 200, + 201, 202, 203, 204, + 205, 206, 207, 208, + 209, 210, 211, 212, + 213, 214, 215, 216, + 217, 218, 219, 220, + 221, 222, 223, 224, + 225, 226, 227, 228, + 229, 230, 231, 232, + 233 ], "starting_column": 1, "ending_column": 2 @@ -1197,12 +1928,15 @@ } } }, - "additional_fields": { "target": "parameter", "convention": "mixedCase" } + "additional_fields": { + "target": "parameter", + "convention": "mixedCase" + } } ], - "description": "Parameter ArtToken.mint(address,uint256,string)._tokenURI (contracts/art-token/ArtToken.sol#91) is not in mixedCase\n", - "markdown": "Parameter [ArtToken.mint(address,uint256,string)._tokenURI](contracts/art-token/ArtToken.sol#L91) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L91", + "description": "Parameter ArtToken.mint(address,uint256,string)._tokenURI (contracts/art-token/ArtToken.sol#111) is not in mixedCase\n", + "markdown": "Parameter [ArtToken.mint(address,uint256,string)._tokenURI](contracts/art-token/ArtToken.sol#L111) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L111", "id": "aeda455609c55ef097e887acabb61fff829c786f2f433319100e124e9df6f8e9", "check": "naming-convention", "impact": "Informational", @@ -1214,13 +1948,13 @@ "type": "variable", "name": "AUCTION_HOUSE", "source_mapping": { - "start": 1274, + "start": 1823, "length": 44, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [37], + "lines": [49], "starting_column": 5, "ending_column": 49 }, @@ -1229,37 +1963,66 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192 + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable ArtToken.AUCTION_HOUSE (contracts/art-token/ArtToken.sol#37) is not in mixedCase\n", - "markdown": "Variable [ArtToken.AUCTION_HOUSE](contracts/art-token/ArtToken.sol#L37) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L37", + "description": "Variable ArtToken.AUCTION_HOUSE (contracts/art-token/ArtToken.sol#49) is not in mixedCase\n", + "markdown": "Variable [ArtToken.AUCTION_HOUSE](contracts/art-token/ArtToken.sol#L49) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L49", "id": "801381de76b3547f4627bb52efb1b320f8a4d03e2f2b03504b027686906d7cac", "check": "naming-convention", "impact": "Informational", @@ -1271,13 +2034,13 @@ "type": "variable", "name": "USDC", "source_mapping": { - "start": 1357, + "start": 1933, "length": 28, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [38], + "lines": [52], "starting_column": 5, "ending_column": 33 }, @@ -1286,37 +2049,66 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192 + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable ArtToken.USDC (contracts/art-token/ArtToken.sol#38) is not in mixedCase\n", - "markdown": "Variable [ArtToken.USDC](contracts/art-token/ArtToken.sol#L38) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L38", + "description": "Variable ArtToken.USDC (contracts/art-token/ArtToken.sol#52) is not in mixedCase\n", + "markdown": "Variable [ArtToken.USDC](contracts/art-token/ArtToken.sol#L52) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L52", "id": "533aec464a8673be69fd3428a36229ead71e6241db166f57125b607c1865ee95", "check": "naming-convention", "impact": "Informational", @@ -1328,13 +2120,13 @@ "type": "variable", "name": "MIN_PRICE", "source_mapping": { - "start": 1423, + "start": 2046, "length": 34, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [40], + "lines": [55], "starting_column": 5, "ending_column": 39 }, @@ -1343,37 +2135,66 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192 + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable ArtToken.MIN_PRICE (contracts/art-token/ArtToken.sol#40) is not in mixedCase\n", - "markdown": "Variable [ArtToken.MIN_PRICE](contracts/art-token/ArtToken.sol#L40) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L40", + "description": "Variable ArtToken.MIN_PRICE (contracts/art-token/ArtToken.sol#55) is not in mixedCase\n", + "markdown": "Variable [ArtToken.MIN_PRICE](contracts/art-token/ArtToken.sol#L55) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L55", "id": "d9b31fc446a93138a5cb36fd814b853d3a985ba746b98d7f13c7941d3c0b0cfe", "check": "naming-convention", "impact": "Informational", @@ -1385,13 +2206,13 @@ "type": "variable", "name": "MIN_FEE", "source_mapping": { - "start": 1486, + "start": 2159, "length": 32, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [41], + "lines": [58], "starting_column": 5, "ending_column": 37 }, @@ -1400,37 +2221,66 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192 + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable ArtToken.MIN_FEE (contracts/art-token/ArtToken.sol#41) is not in mixedCase\n", - "markdown": "Variable [ArtToken.MIN_FEE](contracts/art-token/ArtToken.sol#L41) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L41", + "description": "Variable ArtToken.MIN_FEE (contracts/art-token/ArtToken.sol#58) is not in mixedCase\n", + "markdown": "Variable [ArtToken.MIN_FEE](contracts/art-token/ArtToken.sol#L58) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L58", "id": "66c310607e40582d4796f687535a9af2760b01c0c255e2b501000404d3f30f54", "check": "naming-convention", "impact": "Informational", @@ -1442,13 +2292,13 @@ "type": "variable", "name": "REGULATED", "source_mapping": { - "start": 1546, + "start": 2272, "length": 31, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, - "lines": [43], + "lines": [61], "starting_column": 5, "ending_column": 36 }, @@ -1457,37 +2307,66 @@ "type": "contract", "name": "ArtToken", "source_mapping": { - "start": 722, - "length": 5749, + "start": 1074, + "length": 7301, "filename_relative": "contracts/art-token/ArtToken.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtToken.sol", "filename_short": "contracts/art-token/ArtToken.sol", "is_dependency": false, "lines": [ - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192 + 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, + 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, + 162, 163, 164, 165, 166, + 167, 168, 169, 170, 171, + 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, + 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, + 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, + 232, 233 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable ArtToken.REGULATED (contracts/art-token/ArtToken.sol#43) is not in mixedCase\n", - "markdown": "Variable [ArtToken.REGULATED](contracts/art-token/ArtToken.sol#L43) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtToken.sol#L43", + "description": "Variable ArtToken.REGULATED (contracts/art-token/ArtToken.sol#61) is not in mixedCase\n", + "markdown": "Variable [ArtToken.REGULATED](contracts/art-token/ArtToken.sol#L61) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtToken.sol#L61", "id": "d253f0130e6d6565d26ec341882e06fde36a25ec7541085ef0d479fb045b2c01", "check": "naming-convention", "impact": "Informational", @@ -1499,13 +2378,13 @@ "type": "variable", "name": "_name", "source_mapping": { - "start": 1015, + "start": 1152, "length": 19, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [20], + "lines": [28], "starting_column": 25, "ending_column": 44 }, @@ -1514,13 +2393,13 @@ "type": "function", "name": "initialize", "source_mapping": { - "start": 995, + "start": 1132, "length": 131, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [20, 21, 22], + "lines": [28, 29, 30], "starting_column": 5, "ending_column": 6 }, @@ -1529,20 +2408,39 @@ "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106 + 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140 ], "starting_column": 1, "ending_column": 2 @@ -1552,12 +2450,15 @@ } } }, - "additional_fields": { "target": "parameter", "convention": "mixedCase" } + "additional_fields": { + "target": "parameter", + "convention": "mixedCase" + } } ], - "description": "Parameter ArtTokenBase.initialize(string,string)._name (contracts/art-token/ArtTokenBase.sol#20) is not in mixedCase\n", - "markdown": "Parameter [ArtTokenBase.initialize(string,string)._name](contracts/art-token/ArtTokenBase.sol#L20) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L20", + "description": "Parameter ArtTokenBase.initialize(string,string)._name (contracts/art-token/ArtTokenBase.sol#28) is not in mixedCase\n", + "markdown": "Parameter [ArtTokenBase.initialize(string,string)._name](contracts/art-token/ArtTokenBase.sol#L28) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L28", "id": "0d6536aff27f992204afb08494fd56ce453268a0d6d7f76954870ce15454efdd", "check": "naming-convention", "impact": "Informational", @@ -1569,13 +2470,13 @@ "type": "variable", "name": "_symbol", "source_mapping": { - "start": 1036, + "start": 1173, "length": 21, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [20], + "lines": [28], "starting_column": 46, "ending_column": 67 }, @@ -1584,13 +2485,13 @@ "type": "function", "name": "initialize", "source_mapping": { - "start": 995, + "start": 1132, "length": 131, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, - "lines": [20, 21, 22], + "lines": [28, 29, 30], "starting_column": 5, "ending_column": 6 }, @@ -1599,20 +2500,39 @@ "type": "contract", "name": "ArtTokenBase", "source_mapping": { - "start": 809, - "length": 3012, + "start": 853, + "length": 4336, "filename_relative": "contracts/art-token/ArtTokenBase.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/art-token/ArtTokenBase.sol", "filename_short": "contracts/art-token/ArtTokenBase.sol", "is_dependency": false, "lines": [ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106 + 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, + 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, + 101, 102, 103, 104, + 105, 106, 107, 108, + 109, 110, 111, 112, + 113, 114, 115, 116, + 117, 118, 119, 120, + 121, 122, 123, 124, + 125, 126, 127, 128, + 129, 130, 131, 132, + 133, 134, 135, 136, + 137, 138, 139, 140 ], "starting_column": 1, "ending_column": 2 @@ -1622,12 +2542,15 @@ } } }, - "additional_fields": { "target": "parameter", "convention": "mixedCase" } + "additional_fields": { + "target": "parameter", + "convention": "mixedCase" + } } ], - "description": "Parameter ArtTokenBase.initialize(string,string)._symbol (contracts/art-token/ArtTokenBase.sol#20) is not in mixedCase\n", - "markdown": "Parameter [ArtTokenBase.initialize(string,string)._symbol](contracts/art-token/ArtTokenBase.sol#L20) is not in mixedCase\n", - "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L20", + "description": "Parameter ArtTokenBase.initialize(string,string)._symbol (contracts/art-token/ArtTokenBase.sol#28) is not in mixedCase\n", + "markdown": "Parameter [ArtTokenBase.initialize(string,string)._symbol](contracts/art-token/ArtTokenBase.sol#L28) is not in mixedCase\n", + "first_markdown_element": "contracts/art-token/ArtTokenBase.sol#L28", "id": "7bcea9354c9ddc3dbe1466bf8c094194d3838858b9a7057b8a6ff3e4d9e1c359", "check": "naming-convention", "impact": "Informational", @@ -1639,13 +2562,13 @@ "type": "variable", "name": "ART_TOKEN", "source_mapping": { - "start": 1332, + "start": 1961, "length": 36, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [38], + "lines": [51], "starting_column": 5, "ending_column": 41 }, @@ -1654,58 +2577,105 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable AuctionHouse.ART_TOKEN (contracts/auction-house/AuctionHouse.sol#38) is not in mixedCase\n", - "markdown": "Variable [AuctionHouse.ART_TOKEN](contracts/auction-house/AuctionHouse.sol#L38) is not in mixedCase\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L38", + "description": "Variable AuctionHouse.ART_TOKEN (contracts/auction-house/AuctionHouse.sol#51) is not in mixedCase\n", + "markdown": "Variable [AuctionHouse.ART_TOKEN](contracts/auction-house/AuctionHouse.sol#L51) is not in mixedCase\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L51", "id": "f7dd52429a9f100298e6e21b03630cde50306045be3c0e11376ab20f5034c1df", "check": "naming-convention", "impact": "Informational", @@ -1717,13 +2687,13 @@ "type": "variable", "name": "USDC", "source_mapping": { - "start": 1403, + "start": 2074, "length": 28, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [39], + "lines": [54], "starting_column": 5, "ending_column": 33 }, @@ -1732,58 +2702,105 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable AuctionHouse.USDC (contracts/auction-house/AuctionHouse.sol#39) is not in mixedCase\n", - "markdown": "Variable [AuctionHouse.USDC](contracts/auction-house/AuctionHouse.sol#L39) is not in mixedCase\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L39", + "description": "Variable AuctionHouse.USDC (contracts/auction-house/AuctionHouse.sol#54) is not in mixedCase\n", + "markdown": "Variable [AuctionHouse.USDC](contracts/auction-house/AuctionHouse.sol#L54) is not in mixedCase\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L54", "id": "07d5bd6994cd32404289642e73b3c469146a00de74c2bd91fb3dcec2d6102074", "check": "naming-convention", "impact": "Informational", @@ -1795,13 +2812,13 @@ "type": "variable", "name": "MIN_DURATION", "source_mapping": { - "start": 1610, + "start": 2176, "length": 37, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [44], + "lines": [57], "starting_column": 5, "ending_column": 42 }, @@ -1810,58 +2827,105 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable AuctionHouse.MIN_DURATION (contracts/auction-house/AuctionHouse.sol#44) is not in mixedCase\n", - "markdown": "Variable [AuctionHouse.MIN_DURATION](contracts/auction-house/AuctionHouse.sol#L44) is not in mixedCase\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L44", + "description": "Variable AuctionHouse.MIN_DURATION (contracts/auction-house/AuctionHouse.sol#57) is not in mixedCase\n", + "markdown": "Variable [AuctionHouse.MIN_DURATION](contracts/auction-house/AuctionHouse.sol#L57) is not in mixedCase\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L57", "id": "98b4ffaf5185ecfde6761fb768baf7f6cc537e760d8419d5663fed6cfca136ba", "check": "naming-convention", "impact": "Informational", @@ -1873,13 +2937,13 @@ "type": "variable", "name": "MIN_PRICE", "source_mapping": { - "start": 1762, + "start": 2404, "length": 34, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [47], + "lines": [63], "starting_column": 5, "ending_column": 39 }, @@ -1888,58 +2952,105 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable AuctionHouse.MIN_PRICE (contracts/auction-house/AuctionHouse.sol#47) is not in mixedCase\n", - "markdown": "Variable [AuctionHouse.MIN_PRICE](contracts/auction-house/AuctionHouse.sol#L47) is not in mixedCase\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L47", + "description": "Variable AuctionHouse.MIN_PRICE (contracts/auction-house/AuctionHouse.sol#63) is not in mixedCase\n", + "markdown": "Variable [AuctionHouse.MIN_PRICE](contracts/auction-house/AuctionHouse.sol#L63) is not in mixedCase\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L63", "id": "0104d361e1ea8e3bc4ed2d89bddc062717bbd6745526d41219b06ace53334a7f", "check": "naming-convention", "impact": "Informational", @@ -1951,13 +3062,13 @@ "type": "variable", "name": "MIN_FEE", "source_mapping": { - "start": 1833, + "start": 2516, "length": 32, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, - "lines": [48], + "lines": [66], "starting_column": 5, "ending_column": 37 }, @@ -1966,58 +3077,105 @@ "type": "contract", "name": "AuctionHouse", "source_mapping": { - "start": 706, - "length": 13608, + "start": 1203, + "length": 14191, "filename_relative": "contracts/auction-house/AuctionHouse.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/auction-house/AuctionHouse.sol", "filename_short": "contracts/auction-house/AuctionHouse.sol", "is_dependency": false, "lines": [ - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460 + 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, + 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, + 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, + 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, + 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, + 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, + 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, + 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, + 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, + 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, + 428, 429, 430, 431 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable AuctionHouse.MIN_FEE (contracts/auction-house/AuctionHouse.sol#48) is not in mixedCase\n", - "markdown": "Variable [AuctionHouse.MIN_FEE](contracts/auction-house/AuctionHouse.sol#L48) is not in mixedCase\n", - "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L48", + "description": "Variable AuctionHouse.MIN_FEE (contracts/auction-house/AuctionHouse.sol#66) is not in mixedCase\n", + "markdown": "Variable [AuctionHouse.MIN_FEE](contracts/auction-house/AuctionHouse.sol#L66) is not in mixedCase\n", + "first_markdown_element": "contracts/auction-house/AuctionHouse.sol#L66", "id": "b3634a21e75f1f2401b777ffb2232054c168c111d1f6db43ca86c47fef59c89e", "check": "naming-convention", "impact": "Informational", @@ -2027,98 +3185,53 @@ "elements": [ { "type": "variable", - "name": "HASHED_NAME", + "name": "DOMAIN_SEPARATOR", "source_mapping": { - "start": 750, - "length": 37, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", - "is_dependency": false, - "lines": [25], - "starting_column": 5, - "ending_column": 42 - }, - "type_specific_fields": { - "parent": { - "type": "contract", - "name": "EIP712", - "source_mapping": { - "start": 425, - "length": 2072, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", - "is_dependency": false, - "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87 - ], - "starting_column": 1, - "ending_column": 2 - } - } - }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } - } - ], - "description": "Variable EIP712.HASHED_NAME (contracts/utils/EIP712.sol#25) is not in mixedCase\n", - "markdown": "Variable [EIP712.HASHED_NAME](contracts/utils/EIP712.sol#L25) is not in mixedCase\n", - "first_markdown_element": "contracts/utils/EIP712.sol#L25", - "id": "4daa5f05d6ca1bb23f3a4c7846d51f1091496391019eaf56432e58a8ac3b02e7", - "check": "naming-convention", - "impact": "Informational", - "confidence": "High" - }, - { - "elements": [ - { - "type": "variable", - "name": "HASHED_VERSION", - "source_mapping": { - "start": 793, - "length": 40, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 950, + "length": 41, + "filename_relative": "contracts/utils/EIP712Domain.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712Domain.sol", + "filename_short": "contracts/utils/EIP712Domain.sol", "is_dependency": false, - "lines": [26], + "lines": [32], "starting_column": 5, - "ending_column": 45 + "ending_column": 46 }, "type_specific_fields": { "parent": { "type": "contract", - "name": "EIP712", + "name": "EIP712Domain", "source_mapping": { - "start": 425, - "length": 2072, - "filename_relative": "contracts/utils/EIP712.sol", - "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712.sol", - "filename_short": "contracts/utils/EIP712.sol", + "start": 471, + "length": 1603, + "filename_relative": "contracts/utils/EIP712Domain.sol", + "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/EIP712Domain.sol", + "filename_short": "contracts/utils/EIP712Domain.sol", "is_dependency": false, "lines": [ - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87 + 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable EIP712.HASHED_VERSION (contracts/utils/EIP712.sol#26) is not in mixedCase\n", - "markdown": "Variable [EIP712.HASHED_VERSION](contracts/utils/EIP712.sol#L26) is not in mixedCase\n", - "first_markdown_element": "contracts/utils/EIP712.sol#L26", - "id": "445d5b27459795d0cbd6c42441d6c0be0c925f185fb9145bfddc1b28df49fecc", + "description": "Variable EIP712Domain.DOMAIN_SEPARATOR (contracts/utils/EIP712Domain.sol#32) is not in mixedCase\n", + "markdown": "Variable [EIP712Domain.DOMAIN_SEPARATOR](contracts/utils/EIP712Domain.sol#L32) is not in mixedCase\n", + "first_markdown_element": "contracts/utils/EIP712Domain.sol#L32", + "id": "c5e1e07840d8fa8430d68f2ffa4236ae55d6aec820b9c584905faf4b42cda28d", "check": "naming-convention", "impact": "Informational", "confidence": "High" @@ -2129,13 +3242,13 @@ "type": "variable", "name": "MAIN", "source_mapping": { - "start": 466, + "start": 679, "length": 29, "filename_relative": "contracts/utils/role-system/RoleSystem.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystem.sol", "filename_short": "contracts/utils/role-system/RoleSystem.sol", "is_dependency": false, - "lines": [16], + "lines": [20], "starting_column": 5, "ending_column": 34 }, @@ -2144,33 +3257,42 @@ "type": "contract", "name": "RoleSystem", "source_mapping": { - "start": 304, - "length": 3322, + "start": 479, + "length": 2643, "filename_relative": "contracts/utils/role-system/RoleSystem.sol", "filename_absolute": "/Users/v.biliy/Documents/work/do/do-contracts/contracts/utils/role-system/RoleSystem.sol", "filename_short": "contracts/utils/role-system/RoleSystem.sol", "is_dependency": false, "lines": [ - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130 + 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, + 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110 ], "starting_column": 1, "ending_column": 2 } } }, - "additional_fields": { "target": "variable", "convention": "mixedCase" } + "additional_fields": { + "target": "variable", + "convention": "mixedCase" + } } ], - "description": "Variable RoleSystem.MAIN (contracts/utils/role-system/RoleSystem.sol#16) is not in mixedCase\n", - "markdown": "Variable [RoleSystem.MAIN](contracts/utils/role-system/RoleSystem.sol#L16) is not in mixedCase\n", - "first_markdown_element": "contracts/utils/role-system/RoleSystem.sol#L16", + "description": "Variable RoleSystem.MAIN (contracts/utils/role-system/RoleSystem.sol#20) is not in mixedCase\n", + "markdown": "Variable [RoleSystem.MAIN](contracts/utils/role-system/RoleSystem.sol#L20) is not in mixedCase\n", + "first_markdown_element": "contracts/utils/role-system/RoleSystem.sol#L20", "id": "982f659317f43fe0bfb7378ac84558b3324e377aa7bb10bb095243377cb00a53", "check": "naming-convention", "impact": "Informational", diff --git a/tasks/deploy-art-token-impl.ts b/tasks/deploy-art-token-impl.ts index 30267cd..307afa8 100644 --- a/tasks/deploy-art-token-impl.ts +++ b/tasks/deploy-art-token-impl.ts @@ -1,14 +1,13 @@ import { task } from 'hardhat/config'; import { ChainConfig } from '../types/environment'; -import { deployClassic } from '../scripts/deploy-classic'; -import { USDC_DECIMALS } from '../constants/usdc'; +import { deploy } from '../scripts/deploy'; +import { etherToWeiForErc20 } from './utils/ether-to-wei-for-erc20'; /* npx hardhat deploy-art-token-impl --network fork */ task('deploy-art-token-impl').setAction(async (taskArgs: Record, hardhat) => { - const ethers = hardhat.ethers; const chain = hardhat.network; const chainId = chain.config.chainId; const config = (chain.config); @@ -19,30 +18,42 @@ task('deploy-art-token-impl').setAction(async (taskArgs: Record, console.group('Conditions:'); console.log(`Chain - ${chain.name}`); console.log(`Chain ID - ${chainId}`); + console.log(`Collection - ${config.name}`); console.groupEnd(); console.log('-'.repeat(process.stdout.columns)); - const { usdc, main, minPriceUsd, minFeeUsd, regulated, auctionHouse } = config; + const { usdc, main, minPriceUsd, minFeeUsd, regulated, artToken, auctionHouse } = config; - const minPrice = minPriceUsd * 10 ** USDC_DECIMALS; - const minFee = minFeeUsd * 10 ** USDC_DECIMALS; + const minPrice = await etherToWeiForErc20(usdc, minPriceUsd); + const minFee = await etherToWeiForErc20(usdc, minFeeUsd); console.log(`Deploying ArtToken Impl...`); console.log(`\n`); console.group('Params:'); console.log(`main: ${main}`); + console.log(`artToken: ${artToken.proxy}`); console.log(`auctionHouse: ${auctionHouse.proxy}`); console.log(`usdc: ${usdc}`); + console.log(`minPriceUsd: ${minPriceUsd}`); console.log(`minPrice: ${minPrice}`); + console.log(`minFee: ${minFeeUsd}`); console.log(`minFee: ${minFee}`); console.log(`regulated: ${regulated}`); console.groupEnd(); console.log(`\n`); console.log(`Transaction broadcasting...`); - const { receipt, contractAddr: artTokenImplAddr } = await deployClassic({ + const { receipt, contractAddr: artTokenImplAddr } = await deploy({ name: 'ArtToken', - constructorArgs: [main, auctionHouse.proxy, usdc, minPrice, minFee, regulated], + constructorArgs: [ + artToken.proxy, + main, + auctionHouse.proxy, + usdc, + minPrice, + minFee, + regulated, + ], }); console.log(`Transaction broadcasted`); diff --git a/tasks/deploy-auction-house-impl.ts b/tasks/deploy-auction-house-impl.ts index 9d2b083..3f6fa11 100644 --- a/tasks/deploy-auction-house-impl.ts +++ b/tasks/deploy-auction-house-impl.ts @@ -1,14 +1,14 @@ import { task } from 'hardhat/config'; import { ChainConfig } from '../types/environment'; -import { deployClassic } from '../scripts/deploy-classic'; -import { USDC_DECIMALS } from '../constants/usdc'; +import { deploy } from '../scripts/deploy'; +import { etherToWeiForErc20 } from './utils/ether-to-wei-for-erc20'; +import { hoursToSeconds } from './utils/hours-to-seconds'; /* npx hardhat deploy-auction-house-impl --network fork */ task('deploy-auction-house-impl').setAction(async (taskArgs: Record, hardhat) => { - const ethers = hardhat.ethers; const chain = hardhat.network; const chainId = chain.config.chainId; const config = (chain.config); @@ -22,28 +22,41 @@ task('deploy-auction-house-impl').setAction(async (taskArgs: Record, hardhat) => { - const ethers = hardhat.ethers; const chain = hardhat.network; const chainId = chain.config.chainId; const config = (chain.config); @@ -18,12 +19,17 @@ task('deploy-protocol').setAction(async (taskArgs: Record, hardh console.group('Conditions:'); console.log(`Chain - ${chain.name}`); console.log(`Chain ID - ${chainId}`); + console.log(`Collection - ${config.name}`); console.groupEnd(); console.log('-'.repeat(process.stdout.columns)); const { usdc, main, name, symbol, minPriceUsd, minFeeUsd, regulated, minAuctionDurationHours } = config; + const minPrice = await etherToWeiForErc20(usdc, minPriceUsd); + const minFee = await etherToWeiForErc20(usdc, minFeeUsd); + const minAuctionDuration = hoursToSeconds(minAuctionDurationHours); + console.log(`Deploying protocol...`); console.log(`\n`); console.group('Params:'); @@ -32,9 +38,12 @@ task('deploy-protocol').setAction(async (taskArgs: Record, hardh console.log(`usdc: ${usdc}`); console.log(`main: ${main}`); console.log(`minPriceUsd: ${minPriceUsd}`); + console.log(`minPrice: ${minPrice}`); console.log(`minFeeUsd: ${minFeeUsd}`); + console.log(`minFee: ${minFee}`); console.log(`regulated: ${regulated}`); console.log(`minAuctionDurationHours: ${minAuctionDurationHours}`); + console.log(`minAuctionDuration: ${minAuctionDuration}`); console.groupEnd(); console.log(`\n`); console.log(`Transaction broadcasting...`); @@ -56,10 +65,10 @@ task('deploy-protocol').setAction(async (taskArgs: Record, hardh main, name, symbol, - minPriceUsd, - minFeeUsd, + minPrice, + minFee, regulated, - minAuctionDurationHours, + minAuctionDuration, }); console.log(`Transaction broadcasted`); diff --git a/tasks/utils/ether-to-wei-for-erc20.ts b/tasks/utils/ether-to-wei-for-erc20.ts new file mode 100644 index 0000000..e57af75 --- /dev/null +++ b/tasks/utils/ether-to-wei-for-erc20.ts @@ -0,0 +1,13 @@ +import { AddressLike, Numeric, resolveAddress } from 'ethers'; + +export async function etherToWeiForErc20(address: AddressLike, ether: Numeric): Promise { + const { ethers } = await import('hardhat'); + + const resolvedAddress = await resolveAddress(address); + const contract = await ethers.getContractAt('ERC20', resolvedAddress); + const decimals = await contract.decimals(); + + const wei = BigInt(ether) * 10n ** BigInt(decimals); + + return wei; +} diff --git a/tasks/utils/hours-to-seconds.ts b/tasks/utils/hours-to-seconds.ts new file mode 100644 index 0000000..93354f6 --- /dev/null +++ b/tasks/utils/hours-to-seconds.ts @@ -0,0 +1,3 @@ +export function hoursToSeconds(hours: number) { + return hours * 60 * 60; +} diff --git a/tasks/verify-art-token.ts b/tasks/verify-art-token.ts index 239fdf5..7896d61 100644 --- a/tasks/verify-art-token.ts +++ b/tasks/verify-art-token.ts @@ -1,13 +1,12 @@ import { task } from 'hardhat/config'; import { ChainConfig } from '../types/environment'; -import { USDC_DECIMALS } from '../constants/usdc'; +import { etherToWeiForErc20 } from './utils/ether-to-wei-for-erc20'; /* npx hardhat verify-art-token --network fork */ task('verify-art-token').setAction(async (taskArgs: Record, hardhat) => { - const ethers = hardhat.ethers; const chain = hardhat.network; const chainId = chain.config.chainId; const config = (chain.config); @@ -18,6 +17,7 @@ task('verify-art-token').setAction(async (taskArgs: Record, hard console.group('Conditions:'); console.log(`Chain - ${chain.name}`); console.log(`Chain ID - ${chainId}`); + console.log(`Collection - ${config.name}`); console.groupEnd(); console.log('-'.repeat(process.stdout.columns)); @@ -33,8 +33,8 @@ task('verify-art-token').setAction(async (taskArgs: Record, hard const main = config.main; const auctionHouse = config.auctionHouse.proxy; const usdc = config.usdc; - const minPrice = config.minPriceUsd * 10 ** USDC_DECIMALS; - const minFee = config.minFeeUsd * 10 ** USDC_DECIMALS; + const minPrice = await etherToWeiForErc20(usdc, config.minPriceUsd); + const minFee = await etherToWeiForErc20(usdc, config.minFeeUsd); const regulated = config.regulated; console.log(`Verify ArtToken...`); @@ -82,7 +82,7 @@ task('verify-art-token').setAction(async (taskArgs: Record, hard await hardhat.run('verify:verify', { contract: 'contracts/art-token/ArtToken.sol:ArtToken', address: impl, - constructorArguments: [main, auctionHouse, usdc, minPrice, minFee, regulated], + constructorArguments: [proxy, main, auctionHouse, usdc, minPrice, minFee, regulated], }); console.log('-'.repeat(process.stdout.columns)); }); diff --git a/tasks/verify-auction-house.ts b/tasks/verify-auction-house.ts index 2b64929..3141ebe 100644 --- a/tasks/verify-auction-house.ts +++ b/tasks/verify-auction-house.ts @@ -1,14 +1,13 @@ import { task } from 'hardhat/config'; import { ChainConfig } from '../types/environment'; -import { deployClassic } from '../scripts/deploy-classic'; -import { USDC_DECIMALS } from '../constants/usdc'; +import { etherToWeiForErc20 } from './utils/ether-to-wei-for-erc20'; +import { hoursToSeconds } from './utils/hours-to-seconds'; /* npx hardhat verify-auction-house --network fork */ task('verify-auction-house').setAction(async (taskArgs: Record, hardhat) => { - const ethers = hardhat.ethers; const chain = hardhat.network; const chainId = chain.config.chainId; const config = (chain.config); @@ -19,6 +18,7 @@ task('verify-auction-house').setAction(async (taskArgs: Record, console.group('Conditions:'); console.log(`Chain - ${chain.name}`); console.log(`Chain ID - ${chainId}`); + console.log(`Collection - ${config.name}`); console.groupEnd(); console.log('-'.repeat(process.stdout.columns)); @@ -34,9 +34,9 @@ task('verify-auction-house').setAction(async (taskArgs: Record, const main = config.main; const artToken = config.artToken.proxy; const usdc = config.usdc; - const minAuctionDuration = config.minAuctionDurationHours * 60 * 60; - const minPrice = config.minPriceUsd * 10 ** USDC_DECIMALS; - const minFee = config.minFeeUsd * 10 ** USDC_DECIMALS; + const minPrice = await etherToWeiForErc20(usdc, config.minPriceUsd); + const minFee = await etherToWeiForErc20(usdc, config.minFeeUsd); + const minAuctionDuration = hoursToSeconds(config.minAuctionDurationHours); console.log(`Verify AuctionHouse...`); console.log(`\n`); @@ -83,7 +83,7 @@ task('verify-auction-house').setAction(async (taskArgs: Record, await hardhat.run('verify:verify', { contract: 'contracts/auction-house/AuctionHouse.sol:AuctionHouse', address: impl, - constructorArguments: [main, artToken, usdc, minAuctionDuration, minPrice, minFee], + constructorArguments: [proxy, main, artToken, usdc, minAuctionDuration, minPrice, minFee], }); console.log('-'.repeat(process.stdout.columns)); }); diff --git a/tests/ArtToken.ts b/tests/ArtToken.ts index ccb23fa..ae35916 100644 --- a/tests/ArtToken.ts +++ b/tests/ArtToken.ts @@ -1,388 +1,340 @@ import { expect } from 'chai'; -import { ethers } from 'hardhat'; -import { getSigners } from './utils/get-signers'; -import { ArtToken, AuctionHouse, USDC } from '../typechain-types'; -import { Signer } from '../types/environment'; -import { signBuyPermit } from './utils/sign-art-token-buy-permit'; -import { getChainId } from './utils/get-chain-id'; +import { Signer, MaxInt256, ZeroAddress } from 'ethers'; +import { ArtToken, AuctionHouse, USDC, MarketMock } from '../typechain-types'; import { BuyPermitStruct } from '../types/art-token'; -import { TOTAL_SHARE } from '../constants/distribution'; -import { getValidDeadline } from './utils/get-valid-deadline'; -import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; -import { deployProtocol } from '../scripts/deploy-protocol'; -import { deployUsdc } from './utils/deploy-usdc'; -import { signCreatePermit } from './utils/sign-auction-house-create-permit'; import { CreatePermitStruct } from '../types/auction-house'; +import { MIN_FEE, MIN_PRICE } from './constants/min-price-and-fee'; +import { TOTAL_SHARE } from './constants/distribution'; +import { TOKEN_ID, TOKEN_URI } from './constants/art-token'; +import { HOUR } from './constants/time'; +import { AUCTION_ID, AUCTION_STEP } from './constants/auction-house'; +import { getSigners } from './utils/get-signers'; +import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; +import { deployProtocolTest } from './utils/deploy-protocol-test'; +import { ArtTokenUtils } from './utils/art-token-utils'; +import { AuctionHouseUtils } from './utils/auction-house-utils'; describe('ArtToken', function () { let artToken: ArtToken, artTokenAddr: string; let auctionHouse: AuctionHouse, auctionHouseAddr: string; + let market: MarketMock, marketAddr: string; let usdc: USDC, usdcAddr: string; - let chainId: number; - - let main: Signer, mainAddr: string; - let admin: Signer, adminAddr: string; + let artTokenSigner: Signer, artTokenSignerAddr: string; let financier: Signer, financierAddr: string; let institution: Signer, institutionAddr: string; let buyer: Signer, buyerAddr: string; let randomAccount: Signer, randomAccountAddr: string; - const adminRole = ethers.keccak256(Buffer.from('ADMIN_ROLE')); - const financialRole = ethers.keccak256(Buffer.from('FINANCIAL_ROLE')); - const partnerRole = ethers.keccak256(Buffer.from('PARTNER_ROLE')); - before(async () => { - chainId = await getChainId(); - - [usdc, usdcAddr] = await deployUsdc(); - [ - [main, admin, financier, institution, buyer, randomAccount], - [mainAddr, adminAddr, financierAddr, institutionAddr, buyerAddr, randomAccountAddr], + [artTokenSigner, financier, institution, buyer, randomAccount], + [artTokenSignerAddr, financierAddr, institutionAddr, buyerAddr, randomAccountAddr], ] = await getSigners(); }); beforeEach(async () => { - const { - artToken: _artToken, - artTokenAddr: _artTokenAddr, - auctionHouse: _auctionHouse, - auctionHouseAddr: _auctionHouseAddr, - } = await deployProtocol({ - name: 'TestToken', - symbol: 'TT', - main, - usdc, - minPriceUsd: 10, - minFeeUsd: 10, - minAuctionDurationHours: 1, - regulated: true, - }); + const protocol = await deployProtocolTest({ signer: artTokenSigner, financier }); + + artToken = protocol.artToken; + artTokenAddr = protocol.artTokenAddr; + auctionHouse = protocol.auctionHouse; + auctionHouseAddr = protocol.auctionHouseAddr; + market = protocol.marketMock; + marketAddr = protocol.marketMockAddr; + usdc = protocol.usdc; + usdcAddr = protocol.usdcAddr; + }); - await _artToken.connect(main).transferUniqueRole(adminRole, admin); - await _artToken.connect(main).transferUniqueRole(financialRole, financier); - await _auctionHouse.connect(main).transferUniqueRole(adminRole, admin); - await _auctionHouse.connect(main).transferUniqueRole(financialRole, financier); + describe(`method 'buy'`, () => { + beforeEach(async () => { + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); + }); - await usdc.connect(buyer).mint(); - await usdc.connect(buyer).approve(_artToken, ethers.MaxInt256); + it(`should mint the token, distribute reward, and charge fee`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - artToken = _artToken.connect(buyer); - artTokenAddr = _artTokenAddr; - auctionHouse = _auctionHouse; - auctionHouseAddr = _auctionHouseAddr; - }); + const institutionShare = (TOTAL_SHARE / 5n) * 4n; // 80% + const platformShare = TOTAL_SHARE / 5n; // 20% - let tokenId: bigint; - let tokenURI: string; - let price: bigint; - let fee: bigint; - let participants: string[]; - let shares: bigint[]; - let deadline: number; + const price = MIN_PRICE; + const fee = MIN_FEE; - beforeEach(async () => { - tokenId = 0n; - tokenURI = 'ipfs://Q...'; - price = 100_000_000n; - fee = 100_000_000n; - participants = [financierAddr, institutionAddr]; - shares = [TOTAL_SHARE / 5n, (TOTAL_SHARE / 5n) * 4n]; - deadline = await getValidDeadline(); - }); + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; - describe(`method 'buy'`, () => { - it(`should mint token`, async () => { - await buy(); - - await Promise.all([ - expect(artToken.ownerOf(tokenId)).to.eventually.equal(buyerAddr), - expect(artToken.tokenURI(tokenId)).to.eventually.equal(tokenURI), - expect(artToken.balanceOf(buyer)).to.eventually.equal(1n), - ]); - }); + const tx = await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); - it(`should transfer fee to financier`, async () => { - const transaction = await buy(); + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(buyerAddr, artTokenAddr, price + fee); - await expect(transaction) + await expect(tx) .to.be.emit(usdc, 'Transfer') - .withArgs(artTokenAddr, financierAddr, fee); - }); + .withArgs(artTokenAddr, institutionAddr, (price * institutionShare) / TOTAL_SHARE); - it(`should transfer price and fee from buyer to contract`, async () => { - const transaction = await buy(); + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(artTokenAddr, financierAddr, (price * platformShare) / TOTAL_SHARE); - await expect(transaction) + await expect(tx) .to.be.emit(usdc, 'Transfer') - .withArgs(buyerAddr, artTokenAddr, price + fee); + .withArgs(artTokenAddr, financierAddr, fee); + + await expect(tx) + .to.be.emit(artToken, 'Transfer') // + .withArgs(ZeroAddress, buyerAddr, TOKEN_ID); }); - it(`should fail if token is reserved by auction`, async () => { + it(`should fail if the token is reserved by the auction`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + const createPermit: CreatePermitStruct = { - auctionId: 1n, - tokenId, - tokenURI, - price: 100_000_001n, - fee: 100_000_001n, - step: 1_000_001n, - endTime: deadline, - participants, - shares, - deadline, + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, }; - const signature = await signCreatePermit( - chainId, - auctionHouseAddr, - createPermit, - admin, - ); - - await auctionHouse.create({ - auctionId: createPermit.auctionId, - tokenId, - tokenURI, - price: createPermit.price, - fee: createPermit.fee, - step: createPermit.step, - endTime: createPermit.endTime, - participants, - shares, - signature, - deadline, + await AuctionHouseUtils.create({ + auctionHouse, + permit: createPermit, + permitSigner: artTokenSigner, + sender: institution, }); - await expect(buy()).to.be.rejectedWith('ArtTokenReserved'); - }); - - describe(`permit logic`, () => { - it(`should fail if permit signer is not admin`, async () => { - const _admin = randomAccount; + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, + }; - await expect(buy({ _admin })).to.be.rejectedWith('EIP712InvalidSignature'); + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, }); - it(`should fail if permit is expired`, async () => { - const _deadline = await getLatestBlockTimestamp(); - - await expect(buy({ _deadline })).to.be.rejectedWith('EIP712ExpiredSignature'); - }); + await expect(tx).to.be.rejectedWith('ArtTokenTokenReserved'); + }); - it(`should fail if the sender is invalid`, async () => { - const _artToken = artToken.connect(randomAccount); + it(`should fail if the permit signer is not the art token signer`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - await expect(buy({ _artToken })).to.be.rejectedWith('EIP712InvalidSignature'); - }); - }); + const institutionShare = (TOTAL_SHARE / 5n) * 4n; // 80% + const platformShare = TOTAL_SHARE / 5n; // 20% - describe(`distribution logic`, () => { - it(`should distribute reward between participants according to shares`, async () => { - const transaction = await buy(); - - await Promise.all([ - expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs(artTokenAddr, participants[0], (price * shares[0]) / TOTAL_SHARE), - expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs(artTokenAddr, participants[1], (price * shares[1]) / TOTAL_SHARE), - ]); - }); + const price = MIN_PRICE; + const fee = MIN_FEE; - it(`should fail if number of shares is not equal number of participants`, async () => { - const _participants = [financierAddr]; - const _shares = [TOTAL_SHARE / 2n, TOTAL_SHARE / 2n]; + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; - await expect(buy({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesCount', - ); + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: randomAccount, + sender: buyer, }); - it(`should fail if total shares is not equal TOTAL_SHARE`, async () => { - const _participants = [financierAddr, institutionAddr]; - const _shares = [TOTAL_SHARE, 1n]; + await expect(tx).to.be.rejectedWith('AuthorizationUnauthorizedAction'); + }); + }); - await expect(buy({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesSum', - ); - }); + describe(`method 'transferFrom'`, () => { + beforeEach(async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should fail if shares and participants are empty`, async () => { - const _participants: string[] = []; - const _shares: bigint[] = []; + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); - await expect(buy({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesSum', - ); + await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, }); }); - }); - describe(`method 'transferFrom'`, () => { it(`should transfer to a non-contract account`, async () => { - await buy(); + const tx = await artToken.connect(buyer).transferFrom(buyer, randomAccount, TOKEN_ID); - const transaction = await artToken.transferFrom(buyer, randomAccount, tokenId); - - await expect(transaction) + await expect(tx) .to.be.emit(artToken, 'Transfer') - .withArgs(buyerAddr, randomAccountAddr, tokenId); + .withArgs(buyerAddr, randomAccountAddr, TOKEN_ID); }); it(`should transfer to a partner contract`, async () => { - await buy(); - - await artToken.connect(main).grandRole(partnerRole, auctionHouse); - - const transaction = await artToken.transferFrom(buyer, auctionHouse, tokenId); + const tx = await artToken.connect(buyer).transferFrom(buyer, market, TOKEN_ID); - await expect(transaction) + await expect(tx) .to.be.emit(artToken, 'Transfer') - .withArgs(buyerAddr, auctionHouseAddr, tokenId); + .withArgs(buyerAddr, marketAddr, TOKEN_ID); }); - it(`should fail if a token is tried to transfer to a non-partner contract`, async () => { - await buy(); + it(`should fail if a token is attempted to be transferred to a non-partner contract`, async () => { + const tx = artToken.connect(buyer).transferFrom(buyer, usdc, TOKEN_ID); - await expect( - artToken.transferFrom(buyer, auctionHouse, tokenId), - ).to.eventually.rejectedWith('RoleSystemUnauthorizedAccount'); + await expect(tx).to.eventually.rejectedWith('ArtTokenUnauthorizedAccount'); }); }); - describe(`method 'safeTransferFrom'`, () => { - it(`should transfer to a non-contract account`, async () => { - await buy(); - - const transaction = await artToken['safeTransferFrom(address,address,uint256)']( - buyer, - randomAccount, - tokenId, - ); - - await expect(transaction) - .to.be.emit(artToken, 'Transfer') - .withArgs(buyerAddr, randomAccountAddr, tokenId); - }); + describe(`method 'approve'`, () => { + beforeEach(async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should fail if a token is tried to transfer to a non-partner contract`, async () => { - await buy(); + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); - await expect( - artToken['safeTransferFrom(address,address,uint256)'](buyer, auctionHouse, tokenId), - ).to.eventually.rejectedWith('RoleSystemUnauthorizedAccount'); + await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); }); - }); - describe(`method 'approve'`, () => { it(`should provide the approval to a non-contract account`, async () => { - await buy(); + const tx = await artToken.connect(buyer).approve(randomAccountAddr, TOKEN_ID); - const transaction = await artToken.approve(randomAccountAddr, tokenId); - - await expect(transaction) + await expect(tx) .to.be.emit(artToken, 'Approval') - .withArgs(buyerAddr, randomAccountAddr, tokenId); + .withArgs(buyerAddr, randomAccountAddr, TOKEN_ID); }); it(`should provide the approval to a partner contract`, async () => { - await buy(); - - await artToken.connect(main).grandRole(partnerRole, auctionHouse); + const tx = await artToken.connect(buyer).approve(market, TOKEN_ID); - const transaction = await artToken.approve(auctionHouse, tokenId); - - await expect(transaction) + await expect(tx) .to.be.emit(artToken, 'Approval') - .withArgs(buyerAddr, auctionHouseAddr, tokenId); + .withArgs(buyerAddr, marketAddr, TOKEN_ID); }); - it(`should fail if the approval is tried to provide to a non-partner contract`, async () => { - await buy(); + it(`should fail if the approval is attempted to be provided to a non-partner contract`, async () => { + const tx = artToken.connect(buyer).approve(usdc, TOKEN_ID); - await expect(artToken.approve(auctionHouse, tokenId)).to.eventually.rejectedWith( - 'RoleSystemUnauthorizedAccount', - ); + await expect(tx).to.eventually.rejectedWith('ArtTokenUnauthorizedAccount'); }); }); describe(`method 'setApprovalForAll'`, () => { - it(`should fail`, async () => { - await buy(); + beforeEach(async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, + }; + + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); + + await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + }); + + it(`should provide the approval to a non-contract account`, async () => { + const tx = await artToken.connect(buyer).setApprovalForAll(randomAccountAddr, true); - await expect(artToken.setApprovalForAll(auctionHouse, true)).to.eventually.rejectedWith( - 'ArtTokenForbiddenAction', - ); + await expect(tx) + .to.be.emit(artToken, 'ApprovalForAll') + .withArgs(buyerAddr, randomAccountAddr, true); + }); + + it(`should provide the approval to a partner contract`, async () => { + const tx = await artToken.connect(buyer).setApprovalForAll(market, true); + + await expect(tx) + .to.be.emit(artToken, 'ApprovalForAll') + .withArgs(buyerAddr, marketAddr, true); + }); + + it(`should fail if the approval is attempted to be provided to a non-partner contract`, async () => { + const tx = artToken.connect(buyer).setApprovalForAll(usdc, true); + + await expect(tx).to.eventually.rejectedWith('ArtTokenUnauthorizedAccount'); }); }); describe(`method 'recipientAuthorized'`, () => { it(`should return 'true' for a non-contract account`, async () => { - await expect(artToken.recipientAuthorized(randomAccount)).to.eventually.equal(true); + const authorized = await artToken.recipientAuthorized(randomAccount); + + expect(authorized).equal(true); }); it(`should return 'true' for a partner contract`, async () => { - await artToken.connect(main).grandRole(partnerRole, auctionHouse); + const authorized = await artToken.recipientAuthorized(market); - await expect(artToken.recipientAuthorized(auctionHouse)).to.eventually.equal(true); + expect(authorized).equal(true); }); it(`should return 'false' for a non-partner contract`, async () => { - await expect(artToken.recipientAuthorized(auctionHouse)).to.eventually.equal(false); - }); - }); + const authorized = await artToken.recipientAuthorized(usdc); - async function buy( - params: { - _tokenId?: bigint; - _tokenURI?: string; - _sender?: string; - _price?: bigint; - _fee?: bigint; - _participants?: string[]; - _shares?: bigint[]; - _deadline?: number; - _admin?: Signer; - _artToken?: ArtToken; - } = {}, - ) { - const { - _tokenId = tokenId, - _tokenURI = tokenURI, - _sender = buyerAddr, - _price = price, - _fee = fee, - _participants = participants, - _shares = shares, - _deadline = deadline, - _admin = admin, - _artToken = artToken, - } = params; - - const permit: BuyPermitStruct = { - tokenId: _tokenId, - tokenURI: _tokenURI, - sender: _sender, - price: _price, - fee: _fee, - participants: _participants, - shares: _shares, - deadline: _deadline, - }; - - const signature = await signBuyPermit(chainId, artTokenAddr, permit, _admin); - - return _artToken.buy({ - tokenId: _tokenId, - tokenURI: _tokenURI, - price: _price, - fee: _fee, - participants: _participants, - shares: _shares, - signature, - deadline: _deadline, + expect(authorized).equal(false); }); - } + }); }); diff --git a/tests/AuctionHouse.ts b/tests/AuctionHouse.ts index ff44e8b..bb5998f 100644 --- a/tests/AuctionHouse.ts +++ b/tests/AuctionHouse.ts @@ -1,118 +1,93 @@ import { expect } from 'chai'; -import { ethers } from 'ethers'; -import { ArtToken, AuctionHouse, USDC } from '../typechain-types'; -import { setNextBlockTimestamp } from '@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time'; +import { Signer, MaxInt256, ZeroAddress } from 'ethers'; import { mine } from '@nomicfoundation/hardhat-network-helpers/dist/src/helpers/mine'; -import { Signer } from '../types/environment'; -import { getChainId } from './utils/get-chain-id'; -import { getSigners } from './utils/get-signers'; -import { TOTAL_SHARE } from '../constants/distribution'; -import { getValidDeadline } from './utils/get-valid-deadline'; -import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; -import { deployProtocol } from '../scripts/deploy-protocol'; -import { deployUsdc } from './utils/deploy-usdc'; +import { setNextBlockTimestamp } from '@nomicfoundation/hardhat-network-helpers/dist/src/helpers/time'; +import { ArtToken, AuctionHouse, USDC } from '../typechain-types'; import { CreatePermitStruct } from '../types/auction-house'; -import { signCreatePermit } from './utils/sign-auction-house-create-permit'; import { BuyPermitStruct } from '../types/art-token'; -import { signBuyPermit } from './utils/sign-art-token-buy-permit'; +import { MIN_FEE, MIN_PRICE } from './constants/min-price-and-fee'; +import { TOTAL_SHARE } from './constants/distribution'; +import { AUCTION_ID, AUCTION_STEP, SECOND_AUCTION_ID } from './constants/auction-house'; +import { TOKEN_ID, TOKEN_URI } from './constants/art-token'; +import { HOUR } from './constants/time'; +import { getSigners } from './utils/get-signers'; +import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; +import { deployProtocolTest } from './utils/deploy-protocol-test'; +import { ArtTokenUtils } from './utils/art-token-utils'; +import { AuctionHouseUtils } from './utils/auction-house-utils'; describe('AuctionHouse', function () { let auctionHouse: AuctionHouse, auctionHouseAddr: string; let artToken: ArtToken, artTokenAddr: string; let usdc: USDC, usdcAddr: string; - let chainId: number; - - let main: Signer, mainAddr: string; - let admin: Signer, adminAddr: string; + let auctionHouseSigner: Signer, auctionHouseSignerAddr: string; let financier: Signer, financierAddr: string; let institution: Signer, institutionAddr: string; let buyer: Signer, buyerAddr: string; let randomAccount: Signer, randomAccountAddr: string; - const adminRole = ethers.keccak256(Buffer.from('ADMIN_ROLE')); - const financialRole = ethers.keccak256(Buffer.from('FINANCIAL_ROLE')); - before(async () => { - chainId = await getChainId(); - - [usdc, usdcAddr] = await deployUsdc(); - [ - [main, admin, financier, institution, buyer, randomAccount], - [mainAddr, adminAddr, financierAddr, institutionAddr, buyerAddr, randomAccountAddr], + [auctionHouseSigner, financier, institution, buyer, randomAccount], + [auctionHouseSignerAddr, financierAddr, institutionAddr, buyerAddr, randomAccountAddr], ] = await getSigners(); }); beforeEach(async () => { - const { - auctionHouse: _auctionHouse, - auctionHouseAddr: _auctionHouseAddr, - artToken: _artToken, - artTokenAddr: _artTokenAddr, - } = await deployProtocol({ - name: 'TestToken', - symbol: 'TT', - main, - usdc, - minPriceUsd: 10, - minFeeUsd: 10, - minAuctionDurationHours: 1, - regulated: true, - }); - - await _artToken.connect(main).transferUniqueRole(adminRole, admin); - await _artToken.connect(main).transferUniqueRole(financialRole, financier); - await _auctionHouse.connect(main).transferUniqueRole(adminRole, admin); - await _auctionHouse.connect(main).transferUniqueRole(financialRole, financier); - - await Promise.all([usdc.connect(buyer).mint(), usdc.connect(randomAccount).mint()]); - - await Promise.all([ - usdc.connect(buyer).approve(_auctionHouse, ethers.MaxInt256), - usdc.connect(buyer).approve(_artToken, ethers.MaxInt256), - usdc.connect(randomAccount).approve(_auctionHouse, ethers.MaxInt256), - ]); - - auctionHouse = _auctionHouse; - auctionHouseAddr = _auctionHouseAddr; - artToken = _artToken; - artTokenAddr = _artTokenAddr; - }); - - let auctionId: bigint; - let tokenId: bigint; - let tokenURI: string; - let price: bigint; - let fee: bigint; - let step: bigint; - let endTime: number; - let participants: string[]; - let shares: bigint[]; - let deadline: number; + const protocol = await deployProtocolTest({ + signer: auctionHouseSigner, + financier, + }); - beforeEach(async () => { - auctionId = 3n; - tokenId = 4n; - tokenURI = 'ipfs://Q...'; - price = 100_000_000n; - fee = 100_000_000n; - step = 1_000_000n; - endTime = await getValidDeadline(); - participants = [financierAddr, institutionAddr]; - shares = [TOTAL_SHARE / 5n, (TOTAL_SHARE / 5n) * 4n]; - deadline = await getValidDeadline(); + auctionHouse = protocol.auctionHouse; + auctionHouseAddr = protocol.auctionHouseAddr; + artToken = protocol.artToken; + artTokenAddr = protocol.artTokenAddr; + usdc = protocol.usdc; + usdcAddr = protocol.usdcAddr; }); describe(`method 'create'`, () => { - it(`should create correct auction`, async () => { - await create(); + it(`should create the auction`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const price = MIN_PRICE; + const fee = MIN_FEE; + const step = 1_000_000n; + const endTime = latestBlockTimestamp + HOUR; + const participants = [institutionAddr, financierAddr]; + const shares = [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n]; + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price, + fee, + step, + endTime, + participants, + shares, + deadline: latestBlockTimestamp + HOUR, + }; - const auction = await getAuction(); + const tx = await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - expect(auction.tokenId).equal(tokenId); - expect(auction.tokenURI).equal(tokenURI); - expect(auction.buyer).equal(ethers.ZeroAddress); + const auction = await auctionHouse.auction(AUCTION_ID); + + await expect(tx) + .to.be.emit(auctionHouse, 'Created') + .withArgs(AUCTION_ID, TOKEN_ID, price, endTime); + + expect(auction.tokenId).equal(TOKEN_ID); + expect(auction.tokenURI).equal(TOKEN_URI); + expect(auction.buyer).equal(ZeroAddress); expect(auction.price).equal(price); expect(auction.fee).equal(fee); expect(auction.step).equal(step); @@ -122,545 +97,680 @@ describe('AuctionHouse', function () { expect(auction.shares).to.deep.equal(shares); }); - it(`should create new auction for token that was not sold at the previous auction`, async () => { - await create(); - await end(); + it(`should create the new auction for token that was not sold at the previous auction`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const firstPermit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - const _auctionId = 5n; - const _endTime = await getValidDeadline(); - const _deadline = await getValidDeadline(); + const secondPermit: CreatePermitStruct = { + ...firstPermit, + auctionId: SECOND_AUCTION_ID, + endTime: latestBlockTimestamp + HOUR * 2, + deadline: latestBlockTimestamp + HOUR * 2, + }; - await create({ - _auctionId, - _endTime, - _deadline, + await AuctionHouseUtils.create({ + auctionHouse, + permit: firstPermit, + permitSigner: auctionHouseSigner, + sender: institution, }); - const auction = await getAuction(_auctionId); + await setNextBlockTimestamp(firstPermit.endTime); - expect(auction.tokenId).equal(tokenId); - expect(auction.tokenURI).equal(tokenURI); - expect(auction.buyer).equal(ethers.ZeroAddress); - expect(auction.price).equal(price); - expect(auction.fee).equal(fee); - expect(auction.step).equal(step); - expect(auction.endTime).equal(_endTime); - expect(auction.sold).equal(false); - expect(auction.participants).to.deep.equal(participants); - expect(auction.shares).to.deep.equal(shares); - }); + await AuctionHouseUtils.create({ + auctionHouse, + permit: secondPermit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - it(`should emit created event`, async () => { - const transaction = await create(); + const auction = await auctionHouse.auction(SECOND_AUCTION_ID); - await expect(transaction) - .to.be.emit(auctionHouse, 'Created') - .withArgs(auctionId, tokenId, price, endTime); + expect(auction.tokenId).equal(TOKEN_ID); }); - it(`should fail if end time lass than block time`, async () => { - const blockTimestamp = await getLatestBlockTimestamp(); + it(`should fail if the auction duration is less than the minimum duration`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - const _endTime = blockTimestamp + 100; + const nextBlockTimestamp = latestBlockTimestamp + HOUR; - await setNextBlockTimestamp(_endTime); + await setNextBlockTimestamp(nextBlockTimestamp); - await expect(create({ _endTime })).to.eventually.rejectedWith( - 'AuctionHouseInvalidEndTime', - ); - }); + const minDuration = Number(await auctionHouse.MIN_DURATION()); - it(`should fail if auction already exists`, async () => { - await create(); + const endTime = nextBlockTimestamp + minDuration - 1; + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - await expect(create()).to.eventually.rejectedWith('AuctionHouseAuctionExists'); + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseInvalidEndTime'); }); - it(`should fail if token is already at active auction`, async () => { - await create(); + it(`should fail if the auction duration is greater than the maximum duration`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - const _auctionId = 5n; + const nextBlockTimestamp = latestBlockTimestamp + HOUR; - await expect(create({ _auctionId })).to.eventually.rejectedWith( - 'AuctionHouseTokenReserved', - ); - }); + await setNextBlockTimestamp(nextBlockTimestamp); + + const maxDuration = Number(await auctionHouse.MAX_DURATION()); - it(`should fail if token is at auction with buyer`, async () => { - await create(); - await endWithBuyer(); + const endTime = nextBlockTimestamp + maxDuration + 1; - const _auctionId = 5n; - const _endTime = await getValidDeadline(); - const _deadline = await getValidDeadline(); + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - await expect(create({ _auctionId, _endTime, _deadline })).to.eventually.rejectedWith( - 'AuctionHouseTokenReserved', - ); + await expect(tx).to.eventually.rejectedWith('AuctionHouseInvalidEndTime'); }); - it(`should fail if token is already minted`, async () => { - const buyPermit: BuyPermitStruct = { - tokenId, - tokenURI, - sender: buyerAddr, - price: 100_000_001n, - fee: 100_000_001n, - participants: [financierAddr], - shares: [TOTAL_SHARE], - deadline, + it(`should fail if the auction already exists`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, }; - const signature = await signBuyPermit(chainId, artTokenAddr, buyPermit, admin); - - await artToken.connect(buyer).buy({ - tokenId, - tokenURI, - price: buyPermit.price, - fee: buyPermit.fee, - participants: buyPermit.participants, - shares: buyPermit.shares, - signature, - deadline, + await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, }); - await expect(create()).to.eventually.rejectedWith('AuctionHouseTokenReserved'); + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionExists'); }); - describe(`permit logic`, () => { - it(`should fail if permit signer is not admin`, async () => { - const _admin = randomAccount; + it(`should fail if the token is already in an active auction`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - await expect(create({ _admin })).to.be.rejectedWith('EIP712InvalidSignature'); - }); + const firstPermit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should fail if permit is expired`, async () => { - const _deadline = await getLatestBlockTimestamp(); + const secondPermit: CreatePermitStruct = { + ...firstPermit, + auctionId: SECOND_AUCTION_ID, + }; - await expect(create({ _deadline })).to.be.rejectedWith('EIP712ExpiredSignature'); + await AuctionHouseUtils.create({ + auctionHouse, + permit: firstPermit, + permitSigner: auctionHouseSigner, + sender: institution, }); + + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit: secondPermit, + permitSigner: auctionHouseSigner, + sender: institution, + }); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseTokenReserved'); }); - describe(`distribution logic`, () => { - it(`should fail if number of shares is not equal number of participants`, async () => { - const _participants = [financierAddr]; - const _shares = [TOTAL_SHARE / 2n, TOTAL_SHARE / 2n]; + it(`should fail if the token is in an inactive auction with a buyer`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - await expect(create({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesCount', - ); - }); + const firstPermit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should fail if total shares is not equal TOTAL_SHARE`, async () => { - const _participants = [financierAddr, institutionAddr]; - const _shares = [TOTAL_SHARE, 1n]; + const secondPermit: CreatePermitStruct = { + ...firstPermit, + auctionId: SECOND_AUCTION_ID, + endTime: latestBlockTimestamp + HOUR * 2, + deadline: latestBlockTimestamp + HOUR * 2, + }; - await expect(create({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesSum', - ); + await AuctionHouseUtils.create({ + auctionHouse, + permit: firstPermit, + permitSigner: auctionHouseSigner, + sender: institution, }); - it(`should fail if shares and participants are empty`, async () => { - const _participants: string[] = []; - const _shares: bigint[] = []; + await usdc.connect(buyer).mintAndApprove(auctionHouse, MaxInt256); + + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, 100_000_000n); + + await setNextBlockTimestamp(firstPermit.endTime); - await expect(create({ _participants, _shares })).to.be.rejectedWith( - 'DistributionInvalidSharesSum', - ); + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit: secondPermit, + permitSigner: auctionHouseSigner, + sender: institution, }); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseTokenReserved'); }); - }); - describe(`method 'tokenReserved'`, () => { - it(`should return 'true' for token that is at active auction`, async () => { - await create(); + it(`should fail if the token is already minted`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); - await expect(auctionHouse.tokenReserved(tokenId)).to.eventually.equal(true); - }); + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should return 'true' for token that is at auction with buyer`, async () => { - await create(); - await endWithBuyer(); + const createPermit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - await expect(auctionHouse.tokenReserved(tokenId)).to.eventually.equal(true); - }); + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); - it(`should return 'false' for token that was not sold at the previous auction`, async () => { - await create(); - await end(); + await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: auctionHouseSigner, + sender: buyer, + }); + + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit: createPermit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - await expect(auctionHouse.tokenReserved(tokenId)).to.eventually.equal(false); + await expect(tx).to.eventually.rejectedWith('AuctionHouseTokenReserved'); }); - it(`should return 'false' for token that has never been put at auction`, async () => { - await expect(auctionHouse.tokenReserved(tokenId)).to.eventually.equal(false); + it(`should fail if the permit signer is not the auction house signer`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: randomAccount, + sender: institution, + }); + + await expect(tx).to.eventually.rejectedWith('AuthorizationUnauthorizedAction'); }); }); describe(`method 'raiseInitial'`, () => { beforeEach(async () => { - await create(); - auctionHouse = auctionHouse.connect(buyer); + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; + + await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); + + await usdc.connect(buyer).mintAndApprove(auctionHouse, MaxInt256); }); - it(`should set buyer if new price is equal initial price`, async () => { - await raiseInitial(); + it(`should raise if the new price is equal to the initial price`, async () => { + const { price: initialPrice } = await auctionHouse.auction(AUCTION_ID); + + const newPrice = initialPrice; + + const tx = await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, newPrice); - const auction = await getAuction(); + const auction = await auctionHouse.auction(AUCTION_ID); expect(auction.buyer).equal(buyerAddr); - expect(auction.price).equal(price); + expect(auction.price).equal(newPrice); + + await expect(tx) + .to.be.emit(auctionHouse, 'Raised') + .withArgs(AUCTION_ID, auction.buyer, auction.price); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(buyerAddr, auctionHouseAddr, auction.price + auction.fee); }); - it(`should set buyer and change price if new price is more than initial price`, async () => { - const _price = price + 1n; + it(`should raise if the new price is greater than the initial price`, async () => { + const { price: initialPrice } = await auctionHouse.auction(AUCTION_ID); - await raiseInitial({ _price }); + const newPrice = initialPrice + 1n; - const auction = await getAuction(); + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, newPrice); + + const auction = await auctionHouse.auction(AUCTION_ID); expect(auction.buyer).equal(buyerAddr); - expect(auction.price).equal(_price); + expect(auction.price).equal(newPrice); }); - it(`should emit raised event`, async () => { - const transaction = await raiseInitial(); + it(`should fail if the new price is lower than the initial price`, async () => { + const { price: initialPrice } = await auctionHouse.auction(AUCTION_ID); - await expect(transaction) - .to.be.emit(auctionHouse, 'Raised') - .withArgs(auctionId, buyerAddr, price); - }); + const newPrice = initialPrice - 1n; - it(`should transfer price and fee from buyer to contract`, async () => { - const transaction = await raiseInitial(); + const tx = auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, newPrice); - await expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs(buyerAddr, auctionHouseAddr, price + fee); + await expect(tx).to.eventually.rejectedWith('AuctionHouseRaiseTooLow'); }); - it(`should fail if new price is less than initial price`, async () => { - const _price = price - 1n; + it(`should fail if the auction does not exist`, async () => { + const tx = auctionHouse.connect(buyer).raiseInitial(0, 1n); - await expect(raiseInitial({ _price })).to.eventually.rejectedWith( - 'AuctionHouseRaiseTooSmall', - ); + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionNotExist'); }); - it(`should fail if auction does not exist`, async () => { - const _auctionId = auctionId + 123n; + it(`should fail if the auction has a buyer`, async () => { + const auction = await auctionHouse.auction(AUCTION_ID); - await expect(raiseInitial({ _auctionId })).to.eventually.rejectedWith( - 'AuctionHouseAuctionNotExist', - ); - }); + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, auction.price); - it(`should fail if auction has buyer`, async () => { - await raiseInitial(); + await usdc.connect(randomAccount).mintAndApprove(auctionHouse, MaxInt256); - await expect(raiseInitial()).to.eventually.rejectedWith('AuctionHouseBuyerExists'); + const tx = auctionHouse.connect(randomAccount).raiseInitial(AUCTION_ID, auction.price); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseBuyerExists'); }); - it(`should fail if auction has ended`, async () => { - await end(); + it(`should fail if the auction has ended`, async () => { + const auction = await auctionHouse.auction(AUCTION_ID); + + await setNextBlockTimestamp(auction.endTime); + + const tx = auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, auction.price); - await expect(raiseInitial()).to.eventually.rejectedWith('AuctionHouseAuctionEnded'); + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionEnded'); }); }); describe(`method 'raise'`, () => { beforeEach(async () => { - await create(); - }); - - it(`should change buyer and price if new price is equal sum of old price plus step`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); - await raise({ _auctionHouse: auctionHouse.connect(buyer) }); + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - const auction = await getAuction(); + await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - expect(auction.buyer).equal(buyerAddr); - expect(auction.price).equal(price + step); + await usdc.connect(buyer).mintAndApprove(auctionHouse, MaxInt256); + await usdc.connect(randomAccount).mintAndApprove(auctionHouse, MaxInt256); }); - it(`should change buyer and price if new price is more than sum of old price plus step`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); + it(`should raise if the new price is equal to the sum of the old price and the step`, async () => { + const { price: initialPrice, step, fee } = await auctionHouse.auction(AUCTION_ID); - const _step = step + 55n; + await auctionHouse.connect(randomAccount).raiseInitial(AUCTION_ID, initialPrice); - await raise({ _step, _auctionHouse: auctionHouse.connect(buyer) }); + const newPrice = initialPrice + step; - const auction = await getAuction(); + const tx = await auctionHouse.connect(buyer).raise(AUCTION_ID, newPrice); + + const auction = await auctionHouse.auction(AUCTION_ID); expect(auction.buyer).equal(buyerAddr); - expect(auction.price).equal(price + _step); - }); + expect(auction.price).equal(newPrice); - it(`should transfer price and fee from buyer to contract`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); + await expect(tx) + .to.be.emit(auctionHouse, 'Raised') + .withArgs(AUCTION_ID, auction.buyer, auction.price); - const transaction = await raise({ _auctionHouse: auctionHouse.connect(buyer) }); + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(buyerAddr, auctionHouseAddr, auction.price + auction.fee); - await expect(transaction) + await expect(tx) .to.be.emit(usdc, 'Transfer') - .withArgs(buyerAddr, auctionHouseAddr, price + step + fee); + .withArgs(auctionHouseAddr, randomAccountAddr, initialPrice + fee); }); - it(`should transfer old price and fee to old buyer`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); + it(`should raise if the new price is greater than the sum of the old price and the step`, async () => { + const { price: initialPrice, step } = await auctionHouse.auction(AUCTION_ID); - const transaction = await raise({ _auctionHouse: auctionHouse.connect(buyer) }); + await auctionHouse.connect(randomAccount).raiseInitial(AUCTION_ID, initialPrice); - await expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs(auctionHouseAddr, randomAccountAddr, price + fee); - }); + const newPrice = initialPrice + step + 1n; - it(`should emit raised event`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); + await auctionHouse.connect(buyer).raise(AUCTION_ID, newPrice); - const transaction = await raise({ _auctionHouse: auctionHouse.connect(buyer) }); + const auction = await auctionHouse.auction(AUCTION_ID); - await expect(transaction) - .to.be.emit(auctionHouse, 'Raised') - .withArgs(auctionId, buyerAddr, price + step); + expect(auction.buyer).equal(buyerAddr); + expect(auction.price).equal(newPrice); }); - it(`should fail if new price is less than sum of old price plus step`, async () => { - await raiseInitial({ _auctionHouse: auctionHouse.connect(randomAccount) }); + it(`should fail if the new price is lower than the sum of the old price and the step`, async () => { + const { price: initialPrice, step } = await auctionHouse.auction(AUCTION_ID); + + await auctionHouse.connect(randomAccount).raiseInitial(AUCTION_ID, initialPrice); + + const newPrice = initialPrice + step - 1n; - const _step = step - 1n; + const tx = auctionHouse.connect(buyer).raise(AUCTION_ID, newPrice); - await expect( - raise({ _step, _auctionHouse: auctionHouse.connect(buyer) }), - ).to.eventually.rejectedWith('AuctionHouseRaiseTooSmall'); + await expect(tx).to.eventually.rejectedWith('AuctionHouseRaiseTooLow'); }); - it(`should fail if auction does not exist`, async () => { - const _auctionId = auctionId + 123n; + it(`should fail if the auction does not exist`, async () => { + const tx = auctionHouse.connect(buyer).raise(0, 2n); - await expect(raise({ _auctionId })).to.eventually.rejectedWith( - 'AuctionHouseAuctionNotExist', - ); + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionNotExist'); }); - it(`should fail if auction has ended`, async () => { - await end(); + it(`should fail if the auction has ended`, async () => { + const { price: initialPrice, step, endTime } = await auctionHouse.auction(AUCTION_ID); + + await auctionHouse.connect(randomAccount).raiseInitial(AUCTION_ID, initialPrice); + + await setNextBlockTimestamp(endTime); - await expect(raise()).to.eventually.rejectedWith('AuctionHouseAuctionEnded'); + const tx = auctionHouse.connect(buyer).raise(AUCTION_ID, initialPrice + step); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionEnded'); }); - it(`should fail if auction does not have buyer`, async () => { - await expect(raise()).to.eventually.rejectedWith('AuctionHouseBuyerNotExists'); + it(`should fail if the auction does not have a buyer`, async () => { + const { price: initialPrice, step } = await auctionHouse.auction(AUCTION_ID); + + const tx = auctionHouse.connect(buyer).raise(AUCTION_ID, initialPrice + step); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseBuyerNotExists'); }); }); describe(`method 'finish'`, async () => { beforeEach(async () => { - await create(); + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; + + await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); + + await usdc.connect(buyer).mintAndApprove(auctionHouse, MaxInt256); }); - it(`should mark auction as sold`, async () => { - await endWithBuyer(); + it(`should finish the auction`, async () => { + const { price, endTime, fee, participants, shares } = + await auctionHouse.auction(AUCTION_ID); + + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, price); + + await setNextBlockTimestamp(endTime); - await finish(); + const tx = await auctionHouse.connect(buyer).finish(AUCTION_ID); - const auction = await getAuction(); + const auction = await auctionHouse.auction(AUCTION_ID); expect(auction.sold).equal(true); - }); - it(`should mint token for buyer`, async () => { - await endWithBuyer(); + await expect(tx) // + .to.be.emit(auctionHouse, 'Sold') + .withArgs(AUCTION_ID); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(auctionHouseAddr, financierAddr, fee); + + await expect(tx) + .to.be.emit(artToken, 'Transfer') + .withArgs(ZeroAddress, buyerAddr, TOKEN_ID); - const transaction = await finish(); + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(auctionHouseAddr, participants[0], (price * shares[0]) / TOTAL_SHARE); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(auctionHouseAddr, participants[1], (price * shares[1]) / TOTAL_SHARE); + }); + + it(`should fail if the auction does not exist`, async () => { + const tx = auctionHouse.connect(buyer).finish(0); - await Promise.all([ - expect(transaction) - .to.be.emit(artToken, 'Transfer') - .withArgs(ethers.ZeroAddress, buyerAddr, tokenId), - expect(artToken.ownerOf(tokenId)).to.eventually.equal(buyerAddr), - ]); + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionNotExist'); }); - it(`should emit sold event`, async () => { - await endWithBuyer(); + it(`should fail if the token has been sold`, async () => { + const { price, endTime } = await auctionHouse.auction(AUCTION_ID); - const transaction = await finish(); + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, price); - await expect(transaction).to.be.emit(auctionHouse, 'Sold').withArgs(auctionId); + await setNextBlockTimestamp(endTime); + + await auctionHouse.connect(buyer).finish(AUCTION_ID); + + const tx = auctionHouse.connect(buyer).finish(AUCTION_ID); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseTokenSold'); }); - it(`should transfer fee to financier`, async () => { - await endWithBuyer(); + it(`should fail if the auction has not ended`, async () => { + const { price } = await auctionHouse.auction(AUCTION_ID); - const transaction = await finish(); + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, price); - await expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs(auctionHouseAddr, financierAddr, fee); + const tx = auctionHouse.connect(buyer).finish(AUCTION_ID); + + await expect(tx).to.eventually.rejectedWith('AuctionHouseAuctionNotEnded'); }); - it(`should fail if auction does not exist`, async () => { - const _auctionId = auctionId + 123n; + it(`should fail if the auction does not have a buyer`, async () => { + const { endTime } = await auctionHouse.auction(AUCTION_ID); + + await setNextBlockTimestamp(endTime); + + const tx = auctionHouse.connect(buyer).finish(AUCTION_ID); - await expect(finish(_auctionId)).to.eventually.rejectedWith( - 'AuctionHouseAuctionNotExist', - ); + await expect(tx).to.eventually.rejectedWith('AuctionHouseBuyerNotExists'); }); + }); + + describe(`method 'tokenReserved'`, () => { + beforeEach(async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const permit: CreatePermitStruct = { + auctionId: AUCTION_ID, + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + price: MIN_PRICE, + fee: MIN_FEE, + step: AUCTION_STEP, + endTime: latestBlockTimestamp + HOUR, + participants: [institutionAddr, financierAddr], + shares: [(TOTAL_SHARE / 5n) * 4n, TOTAL_SHARE / 5n], + deadline: latestBlockTimestamp + HOUR, + }; - it(`should fail if auction has sold`, async () => { - await endWithBuyer(); - await finish(); + await AuctionHouseUtils.create({ + auctionHouse, + permit, + permitSigner: auctionHouseSigner, + sender: institution, + }); - await expect(finish()).to.eventually.rejectedWith('AuctionHouseTokenSold'); + await usdc.connect(buyer).mintAndApprove(auctionHouse, MaxInt256); }); - it(`should fail if auction has not ended`, async () => { - await expect(finish()).to.eventually.rejectedWith('AuctionHouseAuctionNotEnded'); + it(`should return 'true' for a token that is in an active auction`, async () => { + const tokenReserved = await auctionHouse.tokenReserved(TOKEN_ID); + + expect(tokenReserved).equal(true); }); - it(`should fail if auction does not have buyer`, async () => { - await end(); + it(`should return 'true' for a token that is in an inactive auction with a buyer`, async () => { + const { price, endTime } = await auctionHouse.auction(AUCTION_ID); - await expect(finish()).to.eventually.rejectedWith('AuctionHouseBuyerNotExists'); + await auctionHouse.connect(buyer).raiseInitial(AUCTION_ID, price); + + await setNextBlockTimestamp(endTime); + + const tokenReserved = await auctionHouse.tokenReserved(TOKEN_ID); + + expect(tokenReserved).equal(true); }); - describe(`distribution logic`, () => { - it(`should distribute reward between participants according to shares`, async () => { - await endWithBuyer(); + it(`should return 'false' for a token that has not been sold`, async () => { + const { endTime } = await auctionHouse.auction(AUCTION_ID); - const transaction = await finish(); + await setNextBlockTimestamp(endTime); + await mine(); - await Promise.all([ - expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs( - auctionHouseAddr, - participants[0], - (price * shares[0]) / TOTAL_SHARE, - ), - expect(transaction) - .to.be.emit(usdc, 'Transfer') - .withArgs( - auctionHouseAddr, - participants[1], - (price * shares[1]) / TOTAL_SHARE, - ), - ]); - }); + const tokenReserved = await auctionHouse.tokenReserved(TOKEN_ID); + + expect(tokenReserved).equal(false); }); - }); - async function create( - params: { - _auctionId?: bigint; - _tokenId?: bigint; - _tokenURI?: string; - _price?: bigint; - _fee?: bigint; - _step?: bigint; - _endTime?: number; - _participants?: string[]; - _shares?: bigint[]; - _deadline?: number; - _admin?: Signer; - _auctionHouse?: AuctionHouse; - } = {}, - ) { - const { - _auctionId = auctionId, - _tokenId = tokenId, - _tokenURI = tokenURI, - _price = price, - _fee = fee, - _step = step, - _endTime = endTime, - _participants = participants, - _shares = shares, - _deadline = deadline, - _admin = admin, - _auctionHouse = auctionHouse, - } = params; - - const permit: CreatePermitStruct = { - auctionId: _auctionId, - tokenId: _tokenId, - tokenURI: _tokenURI, - price: _price, - fee: _fee, - step: _step, - endTime: _endTime, - participants: _participants, - shares: _shares, - deadline: _deadline, - }; - - const signature = await signCreatePermit(chainId, auctionHouseAddr, permit, _admin); - - return _auctionHouse.create({ - auctionId: _auctionId, - tokenId: _tokenId, - tokenURI: _tokenURI, - price: _price, - fee: _fee, - step: _step, - endTime: _endTime, - participants: _participants, - shares: _shares, - signature, - deadline: _deadline, - }); - } - - async function raiseInitial( - params: { - _auctionId?: bigint; - _price?: bigint; - _auctionHouse?: AuctionHouse; - } = {}, - ) { - const { _auctionId = auctionId, _price = price, _auctionHouse = auctionHouse } = params; - - return _auctionHouse.raiseInitial(_auctionId, _price); - } - - async function raise( - params: { - _auctionId?: bigint; - _price?: bigint; - _step?: bigint; - _auctionHouse?: AuctionHouse; - } = {}, - ) { - const { - _auctionId = auctionId, - _price = price, - _step = step, - _auctionHouse = auctionHouse, - } = params; - - return _auctionHouse.raise(_auctionId, _price + _step); - } - - async function finish(_auctionId = auctionId) { - return auctionHouse.finish(_auctionId); - } - - async function getAuction(_auctionId = auctionId) { - return auctionHouse.auction(_auctionId); - } - - async function end() { - const auction = await getAuction(); - - await setNextBlockTimestamp(auction.endTime + 1n); - - await mine(); - } - - async function endWithBuyer(_buyer: Signer = buyer) { - await raiseInitial({ _auctionHouse: auctionHouse.connect(_buyer) }); - await end(); - } + it(`should return 'false' for a token that has never been put up for auction`, async () => { + const tokenReserved = await auctionHouse.tokenReserved(0); + + expect(tokenReserved).equal(false); + }); + }); }); diff --git a/tests/Authorization.ts b/tests/Authorization.ts new file mode 100644 index 0000000..e2f1e71 --- /dev/null +++ b/tests/Authorization.ts @@ -0,0 +1,121 @@ +import { expect } from 'chai'; +import { Signer, MaxInt256 } from 'ethers'; +import { ArtToken, USDC } from '../typechain-types'; +import { BuyPermitStruct } from '../types/art-token'; +import { MIN_FEE, MIN_PRICE } from './constants/min-price-and-fee'; +import { TOTAL_SHARE } from './constants/distribution'; +import { TOKEN_ID, TOKEN_URI } from './constants/art-token'; +import { HOUR } from './constants/time'; +import { getSigners } from './utils/get-signers'; +import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; +import { deployProtocolTest } from './utils/deploy-protocol-test'; +import { ArtTokenUtils } from './utils/art-token-utils'; + +describe('Authorization', function () { + let artToken: ArtToken, artTokenAddr: string; + let usdc: USDC, usdcAddr: string; + + let artTokenSigner: Signer, artTokenSignerAddr: string; + let financier: Signer, financierAddr: string; + let institution: Signer, institutionAddr: string; + let buyer: Signer, buyerAddr: string; + let randomAccount: Signer, randomAccountAddr: string; + + before(async () => { + [ + [artTokenSigner, financier, institution, buyer, randomAccount], + [artTokenSignerAddr, financierAddr, institutionAddr, buyerAddr, randomAccountAddr], + ] = await getSigners(); + }); + + beforeEach(async () => { + const protocol = await deployProtocolTest({ + signer: artTokenSigner, + financier, + }); + + artToken = protocol.artToken; + artTokenAddr = protocol.artTokenAddr; + usdc = protocol.usdc; + usdcAddr = protocol.usdcAddr; + }); + + describe(`method '_requireAuthorizedAction'`, () => { + beforeEach(async () => { + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); + }); + + it(`should allow the action`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + const deadline = latestBlockTimestamp + HOUR; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline, + }; + + await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + }); + + it(`should fail the action if the deadline has expired`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + const deadline = latestBlockTimestamp - HOUR; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('AuthorizationDeadlineExpired'); + }); + + it(`should fail if the signer is invalid`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + const deadline = latestBlockTimestamp + HOUR; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price: MIN_PRICE, + fee: MIN_FEE, + participants: [institutionAddr], + shares: [TOTAL_SHARE], + deadline, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: randomAccount, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('AuthorizationUnauthorizedAction'); + }); + }); +}); diff --git a/tests/Distribution.ts b/tests/Distribution.ts new file mode 100644 index 0000000..04e9c98 --- /dev/null +++ b/tests/Distribution.ts @@ -0,0 +1,234 @@ +import { expect } from 'chai'; +import { Signer, MaxInt256 } from 'ethers'; +import { ArtToken, USDC } from '../typechain-types'; +import { BuyPermitStruct } from '../types/art-token'; +import { MIN_FEE, MIN_PRICE } from './constants/min-price-and-fee'; +import { TOTAL_SHARE } from './constants/distribution'; +import { TOKEN_ID, TOKEN_URI } from './constants/art-token'; +import { HOUR } from './constants/time'; +import { getSigners } from './utils/get-signers'; +import { getLatestBlockTimestamp } from './utils/get-latest-block-timestamp'; +import { deployProtocolTest } from './utils/deploy-protocol-test'; +import { ArtTokenUtils } from './utils/art-token-utils'; + +describe('Distribution', function () { + let artToken: ArtToken, artTokenAddr: string; + let usdc: USDC, usdcAddr: string; + + let artTokenSigner: Signer, artTokenSignerAddr: string; + let financier: Signer, financierAddr: string; + let institution: Signer, institutionAddr: string; + let buyer: Signer, buyerAddr: string; + + before(async () => { + [ + [artTokenSigner, financier, institution, buyer], + [artTokenSignerAddr, financierAddr, institutionAddr, buyerAddr], + ] = await getSigners(); + }); + + beforeEach(async () => { + const protocol = await deployProtocolTest({ + signer: artTokenSigner, + financier, + }); + + artToken = protocol.artToken; + artTokenAddr = protocol.artTokenAddr; + usdc = protocol.usdc; + usdcAddr = protocol.usdcAddr; + }); + + describe(`method 'safeDistribute'`, () => { + beforeEach(async () => { + await usdc.connect(buyer).mintAndApprove(artToken, MaxInt256); + }); + + it(`should distribute rewards between participants according to shares`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const institutionShare = (TOTAL_SHARE / 5n) * 4n; // 80% + const platformShare = TOTAL_SHARE / 5n; // 20% + + const price = MIN_PRICE; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(artTokenAddr, institutionAddr, (price * institutionShare) / TOTAL_SHARE); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(artTokenAddr, financierAddr, (price * platformShare) / TOTAL_SHARE); + }); + + it(`should send the remainder of the division to the last participant`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const institutionShare = (TOTAL_SHARE / 5n) * 4n; // 80% + const platformShare = TOTAL_SHARE / 5n; // 20% + + const remainder = 1n; + const price = 100_000_000n + remainder; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = await ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs(artTokenAddr, institutionAddr, (price * institutionShare) / TOTAL_SHARE); + + await expect(tx) + .to.be.emit(usdc, 'Transfer') + .withArgs( + artTokenAddr, + financierAddr, + (price * platformShare) / TOTAL_SHARE + remainder, + ); + }); + + it(`should fail if the number of participants and the number of shares do not match`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const institutionShare = TOTAL_SHARE; + + const price = MIN_PRICE; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [institutionAddr, financierAddr], + shares: [institutionShare], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('DistributionParticipantsSharesMismatch'); + }); + + it(`should fail if the total share is greater than 100%`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const institutionShare = (TOTAL_SHARE / 5n) * 4n; // 80% + const platformShare = TOTAL_SHARE / 4n; // 25% + + const price = MIN_PRICE; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('DistributionSharesSumTooBig(10500)'); + }); + + it(`should fail if the total share is less than 100%`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const institutionShare = (TOTAL_SHARE / 5n) * 3n; // 60% + const platformShare = TOTAL_SHARE / 5n; // 20% + + const price = MIN_PRICE; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [institutionAddr, financierAddr], + shares: [institutionShare, platformShare], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('DistributionSharesSumTooLow(8000)'); + }); + + it(`should fail if shares and participants are missing`, async () => { + const latestBlockTimestamp = await getLatestBlockTimestamp(); + + const price = MIN_PRICE; + + const buyPermit: BuyPermitStruct = { + tokenId: TOKEN_ID, + tokenURI: TOKEN_URI, + sender: buyerAddr, + price, + fee: MIN_FEE, + participants: [], + shares: [], + deadline: latestBlockTimestamp + HOUR, + }; + + const tx = ArtTokenUtils.buy({ + artToken, + permit: buyPermit, + permitSigner: artTokenSigner, + sender: buyer, + }); + + await expect(tx).to.be.rejectedWith('DistributionSharesSumTooLow(0)'); + }); + }); +}); diff --git a/tests/RoleSystem.ts b/tests/RoleSystem.ts index 434a405..9463064 100644 --- a/tests/RoleSystem.ts +++ b/tests/RoleSystem.ts @@ -1,96 +1,86 @@ import { expect } from 'chai'; +import { Signer, ZeroAddress } from 'ethers'; import { ethers } from 'hardhat'; +import { deploy } from '../scripts/deploy'; +import { RoleSystem } from '../typechain-types'; +import { ADMIN_ROLE } from './constants/roles'; import { getSigners } from './utils/get-signers'; -import { ArtToken } from '../typechain-types'; -import { Signer } from '../types/environment'; -import { deployProtocol } from '../scripts/deploy-protocol'; describe('RoleSystem', function () { - let roleSystem: ArtToken, roleSystemAddr: string; + let roleSystem: RoleSystem, roleSystemAddr: string; let main: Signer, mainAddr: string; let account: Signer, accountAddr: string; - const someRole = ethers.keccak256(Buffer.from('SOME_ROLE')); - before(async () => { [[main, account], [mainAddr, accountAddr]] = await getSigners(); }); beforeEach(async () => { - const { artToken: _artToken, artTokenAddr: _artTokenAddr } = await deployProtocol({ - name: 'TestToken', - symbol: 'TT', - main, - usdc: '0xffffffffffffffffffffffffffffffffffffffff', - minPriceUsd: 10, - minFeeUsd: 10, - minAuctionDurationHours: 1, - regulated: true, + const { contractAddr } = await deploy({ + name: 'RoleSystem', + constructorArgs: [main], }); - roleSystem = _artToken.connect(main); - roleSystemAddr = _artTokenAddr; + roleSystem = await ethers.getContractAt('RoleSystem', contractAddr, main); + roleSystemAddr = contractAddr; }); describe(`roles`, () => { - describe(`method 'grandRole'`, () => { - it(`should grand`, async () => { - const transaction = await roleSystem.grandRole(someRole, account); - - await Promise.all([ - expect(transaction) - .to.be.emit(roleSystem, 'RoleGranted') - .withArgs(someRole, accountAddr), - expect(roleSystem.hasRole(someRole, account)).to.eventually.equal(true), - ]); + describe(`method 'grantRole'`, () => { + it(`should grant`, async () => { + const transaction = await roleSystem.grantRole(ADMIN_ROLE, account); + + await expect(transaction) + .to.be.emit(roleSystem, 'RoleGranted') + .withArgs(ADMIN_ROLE, accountAddr); + + await expect(roleSystem.hasRole(ADMIN_ROLE, account)).to.eventually.equal(true); }); - it(`should fail if sender is not main`, async () => { + it(`should fail if a sender is not the main account`, async () => { await expect( - roleSystem.connect(account).grandRole(someRole, account), + roleSystem.connect(account).grantRole(ADMIN_ROLE, account), ).to.eventually.rejectedWith('RoleSystemNotMain'); }); }); describe(`method 'revokeRole'`, () => { beforeEach(async () => { - await roleSystem.grandRole(someRole, account); + await roleSystem.grantRole(ADMIN_ROLE, account); }); it(`should revoke`, async () => { - const transaction = await roleSystem.revokeRole(someRole, account); - - await Promise.all([ - expect(transaction) - .to.be.emit(roleSystem, 'RoleRevoked') - .withArgs(someRole, accountAddr), - expect(roleSystem.hasRole(someRole, account)).to.eventually.equal(false), - ]); + const transaction = await roleSystem.revokeRole(ADMIN_ROLE, account); + + await expect(transaction) + .to.be.emit(roleSystem, 'RoleRevoked') + .withArgs(ADMIN_ROLE, accountAddr); + + await expect(roleSystem.hasRole(ADMIN_ROLE, account)).to.eventually.equal(false); }); - it(`should fail if sender is not main`, async () => { + it(`should fail if a sender is not the main account`, async () => { await expect( - roleSystem.connect(account).revokeRole(someRole, account), + roleSystem.connect(account).revokeRole(ADMIN_ROLE, account), ).to.eventually.rejectedWith('RoleSystemNotMain'); }); }); describe(`method 'hasRole'`, () => { - it(`should work correctly`, async () => { - await roleSystem.grandRole(someRole, account); + it(`should return correct value`, async () => { + await roleSystem.grantRole(ADMIN_ROLE, account); - await expect(roleSystem.hasRole(someRole, account)).to.eventually.equal(true); + await expect(roleSystem.hasRole(ADMIN_ROLE, account)).to.eventually.equal(true); - await roleSystem.revokeRole(someRole, account); + await roleSystem.revokeRole(ADMIN_ROLE, account); - await expect(roleSystem.hasRole(someRole, account)).to.eventually.equal(false); + await expect(roleSystem.hasRole(ADMIN_ROLE, account)).to.eventually.equal(false); }); - it(`should fail if account is null`, async () => { - await expect( - roleSystem.hasRole(someRole, ethers.ZeroAddress), - ).to.eventually.rejectedWith('RoleSystemZeroAddress'); + it(`should fail if the account is zero`, async () => { + await expect(roleSystem.hasRole(ADMIN_ROLE, ZeroAddress)) // + .to.eventually.rejectedWith('RoleSystemZeroAddress'); }); }); }); @@ -98,42 +88,38 @@ describe('RoleSystem', function () { describe(`unique roles`, () => { describe(`method 'transferUniqueRole'`, () => { it(`should transfer`, async () => { - const transaction1 = await roleSystem.transferUniqueRole(someRole, account); + const tx1 = await roleSystem.transferUniqueRole(ADMIN_ROLE, account); - await expect(transaction1) + await expect(tx1) .to.be.emit(roleSystem, 'UniqueRoleTransferred') - .withArgs(ethers.ZeroAddress, accountAddr, someRole); + .withArgs(ADMIN_ROLE, accountAddr); - const transaction2 = await roleSystem.transferUniqueRole( - someRole, - ethers.ZeroAddress, - ); + const tx2 = await roleSystem.transferUniqueRole(ADMIN_ROLE, ZeroAddress); - await expect(transaction2) + await expect(tx2) .to.be.emit(roleSystem, 'UniqueRoleTransferred') - .withArgs(accountAddr, ethers.ZeroAddress, someRole); + .withArgs(ADMIN_ROLE, ZeroAddress); }); - it(`should fail if sender is not main`, async () => { - await expect( - roleSystem.connect(account).transferUniqueRole(someRole, account), - ).to.eventually.rejectedWith('RoleSystemNotMain'); + it(`should fail if a sender is not the main account`, async () => { + const tx = roleSystem.connect(account).transferUniqueRole(ADMIN_ROLE, account); + + await expect(tx).to.eventually.rejectedWith('RoleSystemNotMain'); }); }); - describe(`method 'uniqueRoleAccount'`, () => { - it(`should return account`, async () => { - await roleSystem.transferUniqueRole(someRole, account); + describe(`method 'uniqueRoleOwner'`, () => { + it(`should return the owner`, async () => { + await roleSystem.transferUniqueRole(ADMIN_ROLE, account); - await expect(roleSystem.uniqueRoleAccount(someRole)).to.eventually.equal( - accountAddr, - ); + await expect(roleSystem.uniqueRoleOwner(ADMIN_ROLE)) // + .to.eventually.equal(accountAddr); }); - it(`should fail if account is null`, async () => { - await expect(roleSystem.uniqueRoleAccount(someRole)).to.eventually.rejectedWith( - 'RoleSystemZeroAddress', - ); + it(`should fail if the role does not have an owner`, async () => { + const tx = roleSystem.uniqueRoleOwner(ADMIN_ROLE); + + await expect(tx).to.eventually.rejectedWith('RoleSystemZeroAddress'); }); }); }); diff --git a/constants/art-token.ts b/tests/constants/art-token.ts similarity index 78% rename from constants/art-token.ts rename to tests/constants/art-token.ts index 00348a1..e045385 100644 --- a/constants/art-token.ts +++ b/tests/constants/art-token.ts @@ -1,6 +1,3 @@ -export const ART_TOKEN_NAME = 'Digital Original'; -export const ART_TOKEN_SYMBOL = 'DO'; - export const ART_TOKEN_DOMAIN_NAME = 'ArtToken'; export const ART_TOKEN_DOMAIN_VERSION = '1'; @@ -16,3 +13,7 @@ export const BUY_PERMIT_TYPE = { { name: 'deadline', type: 'uint256' }, ], }; + +export const TOKEN_ID = 1; +export const TOKEN_URI = 'ipfs://QmbQ9c4KN5FcGreai5rjTRUs1N2FFMaY819JGZZMGDcSLQ'; +export const REGULATED = true; diff --git a/constants/auction-house.ts b/tests/constants/auction-house.ts similarity index 81% rename from constants/auction-house.ts rename to tests/constants/auction-house.ts index 802124a..d325c86 100644 --- a/constants/auction-house.ts +++ b/tests/constants/auction-house.ts @@ -15,3 +15,8 @@ export const CREATE_PERMIT_TYPE = { { name: 'deadline', type: 'uint256' }, ], }; + +export const AUCTION_ID = 1; +export const SECOND_AUCTION_ID = 2; +export const AUCTION_STEP = 1_000_000n; +export const MIN_AUCTION_DURATION = 1800; diff --git a/constants/distribution.ts b/tests/constants/distribution.ts similarity index 100% rename from constants/distribution.ts rename to tests/constants/distribution.ts diff --git a/tests/constants/min-price-and-fee.ts b/tests/constants/min-price-and-fee.ts new file mode 100644 index 0000000..c0eec4e --- /dev/null +++ b/tests/constants/min-price-and-fee.ts @@ -0,0 +1,2 @@ +export const MIN_PRICE = 100_000_000n; +export const MIN_FEE = 100_000_000n; diff --git a/tests/constants/roles.ts b/tests/constants/roles.ts new file mode 100644 index 0000000..f1c2ef4 --- /dev/null +++ b/tests/constants/roles.ts @@ -0,0 +1,6 @@ +import { keccak256 } from 'ethers'; + +export const SIGNER_ROLE = keccak256(Buffer.from('SIGNER_ROLE')); +export const FINANCIAL_ROLE = keccak256(Buffer.from('FINANCIAL_ROLE')); +export const ADMIN_ROLE = keccak256(Buffer.from('ADMIN_ROLE')); +export const PARTNER_ROLE = keccak256(Buffer.from('PARTNER_ROLE')); diff --git a/tests/constants/time.ts b/tests/constants/time.ts new file mode 100644 index 0000000..82340ca --- /dev/null +++ b/tests/constants/time.ts @@ -0,0 +1 @@ +export const HOUR = 3600; diff --git a/tests/utils/art-token-utils.ts b/tests/utils/art-token-utils.ts new file mode 100644 index 0000000..c6d3a10 --- /dev/null +++ b/tests/utils/art-token-utils.ts @@ -0,0 +1,45 @@ +import { Signer, TypedDataDomain } from 'ethers'; +import { BuyPermitStruct } from '../../types/art-token'; +import { + ART_TOKEN_DOMAIN_NAME, + ART_TOKEN_DOMAIN_VERSION, + BUY_PERMIT_TYPE, +} from '../constants/art-token'; +import { ArtToken } from '../../typechain-types'; +import { getChainId } from './get-chain-id'; + +type BuyArgs = { + artToken: ArtToken; + permit: BuyPermitStruct; + permitSigner: Signer; + sender: Signer; +}; + +export class ArtTokenUtils { + static async buy(args: BuyArgs) { + const { artToken, permit, permitSigner, sender } = args; + + const domain = await this.buildDomain(artToken); + + const signature = await permitSigner.signTypedData(domain, BUY_PERMIT_TYPE, permit); + + return artToken.connect(sender).buy({ + ...permit, + signature, + }); + } + + static async buildDomain(artToken: ArtToken): Promise { + const [chainId, verifyingContract] = await Promise.all([ + getChainId(), + artToken.getAddress(), + ]); + + return { + name: ART_TOKEN_DOMAIN_NAME, + version: ART_TOKEN_DOMAIN_VERSION, + chainId, + verifyingContract, + }; + } +} diff --git a/tests/utils/auction-house-utils.ts b/tests/utils/auction-house-utils.ts new file mode 100644 index 0000000..e054e44 --- /dev/null +++ b/tests/utils/auction-house-utils.ts @@ -0,0 +1,45 @@ +import { Signer, TypedDataDomain } from 'ethers'; +import { AuctionHouse } from '../../typechain-types'; +import { CreatePermitStruct } from '../../types/auction-house'; +import { getChainId } from './get-chain-id'; +import { + AUCTION_HOUSE_DOMAIN_NAME, + AUCTION_HOUSE_DOMAIN_VERSION, + CREATE_PERMIT_TYPE, +} from '../constants/auction-house'; + +type CreateArgs = { + auctionHouse: AuctionHouse; + permit: CreatePermitStruct; + permitSigner: Signer; + sender: Signer; +}; + +export class AuctionHouseUtils { + static async create(args: CreateArgs) { + const { auctionHouse, permit, permitSigner, sender } = args; + + const domain = await this.buildDomain(auctionHouse); + + const signature = await permitSigner.signTypedData(domain, CREATE_PERMIT_TYPE, permit); + + return auctionHouse.connect(sender).create({ + ...permit, + signature, + }); + } + + static async buildDomain(auctionHouse: AuctionHouse): Promise { + const [chainId, verifyingContract] = await Promise.all([ + getChainId(), + auctionHouse.getAddress(), + ]); + + return { + name: AUCTION_HOUSE_DOMAIN_NAME, + version: AUCTION_HOUSE_DOMAIN_VERSION, + chainId, + verifyingContract, + }; + } +} diff --git a/tests/utils/deploy-protocol-test.ts b/tests/utils/deploy-protocol-test.ts new file mode 100644 index 0000000..0151fee --- /dev/null +++ b/tests/utils/deploy-protocol-test.ts @@ -0,0 +1,113 @@ +import { ethers } from 'hardhat'; +import { AddressLike, Signer } from 'ethers'; +import { + UpgradedEvent, + AdminChangedEvent, +} from '../../typechain-types/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy'; +import { OwnershipTransferredEvent } from '../../typechain-types/@openzeppelin/contracts/proxy/transparent/ProxyAdmin'; +import { DeployedEvent } from '../../typechain-types/contracts/tests/DeployerTest'; +import { deploy } from '../../scripts/deploy'; +import { MIN_AUCTION_DURATION } from '../constants/auction-house'; +import { MIN_FEE, MIN_PRICE } from '../constants/min-price-and-fee'; +import { REGULATED } from '../constants/art-token'; + +type Params = { + signer: AddressLike; + financier: AddressLike; +}; + +// prettier-ignore +export async function deployProtocolTest(params: Params, deployer?: Signer) { + const { + signer, + financier, + } = params; + + const { receipt } = await deploy( + { + name: 'DeployerTest', + constructorArgs: [signer, financier, MIN_PRICE, MIN_FEE, MIN_AUCTION_DURATION, REGULATED], + }, + deployer, + ); + + const Proxy = await ethers.getContractFactory('TransparentUpgradeableProxy'); + const ProxyAdmin = await ethers.getContractFactory('ProxyAdmin'); + const Deployer = await ethers.getContractFactory('DeployerTest'); + + const ArtToken_Proxy_UpgradedEvent = < + UpgradedEvent.LogDescription + >(Proxy.interface.parseLog(receipt.logs[0])); + + const ArtToken_ProxyAdmin_OwnershipTransferredEvent = < + OwnershipTransferredEvent.LogDescription + >(ProxyAdmin.interface.parseLog(receipt.logs[1])); + + const ArtToken_Proxy_AdminChangedEvent = < + AdminChangedEvent.LogDescription + >(Proxy.interface.parseLog(receipt.logs[2])); + + const AuctionHouse_Proxy_UpgradedEvent = < + UpgradedEvent.LogDescription + >(Proxy.interface.parseLog(receipt.logs[3])); + + const AuctionHouse_ProxyAdmin_OwnershipTransferredEvent = < + OwnershipTransferredEvent.LogDescription + >(ProxyAdmin.interface.parseLog(receipt.logs[4])); + + const AuctionHouse_Proxy_AdminChangedEvent = < + AdminChangedEvent.LogDescription + >(Proxy.interface.parseLog(receipt.logs[5])); + + const Deployer_DeployedEvent = < + DeployedEvent.LogDescription + >(Deployer.interface.parseLog(receipt.logs[6])); + + const artTokenAddr = Deployer_DeployedEvent.args.artToken; + const artTokenImplAddr = ArtToken_Proxy_UpgradedEvent.args.implementation; + const artTokenProxyAdminAddr = ArtToken_Proxy_AdminChangedEvent.args.newAdmin; + const artTokenProxyAdminOwner = ArtToken_ProxyAdmin_OwnershipTransferredEvent.args.newOwner; + + const auctionHouseAddr = Deployer_DeployedEvent.args.auctionHouse; + const auctionHouseImplAddr = AuctionHouse_Proxy_UpgradedEvent.args.implementation; + const auctionHouseProxyAdminAddr = AuctionHouse_Proxy_AdminChangedEvent.args.newAdmin; + const auctionHouseProxyAdminOwner = AuctionHouse_ProxyAdmin_OwnershipTransferredEvent.args.newOwner; + + const marketMockAddr = Deployer_DeployedEvent.args.marketMock; + + const usdcAddr = Deployer_DeployedEvent.args.usdc; + + const artToken = await ethers.getContractAt('ArtToken', artTokenAddr); + const artTokenProxyAdmin = await ethers.getContractAt('ProxyAdmin', artTokenProxyAdminAddr); + + const auctionHouse = await ethers.getContractAt('AuctionHouse', auctionHouseAddr); + const auctionHouseProxyAdmin = await ethers.getContractAt('ProxyAdmin', auctionHouseProxyAdminAddr); + + const marketMock = await ethers.getContractAt('MarketMock', marketMockAddr); + + const usdc = await ethers.getContractAt('USDC', usdcAddr); + + return { + receipt, + + artToken, + artTokenAddr, + artTokenProxyAdmin, + artTokenProxyAdminAddr, + artTokenProxyAdminOwner, + artTokenImplAddr, + + auctionHouse, + auctionHouseAddr, + auctionHouseProxyAdmin, + auctionHouseProxyAdminAddr, + auctionHouseProxyAdminOwner, + auctionHouseImplAddr, + + marketMock, + marketMockAddr, + + usdcAddr, + usdc, + }; +} diff --git a/tests/utils/deploy-usdc.ts b/tests/utils/deploy-usdc.ts deleted file mode 100644 index 9ae7c0a..0000000 --- a/tests/utils/deploy-usdc.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { ethers } from 'hardhat'; -import { deployClassic } from '../../scripts/deploy-classic'; - -export async function deployUsdc() { - const { contractAddr } = await deployClassic({ - name: 'USDC', - constructorArgs: [], - }); - - const contract = await ethers.getContractAt('USDC', contractAddr); - - return [contract, contractAddr] as const; -} diff --git a/tests/utils/get-proxy-admin.ts b/tests/utils/get-proxy-admin.ts deleted file mode 100644 index 1f8daeb..0000000 --- a/tests/utils/get-proxy-admin.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ethers } from 'hardhat'; -import { Contract } from 'ethers'; -import { AdminChangedEvent } from '../../typechain-types/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy'; - -export async function getProxyAdmin(proxy: Contract) { - const receipt = await proxy.deploymentTransaction()?.wait(); - - if (!receipt) { - throw new Error('Deployment transaction receipt error'); - } - - const TransparentUpgradeableProxy = await ethers.getContractFactory( - 'TransparentUpgradeableProxy', - ); - - const adminChangedEvent = ( - (TransparentUpgradeableProxy.interface.parseLog(receipt.logs[2])!) - ); - - const proxyAdminAddress = adminChangedEvent.args.newAdmin; - - return Promise.all([ethers.getContractAt('ProxyAdmin', proxyAdminAddress), proxyAdminAddress]); -} diff --git a/tests/utils/get-signers.ts b/tests/utils/get-signers.ts index aa29336..c9e7745 100644 --- a/tests/utils/get-signers.ts +++ b/tests/utils/get-signers.ts @@ -1,5 +1,5 @@ import { ethers } from 'hardhat'; -import { Signer } from '../../types/environment'; +import { Signer } from 'ethers'; export async function getSigners(): Promise { const [deployer, signer1, signer2, signer3, signer4, signer5, signer6, signer7, signer8] = diff --git a/tests/utils/get-valid-deadline.ts b/tests/utils/get-valid-deadline.ts deleted file mode 100644 index a9fc457..0000000 --- a/tests/utils/get-valid-deadline.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { getLatestBlockTimestamp } from './get-latest-block-timestamp'; - -export async function getValidDeadline() { - const timestamp = await getLatestBlockTimestamp(); - const twoHourS = 60 * 60 * 2; - const deadline = timestamp + twoHourS; - return deadline; -} diff --git a/tests/utils/sign-art-token-buy-permit.ts b/tests/utils/sign-art-token-buy-permit.ts deleted file mode 100644 index 122e1cc..0000000 --- a/tests/utils/sign-art-token-buy-permit.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { TypedDataDomain } from 'ethers'; -import { Signer } from '../../types/environment'; -import { BuyPermitStruct } from '../../types/art-token'; -import { - ART_TOKEN_DOMAIN_NAME, - ART_TOKEN_DOMAIN_VERSION, - BUY_PERMIT_TYPE, -} from '../../constants/art-token'; - -export function signBuyPermit( - chainId: number, - verifyingContract: string, - value: BuyPermitStruct, - signer: Signer, -) { - const domain: TypedDataDomain = { - name: ART_TOKEN_DOMAIN_NAME, - version: ART_TOKEN_DOMAIN_VERSION, - chainId, - verifyingContract, - }; - - return signer.signTypedData(domain, BUY_PERMIT_TYPE, value); -} diff --git a/tests/utils/sign-auction-house-create-permit.ts b/tests/utils/sign-auction-house-create-permit.ts deleted file mode 100644 index 1e9aae6..0000000 --- a/tests/utils/sign-auction-house-create-permit.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { TypedDataDomain } from 'ethers'; -import { Signer } from '../../types/environment'; -import { CreatePermitStruct } from '../../types/auction-house'; -import { - AUCTION_HOUSE_DOMAIN_NAME, - AUCTION_HOUSE_DOMAIN_VERSION, - CREATE_PERMIT_TYPE, -} from '../../constants/auction-house'; - -export function signCreatePermit( - chainId: number, - verifyingContract: string, - value: CreatePermitStruct, - signer: Signer, -) { - const domain: TypedDataDomain = { - name: AUCTION_HOUSE_DOMAIN_NAME, - version: AUCTION_HOUSE_DOMAIN_VERSION, - chainId, - verifyingContract, - }; - - return signer.signTypedData(domain, CREATE_PERMIT_TYPE, value); -} diff --git a/types/art-token.ts b/types/art-token.ts index 799428a..fba7c49 100644 --- a/types/art-token.ts +++ b/types/art-token.ts @@ -1,10 +1,12 @@ +import { AddressLike, Numeric } from 'ethers'; + export type BuyPermitStruct = { - tokenId: bigint; + tokenId: Numeric; tokenURI: string; - sender: string; - price: bigint; - fee: bigint; - participants: string[]; - shares: bigint[]; - deadline: number; + sender: AddressLike; + price: Numeric; + fee: Numeric; + participants: AddressLike[]; + shares: Numeric[]; + deadline: Numeric; }; diff --git a/types/auction-house.ts b/types/auction-house.ts index 3cf17f6..f5e40d6 100644 --- a/types/auction-house.ts +++ b/types/auction-house.ts @@ -1,12 +1,14 @@ +import { Numeric } from 'ethers'; + export type CreatePermitStruct = { - auctionId: bigint; - tokenId: bigint; + auctionId: Numeric; + tokenId: Numeric; tokenURI: string; - price: bigint; - fee: bigint; - step: bigint; - endTime: number; + price: Numeric; + fee: Numeric; + step: Numeric; + endTime: Numeric; participants: string[]; - shares: bigint[]; - deadline: number; + shares: Numeric[]; + deadline: Numeric; }; diff --git a/types/environment.ts b/types/environment.ts index ba59908..62d8418 100644 --- a/types/environment.ts +++ b/types/environment.ts @@ -1,6 +1,4 @@ -import type { Addressable, Signer as EthersSigner } from 'ethers'; - -export type UpgradeableContractConfig = { +type UpgradeableContractConfig = { proxy: string; impl: string; admin: string; @@ -34,9 +32,3 @@ export type RecordConfigCollection = CollectionData & Record>; export type ChainConfig = ConfigEnv & ConfigCollection; - -export type ContractConstructorArgs = (string | number | boolean | Uint8Array | Addressable)[]; - -export type AddressParam = string | Addressable; - -export type Signer = EthersSigner;