-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
826 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 { } | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.