// SPDX-License-Identifier: MPL-2.0 pragma solidity ^0.8.17; import "forge-std/Test.sol"; import "@le7el/web3_crs/contracts/registry/CRSRegistry.sol"; import {AvatarControllerV1} from "src/controller/AvatarControllerV1.sol"; import {IdentityControllerV1} from "src/controller/IdentityControllerV1.sol"; import {ContributorControllerV1} from "src/controller/ContributorControllerV1.sol"; import {AvatarNFTV1} from "src/nft/AvatarNFTV1.sol"; import {IdentityNFTV1} from "src/nft/IdentityNFTV1.sol"; import {ContributorNFTV1} from "src/nft/ContributorNFTV1.sol"; import {LevelingResolver} from "src/resolver/LevelingResolver.sol"; contract TestWithDeployments is Test { uint256 internal constant VALIDATOR_KEY = 0x018e912fc034b4200224c4947242dd7c39f65b102bfbed6ea00e6ed6d77bf1f3; bytes32 internal l7lBasenode = 0xd0340a34011af087b374bbdc5136a48a841af1b55b0af1143ced23c89cf182c9; // ethers.js: utils.namehash("l7l") bytes32 internal l7lHash = 0x37372c33bd16695ac1a42f79a40d119a436fa3a44dc50a9117f2380fa5d80acc; // ethers.js: utils.keccak256(utils.toUtf8Bytes("l7l")) bytes32 internal avatarBasenode = 0x46f49b6a04b289d8ac4920f8a236e64e2689abdcf283566b399ff3bcfb6d967a; bytes32 internal avatarHash = 0xd1f86c93d831119ad98fe983e643a7431e4ac992e3ead6e3007f4dd1adf66343; bytes32 internal contributorBasenode = 0x9ccff02751c1b99e2c60d3b7d6db94c388e4e1828dd065231a867e115b8713e6; bytes32 internal contributorHash = 0xa0921f37fe9761e5e4ec5aa1bd4de740658170e3cf81b3920e874799011ab58b; CRSRegistry internal crs; LevelingResolver internal resolver; IdentityNFTV1 internal identityNFT; AvatarNFTV1 internal avatarNFT; ContributorNFTV1 internal contributorNFT; IdentityControllerV1 internal identityController; AvatarControllerV1 internal avatarController; ContributorControllerV1 internal contributorController; address internal validator = vm.addr(VALIDATOR_KEY); function test() public {} function deployAll(address admin) internal { crs = new CRSRegistry(); resolver = new LevelingResolver(crs); identityNFT = new IdentityNFTV1(crs, l7lBasenode); avatarNFT = new AvatarNFTV1(crs, avatarBasenode); contributorNFT = new ContributorNFTV1(crs, contributorBasenode); identityController = new IdentityControllerV1(identityNFT); avatarController = new AvatarControllerV1(avatarNFT); avatarController.toggleWhitelist(true); contributorController = new ContributorControllerV1(contributorNFT); contributorController.toggleWhitelist(true); identityNFT.addController(address(identityController)); avatarNFT.addController(address(avatarController)); contributorNFT.addController(address(contributorController)); crs.setSubnodeOwner(bytes32(0), l7lHash, admin); crs.setSubnodeOwner(bytes32(0), avatarHash, admin); crs.setSubnodeOwner(bytes32(0), contributorHash, admin); crs.setResolver(l7lBasenode, address(resolver)); crs.setResolver(avatarBasenode, address(resolver)); crs.setResolver(contributorBasenode, address(resolver)); resolver.setRoyalties(l7lBasenode, address(identityController), 0, address(0), address(0)); // free resolver.setRoyalties(avatarBasenode, address(avatarController), 3168873850, address(0), address(0)); // 1 gas coin per year resolver.setRoyalties(contributorBasenode, address(contributorController), 0, address(0), address(0)); // free crs.setSubnodeOwner(bytes32(0), l7lHash, address(identityNFT)); crs.setSubnodeOwner(bytes32(0), avatarHash, address(avatarNFT)); crs.setSubnodeOwner(bytes32(0), contributorHash, address(contributorNFT)); identityController.addValidator(validator); } function registerIdentityNFT(address user, bytes32 secret, uint256 duration, string memory name) internal { vm.deal(user, 1 ether); vm.warp(1657612849); bytes32 commitment = identityController.makeCommitmentWithConfig(name, user, secret, address(resolver), user); identityController.commit(name, commitment, whitelistIdentityName(name, user)); vm.warp(block.timestamp + 61); // low-level call to pass ether payment (bool result,) = address(identityController).call{value: 1 ether}(abi.encodeWithSignature( "registerWithConfig(string,address,uint256,bytes32,address,address)", name, user, duration, secret, address(resolver), user) ); assertTrue(result); assertTrue(identityNFT.ownerOf(uint256(keccak256(bytes(name)))) == user); } function registerAvatarNFT(address user, bytes32 secret, uint256 duration, string memory name) internal { vm.deal(user, 1 ether); vm.warp(1657612849); bytes32 commitment = avatarController.makeCommitmentWithConfig(name, user, secret, address(resolver), user); avatarController.commit(commitment); vm.warp(block.timestamp + 61); // low-level call to pass ether payment (bool result,) = address(avatarController).call{value: 1 ether}(abi.encodeWithSignature( "registerWithConfig(string,address,uint256,bytes32,address,address)", name, user, duration, secret, address(resolver), user) ); assertTrue(result); assertTrue(avatarNFT.ownerOf(uint256(keccak256(bytes(name)))) == user); } function registerContributorNFT(address user, bytes32 secret, uint256 duration, string memory name) internal { vm.deal(user, 1 ether); vm.warp(1657612849); bytes32 commitment = contributorController.makeCommitmentWithConfig(name, user, secret, address(resolver), user); contributorController.commit(commitment); vm.warp(block.timestamp + 61); // low-level call to pass ether payment (bool result,) = address(contributorController).call{value: 1 ether}(abi.encodeWithSignature( "registerWithConfig(string,address,uint256,bytes32,address,address)", name, user, duration, secret, address(resolver), user) ); assertTrue(result); assertTrue(contributorNFT.ownerOf(uint256(keccak256(bytes(name)))) == user); } function nameToAvatarNode(string memory _name) internal view returns (bytes32) { bytes32 _label = keccak256(bytes(_name)); bytes32 _baseNode = avatarController.baseNode(); return keccak256(abi.encodePacked(_baseNode, _label)); } function nameToContributorNode(string memory _name) internal view returns (bytes32) { bytes32 _label = keccak256(bytes(_name)); bytes32 _baseNode = contributorController.baseNode(); return keccak256(abi.encodePacked(_baseNode, _label)); } function whitelistIdentityName(string memory _name, address _user) internal view returns (bytes memory) { bytes32 _challenge = keccak256(abi.encode(identityController.getDomainSeparator(), _user, _name)); _challenge = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _challenge)); (uint8 v, bytes32 r, bytes32 s) = vm.sign(VALIDATOR_KEY, _challenge); return abi.encode(v, r, s); } }