Skip to content

Commit

Permalink
wip: tests
Browse files Browse the repository at this point in the history
  • Loading branch information
3esmit committed Jun 7, 2024
1 parent 4782d00 commit 2436e3f
Show file tree
Hide file tree
Showing 7 changed files with 826 additions and 29 deletions.
100 changes: 100 additions & 0 deletions contracts/test/MerkleTree.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.19 <0.9.0;

library MerkleTree {
error ElementDoesNotExist();

function combinedHash(bytes32 first, bytes32 second) internal pure returns (bytes32) {
if (first == bytes32(0)) {
return second;
}
if (second == bytes32(0)) {
return first;
}
return keccak256(abi.encodePacked(first, second));
}

function getLayers(bytes32[] memory elements) internal pure returns (bytes32[][] memory) {
if (elements.length == 0) {
bytes32[][] memory empty = new bytes32[][](1);
empty ;
return empty;
}

uint256 layerCount = 1;
uint256 remainingElements = elements.length;
while (remainingElements > 1) {
layerCount++;
remainingElements = (remainingElements + 1) / 2;
}

bytes32[][] memory layers = new bytes32[][](layerCount);
layers[0] = elements;

for (uint256 i = 1; i < layerCount; i++) {
layers[i] = getNextLayer(layers[i - 1]);
}

return layers;
}

function getNextLayer(bytes32[] memory elements) internal pure returns (bytes32[] memory) {
uint256 nextLayerLength = (elements.length + 1) / 2;
bytes32[] memory nextLayer = new bytes32[](nextLayerLength);

for (uint256 i = 0; i < elements.length; i += 2) {
bytes32 first = elements[i];
bytes32 second = (i + 1 < elements.length) ? elements[i + 1] : bytes32(0);
nextLayer[i / 2] = combinedHash(first, second);
}

return nextLayer;
}

function getRoot(bytes32[] memory elements) internal pure returns (bytes32) {
bytes32[][] memory layers = getLayers(elements);
return layers[layers.length - 1][0];
}

function getProof(bytes32[] memory elements, bytes32 element) internal pure returns (bytes32[] memory) {
uint256 index = indexOf(elements, element);
if(index == type(uint256).max){
revert ElementDoesNotExist();
}

bytes32[][] memory layers = getLayers(elements);
uint256 proofLength = layers.length - 1;
bytes32[] memory proof = new bytes32[](proofLength);

for (uint256 i = 0; i < proofLength; i++) {
uint256 pairIndex = (index % 2 == 0) ? index + 1 : index - 1;
if (pairIndex < layers[i].length) {
proof[i] = layers[i][pairIndex];
} else {
proof[i] = bytes32(0);
}
index = index / 2;
}

return proof;
}

function indexOf(bytes32[] memory elements, bytes32 element) internal pure returns (uint256) {
for (uint256 i = 0; i < elements.length; i++) {
if (elements[i] == element) {
return i;
}
}
return type(uint256).max;
}

function verifyProof(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) {
bytes32 computedHash = leaf;

for (uint256 i = 0; i < proof.length; i++) {
computedHash = combinedHash(computedHash, proof[i]);
}

return computedHash == root;
}
}
6 changes: 3 additions & 3 deletions script/Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.19 <=0.9.0;

import { Foo } from "../src/Foo.sol";
import { UsernameRegistrar } from "../contracts/registry/UsernameRegistrar.sol";
import { BaseScript } from "./Base.s.sol";
import { DeploymentConfig } from "./DeploymentConfig.s.sol";

contract Deploy is BaseScript {
function run() public returns (Foo foo, DeploymentConfig deploymentConfig) {
function run() public returns (UsernameRegistrar registrar, DeploymentConfig deploymentConfig) {
deploymentConfig = new DeploymentConfig(broadcaster);
foo = new Foo();
//registrar = new UsernameRegistrar();
}
}
160 changes: 160 additions & 0 deletions script/DeployTest.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.19 <=0.9.0;

import { BaseScript } from "./Base.s.sol";
import { DeploymentTestConfig } from "./DeploymentTestConfig.s.sol";
import { TestToken } from "../contracts/token/TestToken.sol";
import { ENSRegistry } from "../contracts/ens/ENSRegistry.sol";
import { PublicResolver } from "../contracts/ens/PublicResolver.sol";
import { UsernameRegistrar } from "../contracts/registry/UsernameRegistrar.sol";
import { UpdatedUsernameRegistrar } from "../contracts/mocks/UpdatedUsernameRegistrar.sol";
import { DummyUsernameRegistrar } from "../contracts/mocks/DummyUsernameRegistrar.sol";
import { UpdatedDummyUsernameRegistrar } from "../contracts/mocks/UpdatedDummyUsernameRegistrar.sol";
import { Dummy2UsernameRegistrar } from "../contracts/mocks/Dummy2UsernameRegistrar.sol";
import { UpdatedDummy2UsernameRegistrar } from "../contracts/mocks/UpdatedDummy2UsernameRegistrar.sol";

contract DeployTest is BaseScript {
DeploymentTestConfig deploymentTestConfig;
TestToken token;
ENSRegistry ensRegistry;
PublicResolver publicResolver;
constructor() {
deploymentTestConfig = new DeploymentTestConfig(broadcaster);
}


function run() public returns (
TestToken,
ENSRegistry,
PublicResolver,
DeploymentTestConfig
) {
DeploymentTestConfig.NetworkConfig memory config = deploymentTestConfig.activeNetworkConfig();

vm.startBroadcast(broadcaster);
token = new TestToken();
ensRegistry = new ENSRegistry();
publicResolver = new PublicResolver(ensRegistry);
vm.stopBroadcast();

return (
token,
ensRegistry,
publicResolver,
deploymentTestConfig
);
}


function deployRegistry() public returns (
UsernameRegistrar,
UpdatedUsernameRegistrar,
DeploymentTestConfig
) {
DeploymentTestConfig.NetworkConfig memory config = deploymentTestConfig.activeNetworkConfig();

vm.startBroadcast(broadcaster);
UsernameRegistrar usernameRegistrar = new UsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.registry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(0)
);

UpdatedUsernameRegistrar updatedUsernameRegistrar = new UpdatedUsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.registry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(usernameRegistrar)
);
vm.stopBroadcast();

return (
usernameRegistrar,
updatedUsernameRegistrar,
deploymentTestConfig
);
}



