feat: design ens verification flow (#193)
* wip: add base solidity functions to try ens validation * chore: add hardhat fork setup with env variable * wip: setup ens verification for FleekERC721 * wip: add ens namehash generation * chore: gas report setting * feat: add ens verification on setTokenENS function * test: hardhat transfer ens owner to set new ens * test: fix foundry tests to enable ens validation * refactor: change back ens to calldata and split out a public function for namehash testing * refactor: move FleekENS.sol to util folder * test: add ens validation tests for not owner attempts * chore: add mainnet api key env in ci * chore: fix .env.example * fix: remove extra unused file
This commit is contained in:
parent
2225b301ff
commit
83cd36dfc3
|
|
@ -11,6 +11,8 @@ on:
|
|||
jobs:
|
||||
test-contracts:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
MAINNET_API_KEY: ${{ secrets.MAINNET_API_KEY }}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
|
|
|
|||
|
|
@ -9,4 +9,13 @@ PRIVATE_KEY=
|
|||
POLYSCAN_API=https://mumbai.polygonscan.com/
|
||||
|
||||
# The address of the deployed contract on the blockchain
|
||||
CONTRACT_ADDRESS=
|
||||
CONTRACT_ADDRESS=
|
||||
|
||||
# Alchemy or Infura API key to fork the mainnet on tests (e.g. https://eth-mainnet.g.alchemy.com/v2/your-api-key)
|
||||
MAINNET_API_KEY=
|
||||
|
||||
# Enable gas report on hardhat tests
|
||||
REPORT_GAS=true
|
||||
|
||||
# The CoinMarketCap API key to get the price of the token for gas report
|
||||
COINMARKETCAP_KEY=
|
||||
|
|
@ -2,10 +2,11 @@
|
|||
cache
|
||||
artifacts
|
||||
deployments/hardhat
|
||||
gas-report
|
||||
|
||||
# Foundry
|
||||
out
|
||||
forge-cache
|
||||
|
||||
# OpenZeppelin
|
||||
.openzeppelin/unknown-*.json
|
||||
.openzeppelin/unknown-*.json
|
||||
|
|
@ -9,6 +9,7 @@ import "./FleekAccessControl.sol";
|
|||
import "./FleekBilling.sol";
|
||||
import "./FleekPausable.sol";
|
||||
import "./FleekAccessPoints.sol";
|
||||
import "./util/FleekENS.sol";
|
||||
import "./util/FleekStrings.sol";
|
||||
import "./IERCX.sol";
|
||||
|
||||
|
|
@ -104,7 +105,7 @@ contract FleekERC721 is
|
|||
string memory name,
|
||||
string memory description,
|
||||
string memory externalURL,
|
||||
string memory ENS,
|
||||
string calldata ens,
|
||||
string memory commitHash,
|
||||
string memory gitRepository,
|
||||
string memory logo,
|
||||
|
|
@ -112,6 +113,7 @@ contract FleekERC721 is
|
|||
bool accessPointAutoApproval,
|
||||
address verifier
|
||||
) public payable requirePayment(Billing.Mint) returns (uint256) {
|
||||
FleekENS.requireENSOwner(ens);
|
||||
uint256 tokenId = _appIds;
|
||||
_mint(to, tokenId);
|
||||
|
||||
|
|
@ -121,7 +123,7 @@ contract FleekERC721 is
|
|||
app.name = name;
|
||||
app.description = description;
|
||||
app.externalURL = externalURL;
|
||||
app.ENS = ENS;
|
||||
app.ENS = ens;
|
||||
app.logo = logo;
|
||||
app.color = color;
|
||||
|
||||
|
|
@ -134,7 +136,7 @@ contract FleekERC721 is
|
|||
name,
|
||||
description,
|
||||
externalURL,
|
||||
ENS,
|
||||
ens,
|
||||
commitHash,
|
||||
gitRepository,
|
||||
logo,
|
||||
|
|
@ -274,8 +276,9 @@ contract FleekERC721 is
|
|||
*/
|
||||
function setTokenENS(
|
||||
uint256 tokenId,
|
||||
string memory _tokenENS
|
||||
string calldata _tokenENS
|
||||
) public virtual requireTokenRole(tokenId, TokenRoles.Controller) {
|
||||
FleekENS.requireENSOwner(_tokenENS);
|
||||
_requireMinted(tokenId);
|
||||
_apps[tokenId].ENS = _tokenENS;
|
||||
emit MetadataUpdate(tokenId, "ENS", _tokenENS, msg.sender);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.7;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import {ENS} from "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
|
||||
import {Resolver} from "@ensdomains/ens-contracts/contracts/resolvers/Resolver.sol";
|
||||
|
||||
error MustBeENSOwner();
|
||||
|
||||
library FleekENS {
|
||||
ENS internal constant _ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
|
||||
|
||||
/**
|
||||
* @dev Reverts if the sender is not the owner of the ENS node.
|
||||
*/
|
||||
function requireENSOwner(string calldata name) internal view {
|
||||
if (_ens.owner(namehash(bytes(name), 0)) != msg.sender) revert MustBeENSOwner();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Processes the name and returns the ENS node hash.
|
||||
*/
|
||||
function namehash(bytes calldata name, uint256 index) internal view returns (bytes32) {
|
||||
for (uint256 i = index; i < name.length; i++) {
|
||||
if (name[i] == ".") {
|
||||
return keccak256(abi.encodePacked(namehash(name, i + 1), keccak256(name[index:i])));
|
||||
}
|
||||
}
|
||||
return keccak256(abi.encodePacked(bytes32(0x0), keccak256(name[index:name.length])));
|
||||
}
|
||||
}
|
||||
|
|
@ -4,3 +4,8 @@ out = 'out'
|
|||
libs = ['node_modules', 'lib']
|
||||
test = 'test/foundry'
|
||||
cache_path = 'forge-cache'
|
||||
via_ir = true
|
||||
|
||||
[rpc_endpoints]
|
||||
mainnet = "${MAINNET_API_KEY}"
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ const {
|
|||
PRIVATE_KEY,
|
||||
REPORT_GAS,
|
||||
POLYGONSCAN_KEY,
|
||||
MAINNET_API_KEY,
|
||||
COINMARKETCAP_KEY,
|
||||
} = process.env;
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
|
|
@ -25,6 +27,12 @@ const config: HardhatUserConfig = {
|
|||
networks: {
|
||||
hardhat: {
|
||||
chainId: 31337,
|
||||
forking: MAINNET_API_KEY
|
||||
? {
|
||||
url: MAINNET_API_KEY,
|
||||
blockNumber: 16876149,
|
||||
}
|
||||
: undefined,
|
||||
},
|
||||
mumbai: {
|
||||
url: API_URL,
|
||||
|
|
@ -35,9 +43,9 @@ const config: HardhatUserConfig = {
|
|||
gasReporter: {
|
||||
enabled: REPORT_GAS === 'true' || false,
|
||||
currency: 'USD',
|
||||
outputFile: 'gas-report.txt',
|
||||
outputFile: 'gas-report',
|
||||
noColors: true,
|
||||
// coinmarketcap: process.env.COINMARKETCAP_API_KEY,
|
||||
coinmarketcap: COINMARKETCAP_KEY,
|
||||
},
|
||||
contractSizer: {
|
||||
runOnCompile: false,
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
"description": "",
|
||||
"private": "false",
|
||||
"scripts": {
|
||||
"test": "hardhat test && forge test --via-ir",
|
||||
"test:foundry": "forge test --via-ir -vvv",
|
||||
"test": "yarn test:hardhat && yarn test:foundry",
|
||||
"test:foundry": "forge test -vvv --fork-url mainnet --fork-block-number 16876149",
|
||||
"test:hardhat": "hardhat test",
|
||||
"format": "prettier --write \"./**/*.{js,json,sol,ts}\"",
|
||||
"node:hardhat": "hardhat node",
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
},
|
||||
"homepage": "https://github.com/fleekxyz/non-fungible-apps#readme",
|
||||
"devDependencies": {
|
||||
"@ensdomains/ens-contracts": "^0.0.20",
|
||||
"@ensdomains/eth-ens-namehash": "^2.0.15",
|
||||
"@nomicfoundation/hardhat-chai-matchers": "^1.0.5",
|
||||
"@nomicfoundation/hardhat-network-helpers": "^1.0.7",
|
||||
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
|
||||
|
|
|
|||
|
|
@ -162,6 +162,7 @@ contract Test_FleekERC721_AccessControl is Test_FleekERC721_Base, Test_FleekERC7
|
|||
|
||||
function test_mint() public {
|
||||
// Anyone can mint
|
||||
transferENS(TestConstants.APP_ENS, anyAddress);
|
||||
vm.startPrank(anyAddress);
|
||||
mintDefault(address(99));
|
||||
vm.stopPrank();
|
||||
|
|
@ -201,7 +202,7 @@ contract Test_FleekERC721_AccessControl is Test_FleekERC721_Base, Test_FleekERC7
|
|||
}
|
||||
|
||||
function test_setTokenENS() public {
|
||||
string memory ens = "ens";
|
||||
string memory ens = "ens.eth";
|
||||
|
||||
// ColletionOwner
|
||||
vm.prank(collectionOwner);
|
||||
|
|
@ -214,10 +215,12 @@ contract Test_FleekERC721_AccessControl is Test_FleekERC721_Base, Test_FleekERC7
|
|||
CuT.setTokenENS(tokenId, ens);
|
||||
|
||||
// TokenOwner
|
||||
transferENS(ens, tokenOwner);
|
||||
vm.prank(tokenOwner);
|
||||
CuT.setTokenENS(tokenId, ens);
|
||||
|
||||
// TokenController
|
||||
transferENS(ens, tokenController);
|
||||
vm.prank(tokenController);
|
||||
CuT.setTokenENS(tokenId, ens);
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,32 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
import "./TestBase.sol";
|
||||
import {Utils} from "./Utils.sol";
|
||||
|
||||
contract Test_FleekERC721_ENS is Test_FleekERC721_Base {
|
||||
function expectRevertWithMustBeENSOwner() internal {
|
||||
vm.expectRevert(MustBeENSOwner.selector);
|
||||
}
|
||||
|
||||
function setUp() public {
|
||||
baseSetUp();
|
||||
}
|
||||
|
||||
function testFuzz_cannotMintIfNotENSOwner(address account) public {
|
||||
vm.assume(deployer != account);
|
||||
vm.prank(account);
|
||||
expectRevertWithMustBeENSOwner();
|
||||
mintDefault(account);
|
||||
}
|
||||
|
||||
function testFuzz_cannotSetTokenENSIfNotENSOwner(address account) public {
|
||||
vm.assume(deployer != account);
|
||||
mintDefault(account);
|
||||
|
||||
vm.prank(account);
|
||||
expectRevertWithMustBeENSOwner();
|
||||
CuT.setTokenENS(0, TestConstants.APP_ENS);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ contract Test_FleekERC721_GetToken is Test_FleekERC721_Base {
|
|||
string memory name,
|
||||
string memory description,
|
||||
string memory externalURL,
|
||||
string memory ENS,
|
||||
string memory ens,
|
||||
uint256 currentBuild,
|
||||
string memory logo,
|
||||
uint24 color
|
||||
|
|
@ -28,7 +28,7 @@ contract Test_FleekERC721_GetToken is Test_FleekERC721_Base {
|
|||
assertEq(externalURL, TestConstants.APP_EXTERNAL_URL);
|
||||
assertEq(logo, TestConstants.LOGO_0);
|
||||
assertEq(color, TestConstants.APP_COLOR);
|
||||
assertEq(ENS, TestConstants.APP_ENS);
|
||||
assertEq(ens, TestConstants.APP_ENS);
|
||||
assertEq(currentBuild, 0);
|
||||
}
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ contract Test_FleekERC721_GetToken is Test_FleekERC721_Base {
|
|||
CuT.setTokenName(tokenId, newAppName);
|
||||
CuT.setTokenDescription(tokenId, newDescription);
|
||||
CuT.setTokenExternalURL(tokenId, newExternalURL);
|
||||
transferENS(newENS, deployer);
|
||||
CuT.setTokenENS(tokenId, newENS);
|
||||
CuT.setTokenBuild(tokenId, newCommitHash, newRepository);
|
||||
CuT.setTokenLogoAndColor(tokenId, newLogo, newColor);
|
||||
|
|
@ -53,7 +54,7 @@ contract Test_FleekERC721_GetToken is Test_FleekERC721_Base {
|
|||
string memory name,
|
||||
string memory description,
|
||||
string memory externalURL,
|
||||
string memory ENS,
|
||||
string memory ens,
|
||||
uint256 currentBuild,
|
||||
string memory logo,
|
||||
uint24 color
|
||||
|
|
@ -63,7 +64,7 @@ contract Test_FleekERC721_GetToken is Test_FleekERC721_Base {
|
|||
assertEq(externalURL, newExternalURL);
|
||||
assertEq(logo, newLogo);
|
||||
assertEq(color, newColor);
|
||||
assertEq(ENS, newENS);
|
||||
assertEq(ens, newENS);
|
||||
assertEq(currentBuild, 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
|||
|
||||
function test_mintTwoTokensForTwoAddresses() public {
|
||||
uint256 firstMint = mintDefault(deployer);
|
||||
|
||||
transferENS("fleek.eth", deployer);
|
||||
uint256 secondMint = CuT.mint(
|
||||
address(12),
|
||||
"Different App Name",
|
||||
|
|
@ -45,6 +47,7 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
|||
}
|
||||
|
||||
function test_mintWithAutoApprovalAPsOn() public {
|
||||
transferENS("fleek.eth", deployer);
|
||||
uint256 mint = CuT.mint(
|
||||
address(12),
|
||||
"Different App Name",
|
||||
|
|
@ -83,6 +86,7 @@ contract Test_FleekERC721_Mint is Test_FleekERC721_Base {
|
|||
bool autoApprovalAp
|
||||
) public {
|
||||
vm.assume(to != address(0));
|
||||
transferENS(ens, deployer);
|
||||
uint256 tokenId = CuT.mint(
|
||||
to,
|
||||
appName,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ pragma solidity ^0.8.17;
|
|||
import "forge-std/Test.sol";
|
||||
import "contracts/FleekERC721.sol";
|
||||
import {TestConstants} from "./Constants.sol";
|
||||
import {Utils} from "./Utils.sol";
|
||||
|
||||
abstract contract Test_FleekERC721_Assertions is Test {
|
||||
function expectRevertWithTokenRole(uint256 tokenId, FleekAccessControl.TokenRoles role) public {
|
||||
|
|
@ -47,6 +48,7 @@ abstract contract Test_FleekERC721_Assertions is Test {
|
|||
abstract contract Test_FleekERC721_Base is Test, Test_FleekERC721_Assertions {
|
||||
FleekERC721 internal CuT; // Contract Under Test
|
||||
address internal deployer;
|
||||
ENS internal constant _ens = ENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e);
|
||||
|
||||
function deployUninitialized() internal returns (FleekERC721) {
|
||||
FleekERC721 _contract = new FleekERC721();
|
||||
|
|
@ -59,6 +61,15 @@ abstract contract Test_FleekERC721_Base is Test, Test_FleekERC721_Assertions {
|
|||
CuT = deployUninitialized();
|
||||
CuT.initialize("Test Contract", "FLKAPS", new uint256[](0));
|
||||
deployer = address(this);
|
||||
transferENS(TestConstants.APP_ENS, deployer);
|
||||
}
|
||||
|
||||
function transferENS(string memory ens, address newOwner) public {
|
||||
bytes32 node = Utils.namehash(ens);
|
||||
address ensOwner = _ens.owner(node);
|
||||
vm.deal(ensOwner, 100000000000);
|
||||
vm.prank(ensOwner);
|
||||
_ens.setOwner(node, newOwner);
|
||||
}
|
||||
|
||||
function mintDefault(address to) internal returns (uint256) {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,16 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.17;
|
||||
|
||||
import {FleekENS} from "contracts/util/FleekENS.sol";
|
||||
|
||||
library Utils {
|
||||
/**
|
||||
* @dev This function is copyed from `FleekENS.sol`.
|
||||
* It changes the `internal` modifier to `public` allowing it
|
||||
* to be used in tests applying memory values
|
||||
*/
|
||||
function namehash(string calldata name) public view returns (bytes32) {
|
||||
return FleekENS.namehash(bytes(name), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Errors, transferENSNode } from './helpers';
|
||||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
const { MintParams } = TestConstants;
|
||||
|
||||
describe('FleekERC721.ENS', () => {
|
||||
let fixture: Awaited<ReturnType<typeof Fixtures.default>>;
|
||||
|
||||
beforeEach(async () => {
|
||||
fixture = await loadFixture(Fixtures.default);
|
||||
});
|
||||
|
||||
it('should not allow mint if not ENS owner', async () => {
|
||||
const { contract, owner } = fixture;
|
||||
|
||||
await expect(
|
||||
contract.mint(
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
MintParams.externalUrl,
|
||||
'app.eth',
|
||||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings,
|
||||
owner.address
|
||||
)
|
||||
).to.be.revertedWithCustomError(contract, Errors.MustBeENSOwner);
|
||||
});
|
||||
|
||||
it('should not allow set ENS if not ENS owner', async () => {
|
||||
const { contract, owner } = fixture;
|
||||
|
||||
await transferENSNode('app.eth', owner);
|
||||
|
||||
await contract.mint(
|
||||
owner.address,
|
||||
MintParams.name,
|
||||
MintParams.description,
|
||||
MintParams.externalUrl,
|
||||
'app.eth',
|
||||
MintParams.commitHash,
|
||||
MintParams.gitRepository,
|
||||
MintParams.logo,
|
||||
MintParams.color,
|
||||
MintParams.accessPointAutoApprovalSettings,
|
||||
owner.address
|
||||
);
|
||||
|
||||
await expect(
|
||||
contract.setTokenENS(0, 'subdomain.app.eth')
|
||||
).to.be.revertedWithCustomError(contract, Errors.MustBeENSOwner);
|
||||
});
|
||||
});
|
||||
|
|
@ -15,4 +15,5 @@ export const Errors = Object.freeze({
|
|||
PausableIsSetTo: 'PausableIsSetTo',
|
||||
ThereIsNoTokenMinted: 'ThereIsNoTokenMinted',
|
||||
RequiredPayment: 'RequiredPayment',
|
||||
MustBeENSOwner: 'MustBeENSOwner',
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
import { ethers, upgrades } from 'hardhat';
|
||||
import { TestConstants } from './constants';
|
||||
import { transferENSNode } from './utils';
|
||||
|
||||
export abstract class Fixtures {
|
||||
static async default() {
|
||||
// Contracts are deployed using the first signer/account by default
|
||||
const [owner, otherAccount] = await ethers.getSigners();
|
||||
|
||||
await transferENSNode(TestConstants.MintParams.ens, owner);
|
||||
|
||||
const libraries = {
|
||||
FleekSVG: (await (await ethers.getContractFactory('FleekSVG')).deploy())
|
||||
.address,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers';
|
||||
import { ethers, upgrades } from 'hardhat';
|
||||
import { TestConstants } from './constants';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const namehash = require('@ensdomains/eth-ens-namehash');
|
||||
|
||||
export const parseTokenURI = (tokenURI: string) => {
|
||||
const tokenURIDecoded = Buffer.from(
|
||||
tokenURI.replace('data:application/json;base64,', ''),
|
||||
|
|
@ -6,3 +13,25 @@ export const parseTokenURI = (tokenURI: string) => {
|
|||
|
||||
return JSON.parse(tokenURIDecoded);
|
||||
};
|
||||
|
||||
export const getENSNode = (name: string) => {
|
||||
return namehash.hash(namehash.normalize(name));
|
||||
};
|
||||
|
||||
export const transferENSNode = async (name: string, to: SignerWithAddress) => {
|
||||
const ens = await ethers.getContractAt(
|
||||
'ENS',
|
||||
'0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'
|
||||
);
|
||||
|
||||
const ensNode = getENSNode(name);
|
||||
|
||||
const ensOwner = await ethers.getImpersonatedSigner(await ens.owner(ensNode));
|
||||
|
||||
await to.sendTransaction({
|
||||
to: ensOwner.address,
|
||||
value: ethers.utils.parseEther('1000'),
|
||||
});
|
||||
|
||||
await ens.connect(ensOwner).setOwner(ensNode, to.address);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { loadFixture } from '@nomicfoundation/hardhat-network-helpers';
|
||||
import { expect } from 'chai';
|
||||
import { TestConstants, Fixtures, Events } from './helpers';
|
||||
import { TestConstants, Fixtures, Events, transferENSNode } from './helpers';
|
||||
|
||||
const {
|
||||
Logos: { 1: Logo1 },
|
||||
|
|
@ -25,9 +25,11 @@ describe('FleekERC721.UpdateProperties', () => {
|
|||
it('should emit event for ens change', async () => {
|
||||
const { contract, tokenId, owner } = fixture;
|
||||
|
||||
await expect(contract.setTokenENS(tokenId, 'app.eth'))
|
||||
await transferENSNode('subdomain.app.eth', owner);
|
||||
|
||||
await expect(contract.setTokenENS(tokenId, 'subdomain.app.eth'))
|
||||
.to.emit(contract, Events.MetadataUpdate.string)
|
||||
.withArgs(tokenId, 'ENS', 'app.eth', owner.address);
|
||||
.withArgs(tokenId, 'ENS', 'subdomain.app.eth', owner.address);
|
||||
});
|
||||
|
||||
it('should emit event for name change', async () => {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,33 @@
|
|||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@ensdomains/buffer@^0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@ensdomains/buffer/-/buffer-0.1.1.tgz#6c275ba7e457e935405b67876f1f0d980c8baa63"
|
||||
integrity sha512-92SfSiNS8XorgU7OUBHo/i1ZU7JV7iz/6bKuLPNVsMxV79/eI7fJR6jfJJc40zAHjs3ha+Xo965Idomlq3rqnw==
|
||||
|
||||
"@ensdomains/ens-contracts@^0.0.20":
|
||||
version "0.0.20"
|
||||
resolved "https://registry.yarnpkg.com/@ensdomains/ens-contracts/-/ens-contracts-0.0.20.tgz#346eac70d666a7864142287ce1759b0f44bd8a5e"
|
||||
integrity sha512-lAHQBVj2WtgbchcrE8ZuFI6DFq+O33wkLAGqsO2gcnn0EUJb65OJIdTqUfvfULKGJjkB2pyHfS/RgMSIW6h1Pw==
|
||||
dependencies:
|
||||
"@ensdomains/buffer" "^0.1.1"
|
||||
"@ensdomains/solsha1" "0.0.3"
|
||||
"@openzeppelin/contracts" "^4.1.0"
|
||||
dns-packet "^5.3.0"
|
||||
|
||||
"@ensdomains/eth-ens-namehash@^2.0.15":
|
||||
version "2.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@ensdomains/eth-ens-namehash/-/eth-ens-namehash-2.0.15.tgz#5e5f2f24ba802aff8bc19edd822c9a11200cdf4a"
|
||||
integrity sha512-JRDFP6+Hczb1E0/HhIg0PONgBYasfGfDheujmfxaZaAv/NAH4jE6Kf48WbqfRZdxt4IZI3jl3Ri7sZ1nP09lgw==
|
||||
|
||||
"@ensdomains/solsha1@0.0.3":
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@ensdomains/solsha1/-/solsha1-0.0.3.tgz#fd479da9d40aadb59ff4fb4ec50632e7d2275a83"
|
||||
integrity sha512-uhuG5LzRt/UJC0Ux83cE2rCKwSleRePoYdQVcqPN1wyf3/ekMzT/KZUF9+v7/AG5w9jlMLCQkUM50vfjr0Yu9Q==
|
||||
dependencies:
|
||||
hash-test-vectors "^1.3.2"
|
||||
|
||||
"@ethereumjs/common@2.5.0":
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268"
|
||||
|
|
@ -398,6 +425,11 @@
|
|||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@leichtgewicht/ip-codec@^2.0.1":
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b"
|
||||
integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==
|
||||
|
||||
"@metamask/eth-sig-util@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088"
|
||||
|
|
@ -700,6 +732,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.1.tgz#363f7dd08f25f8f77e16d374350c3d6b43340a7a"
|
||||
integrity sha512-1wTv+20lNiC0R07jyIAbHU7TNHKRwGiTGRfiNnA8jOWjKT98g5OgLpYWOi40Vgpk8SPLA9EvfJAbAeIyVn+7Bw==
|
||||
|
||||
"@openzeppelin/contracts@^4.1.0":
|
||||
version "4.8.2"
|
||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.2.tgz#d815ade0027b50beb9bcca67143c6bcc3e3923d6"
|
||||
integrity sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g==
|
||||
|
||||
"@openzeppelin/contracts@^4.7.3":
|
||||
version "4.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4"
|
||||
|
|
@ -2155,6 +2192,13 @@ dir-glob@^3.0.1:
|
|||
dependencies:
|
||||
path-type "^4.0.0"
|
||||
|
||||
dns-packet@^5.3.0:
|
||||
version "5.4.0"
|
||||
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b"
|
||||
integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g==
|
||||
dependencies:
|
||||
"@leichtgewicht/ip-codec" "^2.0.1"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||
|
|
@ -3302,6 +3346,11 @@ hash-base@^3.0.0:
|
|||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
hash-test-vectors@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hash-test-vectors/-/hash-test-vectors-1.3.2.tgz#f050fde1aff46ec28dcf4f70e4e3238cd5000f4c"
|
||||
integrity sha512-PKd/fitmsrlWGh3OpKbgNLE04ZQZsvs1ZkuLoQpeIKuwx+6CYVNdW6LaPIS1QAdZvV40+skk0w4YomKnViUnvQ==
|
||||
|
||||
hash.js@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846"
|
||||
|
|
|
|||
Loading…
Reference in New Issue