From 5e27300da8248f500011b354014efb0359608643 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:11:07 +0300 Subject: [PATCH 1/6] integrating XERC721Upgradeable with the OZ ERC721Upgradeable underneath --- contracts/VoteEscrow.sol | 51 +++++++++++++++++--------------- contracts/XERC721Upgradeable.sol | 8 +++++ 2 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 contracts/XERC721Upgradeable.sol diff --git a/contracts/VoteEscrow.sol b/contracts/VoteEscrow.sol index e3fdf98..a3d0dcc 100644 --- a/contracts/VoteEscrow.sol +++ b/contracts/VoteEscrow.sol @@ -1,13 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.13; -import {IERC721, IERC721Metadata} from "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; -import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol"; import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; +import { IVotesUpgradeable } from "@openzeppelin/contracts-upgradeable/governance/utils/IVotesUpgradeable.sol"; import {IERC20} from "./interfaces/IERC20.sol"; import {IVoteEscrow} from "./interfaces/IVoteEscrow.sol"; +import {XERC721Upgradeable} from "./XERC721Upgradeable.sol"; /// @title Voting Escrow /// @notice veNFT implementation that escrows ERC-20 tokens in the form of an ERC-721 NFT @@ -19,7 +19,7 @@ import {IVoteEscrow} from "./interfaces/IVoteEscrow.sol"; /// @dev Vote weight decays linearly over time. Lock time cannot be more than `MAXTIME` (1 years). // TODO XERC20Upgradeable -contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradeable { +contract VoteEscrow is XERC721Upgradeable, IVotesUpgradeable, ReentrancyGuardUpgradeable { enum DepositType { DEPOSIT_FOR_TYPE, CREATE_LOCK_TYPE, @@ -109,8 +109,13 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea _disableInitializers(); } + function initialize(string memory name_, string memory symbol_) external initializer { + __ERC721_init(name_, symbol_); + } + function initialize(address token_addr, address _bridge, address _auctionsFactory) external initializer { __ReentrancyGuard_init(); + __ERC721_init("veIonic", "veION"); masterChainId = ARBITRUM_ONE; bridge = _bridge; @@ -136,10 +141,10 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea METADATA STORAGE ------------------------------------------------------------*/ - string constant public name = "veIonic"; - string constant public symbol = "veION"; - string constant public version = "1.0.0"; - uint8 constant public decimals = 18; + // string constant public name = "veIonic"; + // string constant public symbol = ; + string constant public version = "1.0.0"; + // uint8 constant public decimals = 18; function setTeam(address _team) external { require(msg.sender == team); @@ -148,7 +153,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @dev Returns current token URI metadata /// @param _tokenId Token ID to fetch URI for. - function tokenURI(uint _tokenId) external view returns (string memory) { + function tokenURI(uint _tokenId) public view override returns (string memory) { require(idToOwner[_tokenId] != address(0), "Query for nonexistent token"); LockedBalance memory _locked = locked[_tokenId]; // return IVeArtProxy(artProxy)._tokenURI(_tokenId,_balanceOfNFT(_tokenId, block.timestamp),_locked.end,uint(int256(_locked.amount))); @@ -166,7 +171,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @dev Returns the address of the owner of the NFT. /// @param _tokenId The identifier for an NFT. - function ownerOf(uint _tokenId) public view returns (address) { + function ownerOf(uint _tokenId) public view override returns (address) { return idToOwner[_tokenId]; } @@ -180,7 +185,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @dev Returns the number of NFTs owned by `_owner`. /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid. /// @param _owner Address for whom to query the balance. - function balanceOf(address _owner) external view returns (uint) { + function balanceOf(address _owner) public view override returns (uint) { return _balance(_owner); } @@ -198,14 +203,14 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @dev Get the approved address for a single NFT. /// @param _tokenId ID of the NFT to query the approval of. - function getApproved(uint _tokenId) external view returns (address) { + function getApproved(uint _tokenId) public view override returns (address) { return idToApprovals[_tokenId]; } /// @dev Checks if `_operator` is an approved operator for `_owner`. /// @param _owner The address that owns the NFTs. /// @param _operator The address that acts on behalf of the owner. - function isApprovedForAll(address _owner, address _operator) external view returns (bool) { + function isApprovedForAll(address _owner, address _operator) public view override returns (bool) { return (ownerToOperators[_owner])[_operator]; } @@ -219,7 +224,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// Throws if `_approved` is the current owner. (NOTE: This is not written the EIP) /// @param _approved Address to be approved for the given NFT ID. /// @param _tokenId ID of the token to be approved. - function approve(address _approved, uint _tokenId) public { + function approve(address _approved, uint _tokenId) public override { address owner = idToOwner[_tokenId]; // Throws if `_tokenId` is not a valid NFT require(owner != address(0)); @@ -240,7 +245,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @notice This works even if sender doesn't own any tokens at the time. /// @param _operator Address to add to the set of authorized operators. /// @param _approved True if the operators is approved, false to revoke approval. - function setApprovalForAll(address _operator, bool _approved) external { + function setApprovalForAll(address _operator, bool _approved) public override { // Throws if `_operator` is the `msg.sender` assert(_operator != msg.sender); ownerToOperators[msg.sender][_operator] = _approved; @@ -263,7 +268,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @param _spender address of the spender to query /// @param _tokenId uint ID of the token to be transferred /// @return bool whether the msg.sender is approved for the given token ID, is an operator of the owner, or is the owner of the token - function _isApprovedOrOwner(address _spender, uint _tokenId) internal view returns (bool) { + function _isApprovedOrOwner(address _spender, uint _tokenId) internal view override returns (bool) { address owner = idToOwner[_tokenId]; bool spenderIsOwner = owner == _spender; bool spenderIsApproved = _spender == idToApprovals[_tokenId]; @@ -318,7 +323,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea address _from, address _to, uint _tokenId - ) external { + ) public override { _transferFrom(_from, _to, _tokenId, msg.sender); } @@ -337,7 +342,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea address _from, address _to, uint _tokenId - ) external { + ) public override { safeTransferFrom(_from, _to, _tokenId, ""); } @@ -369,7 +374,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea address _to, uint _tokenId, bytes memory _data - ) public { + ) public override { _transferFrom(_from, _to, _tokenId, msg.sender); if (_isContract(_to)) { @@ -396,7 +401,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// @dev Interface identification is specified in ERC-165. /// @param _interfaceID Id of the interface - function supportsInterface(bytes4 _interfaceID) external view returns (bool) { + function supportsInterface(bytes4 _interfaceID) public view override returns (bool) { return supportedInterfaces[_interfaceID]; } @@ -443,8 +448,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea /// Throws if `_tokenId` is owned by someone. /// @param _to The address that will receive the minted tokens. /// @param _tokenId The token id to mint. - /// @return A boolean that indicates if the operation was successful. - function _mint(address _to, uint _tokenId) internal onlyBridge returns (bool) { + function _mint(address _to, uint _tokenId) internal override onlyBridge { // Throws if `_to` is zero address assert(_to != address(0)); // checkpoint for gov @@ -452,7 +456,6 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea // Add NFT. Throws if `_tokenId` is owned by someone _addTokenTo(_to, _tokenId); emit Transfer(address(0), _to, _tokenId); - return true; } /// @dev Remove a NFT from an index mapping to a given address @@ -498,7 +501,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea ownerToNFTokenCount[_from] -= 1; } - function _burn(uint _tokenId) internal onlyBridge { + function _burn(uint _tokenId) internal override onlyBridge { require(_isApprovedOrOwner(msg.sender, _tokenId), "caller is not owner nor approved"); address owner = ownerOf(_tokenId); @@ -1403,7 +1406,7 @@ contract VoteEscrow is IERC721, IERC721Metadata, IVotes, ReentrancyGuardUpgradea bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, - keccak256(bytes(name)), + keccak256(bytes(name())), keccak256(bytes(version)), block.chainid, address(this) diff --git a/contracts/XERC721Upgradeable.sol b/contracts/XERC721Upgradeable.sol new file mode 100644 index 0000000..cd97d44 --- /dev/null +++ b/contracts/XERC721Upgradeable.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.13; + +import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import { IERC721Upgradeable, IERC721MetadataUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; + +abstract contract XERC721Upgradeable is ERC721Upgradeable { +} \ No newline at end of file From 4aa314a3259fd8b0298b8b04938c623eb7e24b78 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:15:04 +0300 Subject: [PATCH 2/6] xerc20 contents into x721 --- contracts/XERC721Upgradeable.sol | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/contracts/XERC721Upgradeable.sol b/contracts/XERC721Upgradeable.sol index cd97d44..f685f9c 100644 --- a/contracts/XERC721Upgradeable.sol +++ b/contracts/XERC721Upgradeable.sol @@ -5,4 +5,63 @@ import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { IERC721Upgradeable, IERC721MetadataUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; abstract contract XERC721Upgradeable is ERC721Upgradeable { + event BridgeAdded(address indexed bridge); + event BridgeRemoved(address indexed bridge); + + mapping(address => bool) internal _whitelistedBridges; + + constructor() {} + + function initialize(address _owner, string memory _name, string memory _symbol) public initializer { + __XERC721_init(); + __ERC20_init(_name, _symbol); + __ERC20Permit_init(_name); + __ProposedOwnable_init(); + + // Set specified owner + _setOwner(_owner); + } + + function __XERC721_init() internal onlyInitializing { + __XERC721_init_unchained(); + } + + function __XERC721_init_unchained() internal onlyInitializing {} + + error XERC721__onlyBridge_notBridge(); + error XERC721__addBridge_alreadyAdded(); + error XERC721__removeBridge_alreadyRemoved(); + + modifier onlyBridge() { + if (!_whitelistedBridges[msg.sender]) { + revert XERC721__onlyBridge_notBridge(); + } + _; + } + + function addBridge(address _bridge) external onlyOwner { + if (_whitelistedBridges[_bridge]) { + revert XERC721__addBridge_alreadyAdded(); + } + emit BridgeAdded(_bridge); + _whitelistedBridges[_bridge] = true; + } + + function removeBridge(address _bridge) external onlyOwner { + if (!_whitelistedBridges[_bridge]) { + revert XERC721__removeBridge_alreadyRemoved(); + } + emit BridgeRemoved(_bridge); + _whitelistedBridges[_bridge] = false; + } + + function mint(address _to, uint256 _amount) public onlyBridge { + _mint(_to, _amount); + } + + function burn(address _from, uint256 _amount) public onlyBridge { + _burn(_from, _amount); + } + + uint256[49] private __GAP; // gap for upgrade safety } \ No newline at end of file From 04a833673b3fe64cbbe39c8260fbedcbf241d189 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:15:26 +0300 Subject: [PATCH 3/6] forge install: chain-abstraction-integration --- .gitmodules | 3 +++ lib/chain-abstraction-integration | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/chain-abstraction-integration diff --git a/.gitmodules b/.gitmodules index 62b27b6..d30f00b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "lib/solmate"] path = lib/solmate url = https://github.com/transmissions11/solmate +[submodule "lib/chain-abstraction-integration"] + path = lib/chain-abstraction-integration + url = https://github.com/connext/chain-abstraction-integration diff --git a/lib/chain-abstraction-integration b/lib/chain-abstraction-integration new file mode 160000 index 0000000..9eb6bc4 --- /dev/null +++ b/lib/chain-abstraction-integration @@ -0,0 +1 @@ +Subproject commit 9eb6bc4dc9e304214526b682a4b5a4c837069786 From 8e164d16238f94e7bebdf57998bd1be89e847b38 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 09:25:56 +0300 Subject: [PATCH 4/6] integrated the xerc721 --- contracts/VoteEscrow.sol | 14 ++++++-------- contracts/XERC721Upgradeable.sol | 20 ++++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/contracts/VoteEscrow.sol b/contracts/VoteEscrow.sol index a3d0dcc..d1443bc 100644 --- a/contracts/VoteEscrow.sol +++ b/contracts/VoteEscrow.sol @@ -92,7 +92,6 @@ contract VoteEscrow is XERC721Upgradeable, IVotesUpgradeable, ReentrancyGuardUpg uint256 public masterChainId; uint128 constant ARBITRUM_ONE = 42161; - address public bridge; address public auctionsFactory; modifier onlyOnMasterChain() { @@ -100,11 +99,6 @@ contract VoteEscrow is XERC721Upgradeable, IVotesUpgradeable, ReentrancyGuardUpg _; } - modifier onlyBridge() { - require(msg.sender == bridge, "only bridge"); - _; - } - constructor() { _disableInitializers(); } @@ -113,12 +107,16 @@ contract VoteEscrow is XERC721Upgradeable, IVotesUpgradeable, ReentrancyGuardUpg __ERC721_init(name_, symbol_); } - function initialize(address token_addr, address _bridge, address _auctionsFactory) external initializer { + function initialize(address token_addr, address _auctionsFactory) external initializer { __ReentrancyGuard_init(); + __Ownable_init(); + __Ownable2Step_init(); __ERC721_init("veIonic", "veION"); + __XERC721_init(); + + _transferOwnership(msg.sender); masterChainId = ARBITRUM_ONE; - bridge = _bridge; auctionsFactory = _auctionsFactory; token = token_addr; voter = msg.sender; diff --git a/contracts/XERC721Upgradeable.sol b/contracts/XERC721Upgradeable.sol index f685f9c..5dd557e 100644 --- a/contracts/XERC721Upgradeable.sol +++ b/contracts/XERC721Upgradeable.sol @@ -3,8 +3,9 @@ pragma solidity 0.8.13; import "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import { IERC721Upgradeable, IERC721MetadataUpgradeable } from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; +import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; -abstract contract XERC721Upgradeable is ERC721Upgradeable { +abstract contract XERC721Upgradeable is ERC721Upgradeable, Ownable2StepUpgradeable { event BridgeAdded(address indexed bridge); event BridgeRemoved(address indexed bridge); @@ -13,13 +14,12 @@ abstract contract XERC721Upgradeable is ERC721Upgradeable { constructor() {} function initialize(address _owner, string memory _name, string memory _symbol) public initializer { + __Ownable_init(); + __Ownable2Step_init(); + __ERC721_init(_name, _symbol); __XERC721_init(); - __ERC20_init(_name, _symbol); - __ERC20Permit_init(_name); - __ProposedOwnable_init(); - // Set specified owner - _setOwner(_owner); + _transferOwnership(_owner); } function __XERC721_init() internal onlyInitializing { @@ -55,12 +55,12 @@ abstract contract XERC721Upgradeable is ERC721Upgradeable { _whitelistedBridges[_bridge] = false; } - function mint(address _to, uint256 _amount) public onlyBridge { - _mint(_to, _amount); + function mint(address _to, uint256 _tokenId) public onlyBridge { + _mint(_to, _tokenId); } - function burn(address _from, uint256 _amount) public onlyBridge { - _burn(_from, _amount); + function burn(uint256 _tokenId) public onlyBridge { + _burn(_tokenId); } uint256[49] private __GAP; // gap for upgrade safety From 68e7aa79979757b38a9f1934dca7a16c47892515 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:53:13 +0300 Subject: [PATCH 5/6] prettier config --- .prettierrc | 16 ++++++++++++++++ contracts/VoteEscrow.sol | 1 - 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..e854a4a --- /dev/null +++ b/.prettierrc @@ -0,0 +1,16 @@ +{ + "overrides": [ + { + "files": ["*.sol", "*.ts", "*.tsx", ".js"], + "options": { + "printWidth": 120, + "tabWidth": 2, + "useTabs": false, + "singleQuote": false, + "bracketSpacing": true, + "explicitTypes": "always", + "trailingComma": "none" + } + } + ] +} diff --git a/contracts/VoteEscrow.sol b/contracts/VoteEscrow.sol index d1443bc..f2c4f10 100644 --- a/contracts/VoteEscrow.sol +++ b/contracts/VoteEscrow.sol @@ -18,7 +18,6 @@ import {XERC721Upgradeable} from "./XERC721Upgradeable.sol"; /// @author Modified from THENA (https://github.com/ThenafiBNB/THENA-Contracts/blob/main/contracts/VotingEscrow.sol) /// @dev Vote weight decays linearly over time. Lock time cannot be more than `MAXTIME` (1 years). -// TODO XERC20Upgradeable contract VoteEscrow is XERC721Upgradeable, IVotesUpgradeable, ReentrancyGuardUpgradeable { enum DepositType { DEPOSIT_FOR_TYPE, From 61a8eb3ec73f07f6cdeba4c4325c23d15cb7e6f6 Mon Sep 17 00:00:00 2001 From: Veliko Minkov <2662912+vminkov@users.noreply.github.com> Date: Wed, 9 Aug 2023 13:59:31 +0300 Subject: [PATCH 6/6] installing prettier --- package.json | 12 ++++++++++++ yarn.lock | 25 +++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 058acda..b718405 100644 --- a/package.json +++ b/package.json @@ -30,5 +30,17 @@ "mocha": "^9.2.2", "solidity-coverage": "^0.7.20", "ts-node": "^10.9.1" + }, + "scripts": { + "forge": "forge", + "prettier": "prettier --write --plugin=prettier-plugin-solidity 'contracts/**/*.sol' --config .prettierrc", + "lint": "prettier --list-different 'contracts/**/*.sol'" + }, + "files": [ + "contracts" + ], + "devDependencies": { + "prettier": "^2.6.2", + "prettier-plugin-solidity": "^1.0.0-beta.19" } } diff --git a/yarn.lock b/yarn.lock index 4ba569c..766f82a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1171,6 +1171,13 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@solidity-parser/parser@^0.16.0": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" + integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== + dependencies: + antlr4ts "^0.5.0-alpha.4" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -7953,7 +7960,16 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== -prettier@^2.1.2: +prettier-plugin-solidity@^1.0.0-beta.19: + version "1.1.3" + resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.1.3.tgz#9a35124f578404caf617634a8cab80862d726cba" + integrity sha512-fQ9yucPi2sBbA2U2Xjh6m4isUTJ7S7QLc/XDDsktqqxYfTwdYKJ0EnnywXHwCGAaYbQNK+HIYPL1OemxuMsgeg== + dependencies: + "@solidity-parser/parser" "^0.16.0" + semver "^7.3.8" + solidity-comments-extractor "^0.0.7" + +prettier@^2.1.2, prettier@^2.6.2: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== @@ -8682,7 +8698,7 @@ semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4: +semver@^7.3.4, semver@^7.3.8: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -8967,6 +8983,11 @@ solidity-ast@^0.4.15: resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.49.tgz#ecba89d10c0067845b7848c3a3e8cc61a4fc5b82" integrity sha512-Pr5sCAj1SFqzwFZw1HPKSq0PehlQNdM8GwKyAVYh2DOn7/cCK8LUKD1HeHnKtTgBW7hi9h4nnnan7hpAg5RhWQ== +solidity-comments-extractor@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/solidity-comments-extractor/-/solidity-comments-extractor-0.0.7.tgz#99d8f1361438f84019795d928b931f4e5c39ca19" + integrity sha512-wciNMLg/Irp8OKGrh3S2tfvZiZ0NEyILfcRCXCD4mp7SgK/i9gzLfhY2hY7VMCQJ3kH9UB9BzNdibIVMchzyYw== + solidity-coverage@^0.7.20: version "0.7.22" resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.7.22.tgz#168f414be4c0f5303addcf3ab9714cf64f72c080"