function deployDummy() public returns (
DummyUsernameRegistrar,
UpdatedDummyUsernameRegistrar,
DeploymentTestConfig
) {
DeploymentTestConfig.NetworkConfig memory config = deploymentTestConfig.activeNetworkConfig();

vm.startBroadcast(broadcaster);

DummyUsernameRegistrar dummyUsernameRegistrar = new DummyUsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.dummyRegistry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(0)
);

UpdatedDummyUsernameRegistrar updatedDummyUsernameRegistrar = new UpdatedDummyUsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.dummyRegistry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(dummyUsernameRegistrar)
);
vm.stopBroadcast();

return (
dummyUsernameRegistrar,
updatedDummyUsernameRegistrar,
deploymentTestConfig
);
}


function deployDummy2() public returns (
Dummy2UsernameRegistrar,
UpdatedDummy2UsernameRegistrar
) {
DeploymentTestConfig.NetworkConfig memory config = deploymentTestConfig.activeNetworkConfig();

vm.startBroadcast(broadcaster);

Dummy2UsernameRegistrar dummy2UsernameRegistrar = new Dummy2UsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.dummy2Registry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(0)
);

UpdatedDummy2UsernameRegistrar updatedDummy2UsernameRegistrar = new UpdatedDummy2UsernameRegistrar(
token,
ensRegistry,
publicResolver,
config.dummy2Registry.namehash,
config.usernameMinLength,
config.reservedUsernamesMerkleRoot,
address(dummy2UsernameRegistrar)
);

vm.stopBroadcast();

return (
dummy2UsernameRegistrar,
updatedDummy2UsernameRegistrar
);
}
}
85 changes: 85 additions & 0 deletions script/DeploymentTestConfig.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.19 <=0.9.0;

import { Script } from "forge-std/Script.sol";

contract DeploymentTestConfig is Script {
error DeploymentConfig_InvalidDeployerAddress();
error DeploymentConfig_NoConfigForChain(uint256);
bytes32 constant ETH_LABELHASH = keccak256("eth");
bytes32 constant ETH_NAMEHASH = keccak256(abi.encodePacked(bytes32(0x0), ETH_LABELHASH));

struct RegistryConfig {
string name;
string registry;
bytes32 label;
bytes32 namehash;
uint256 price;
}

struct NetworkConfig {
address deployer;
bytes32 reservedUsernamesMerkleRoot;
uint256 usernameMinLength;
RegistryConfig registry;
RegistryConfig dummyRegistry;
RegistryConfig dummy2Registry;
}

NetworkConfig private activeNetworkConfig_;

address public deployer;

constructor(address _broadcaster) {
deployer = _broadcaster;
if (block.chainid == 31_337) {
activeNetworkConfig_ = getOrCreateAnvilEthConfig(_broadcaster);
} else {
revert DeploymentConfig_NoConfigForChain(block.chainid);
}
if (_broadcaster == address(0)) revert DeploymentConfig_InvalidDeployerAddress();
}

function activeNetworkConfig() public view returns (NetworkConfig memory) {
return activeNetworkConfig_;
}

function getOrCreateAnvilEthConfig(address _deployer) public pure returns (NetworkConfig memory) {
bytes32 reservedUsernamesMerkleRoot = 0xb46e19581b371ab0856ee8ffd05b33cbfd264755e18f2d004780bb929970a53e ; // Replace with actual merkle root

RegistryConfig memory registry = RegistryConfig({
name: "stateofus",
registry: "stateofus.eth",
label: keccak256(abi.encodePacked("stateofus")),
namehash: keccak256(abi.encodePacked(ETH_NAMEHASH, keccak256("stateofus"))),
price: 1000
});

RegistryConfig memory dummyRegistry = RegistryConfig({
name: "dummyreg",
registry: "dummyreg.eth",
label: keccak256(abi.encodePacked("dummyreg")),
namehash: keccak256(abi.encodePacked(ETH_NAMEHASH, keccak256("dummyreg"))),
price: 1000
});

RegistryConfig memory dummy2Registry = RegistryConfig({
name: "dummy2reg",
registry: "dummy2reg.eth",
label: keccak256(abi.encodePacked("dummy2reg")),
namehash: keccak256(abi.encodePacked(ETH_NAMEHASH, keccak256("dummy2reg"))),
price: 1000
});

return NetworkConfig({
deployer: _deployer,
reservedUsernamesMerkleRoot: reservedUsernamesMerkleRoot,
usernameMinLength: 3,
registry: registry,
dummyRegistry: dummyRegistry,
dummy2Registry: dummy2Registry
});
}

function test() public { }
}
26 changes: 0 additions & 26 deletions test/Foo.t.sol

This file was deleted.

Loading

0 comments on commit 2436e3f

Please sign in to comment.