Skip to content

Commit

Permalink
Add script for pre-minting basenames (#83)
Browse files Browse the repository at this point in the history
* Add script for pre-minting basenames

* Add expected full premint list

* Updated premint script and makefile

* Lint

* Add csv writing to premint logic

* Ignore scratch

* Fix typo

* Run premint3

* Remove dup

* Add not-found name

* Run premint2

* premint verifications and attestations

* Run premint4

* Add premint5, output csv

* lint

* update output

* Add premint 6

* Add BNS parser

* Run premint 7

* Update csv

* Update csv

* Run premint 8 for 1 year duration reservations

* Run premint 9

* Add single run of premint for rodeo

* Rerun BNS merkle gen

* Run premint verification

* Lint

* cleanup for review
  • Loading branch information
stevieraykatz authored Aug 24, 2024
1 parent 14a6b17 commit b2f909f
Show file tree
Hide file tree
Showing 16 changed files with 3,775 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@ docs/

# Dotenv file
.env

# Local env
script/Scratch*
111 changes: 111 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
include .env

# premint1 file should be minted with a 100-year duration, these are coinbase-specific domains
# 3153600000 = 100 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-testnet-premint-1
execute-testnet-premint-1:
@for name in $$(cat script/premint/premint1); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --sig "run(string,uint256)" "$$name" 3153600000 \
--rpc-url $(BASE_SEPOLIA_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint1 file should be minted with a 100-year duration, these are coinbase-specific domains
# 3153600000 = 100 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-1
execute-premint-1:
@for name in $$(cat script/premint/premint1); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --sig "run(string,uint256)" "$$name" 3153600000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint2 file should be minted with a 10-year duration, these are cb exec domains
# 315360000 = 10 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-2
execute-premint-2:
@for name in $$(cat script/premint/premint2); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 315360000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint3 file should be minted with a 5-year duration, these are web2-specific domains
# 157680000 = 5 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-3
execute-premint-3:
@for name in $$(cat script/premint/premint3); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 157680000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint4 file should be minted with a 5-year duration, these are web3-specific domains/individuals
# 157680000 = 5 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-4
execute-premint-4:
@for name in $$(cat script/premint/premint4); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 157680000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint5 file should be minted with a 5-year duration, these are web3-specific domains/individuals
# 157680000 = 5 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-5
execute-premint-5:
@for name in $$(cat script/premint/premint5); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 157680000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint6 file should be minted with a 100-year duration, these are Coinbase/Base specific domains
# 3153600000 = 100 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-6
execute-premint-6:
@for name in $$(cat script/premint/premint6); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 3153600000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint7 file should be minted with a 1-year duration, these are the F500 names
# 31536000 = 1 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-7
execute-premint-7:
@for name in $$(cat script/premint/premint7); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 31536000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint8 file should be minted with a 1-year duration, these are the base BD names
# 31536000 = 1 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-8
execute-premint-8:
@for name in $$(cat script/premint/premint8); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 31536000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done

# premint9 file should be minted with a 100-year duration, these are the base project words
# 3153600000 = 100 (years) * 365 (days) * 24 (hours) * 3600 (seconds)
.PHONY: execute-premint-9
execute-premint-9:
@for name in $$(cat script/premint/premint9); \
do \
echo "$$name"; \
forge script script/premint/Premint.s.sol --ffi --sig "run(string,uint256)" "$$name" 31536000 \
--rpc-url $(BASE_RPC_URL) --fork-retries 5 --broadcast; \
done
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ src = "src"
out = "out"
libs = ["lib"]
remappings = ["@ensdomains/buffer/=lib/buffer"]
fs_permissions = [{access = "read", path = "./script/premint/"}]

[rpc_endpoints]
sepolia="${SEPOLIA_RPC_URL}"
Expand All @@ -11,3 +12,4 @@ base-sepolia="${BASE_SEPOLIA_RPC_URL}"
[etherscan]
sepolia={url = "https://api-sepolia.etherscan.io/api", key = "${ETHERSCAN_API_KEY}"}
base-sepolia={url = "https://api-sepolia.basescan.org/api", key = "${BASE_ETHERSCAN_API_KEY}"}

45 changes: 45 additions & 0 deletions py/BNS.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import json


def main():

owners = []
with open("cache/Update-BNS-Users.json", "r") as f:
data = json.load(f)
for r in data:
if(len(r["owners"]) > 1):
print("multiple owners for %s" % r["name"])
elif(len(r["owners"]) == 0):
print("no owners for %s" % r["name"])
else:
owners.append(r["owners"][0]["owner_address"])


seen = set()
owner_count = dict()
unique_owners = []
for owner in owners:
if owner not in seen:
unique_owners.append(owner)
seen.add(owner)
owner_count[owner] = 1
else:
owner_count[owner] += 1


with open("cache/bns.csv", "a") as f:
for owner in unique_owners:
f.write(owner + "\n")


print("Total owned tokens: %s" % len(owners))
print("Total unique owners: %s" % len(unique_owners))
c = 0
for w in sorted(owner_count, key=owner_count.get):
if owner_count[w] > 9:
c+=1
print(w, owner_count[w])
print("Multiple name holders: %s" % str(c))

if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions py/writer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/python3

import sys

print("In writer.py")
with open("script/premint/output.csv", 'a') as f:
f.write(sys.argv[1])
62 changes: 62 additions & 0 deletions script/premint/Premint.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;

import {BaseRegistrar} from "src/L2/BaseRegistrar.sol";
import {RegistrarController} from "src/L2/RegistrarController.sol";
import {LibString} from "solady/utils/LibString.sol";

import "forge-std/Script.sol";

/// @title Script for autonomously reserving names with a controller-permissioned pkey
///
/// @notice addr(PREMINT_PRIVATE_KEY) must be an approved `controller` on the BaseRegistrar
contract Premint is Script {
uint256 premintPrivateKey = vm.envUint("PREMINT_PRIVATE_KEY");
address BASE_REGISTRAR = vm.envAddress("BASE_REGISTRAR_ADDR");
address BASE_ECOSYSTEM_MULTISIG = vm.envAddress("BASE_ECOSYSTEM_MULTISIG");
address REGISTRAR_CONTROLLER = vm.envAddress("REGISTRAR_CONTROLLER_ADDR");

function run(string memory name, uint256 duration) external {
console.log("-------------------------------");
console.log("Minting name:");
console.log(name);
console.log("-------------------------------");

vm.startBroadcast(premintPrivateKey);

bytes32 label = keccak256(bytes(name));
uint256 id = uint256(label);

if (!BaseRegistrar(BASE_REGISTRAR).isAvailable(id)) {
console.log("Name already registered");
return;
}

// Premint name
BaseRegistrar(BASE_REGISTRAR).registerOnly(id, BASE_ECOSYSTEM_MULTISIG, duration);

// Record name and id in csv
string memory idStr = vm.toString(id);
string memory data = LibString.concat(name, ",");
data = LibString.concat(data, idStr);
data = LibString.concat(data, "\n");
string[] memory input = new string[](3);
input[0] = "python3";
input[1] = "py/writer.py";
input[2] = data;
vm.ffi(input);
}

function verify(uint256 lines, string calldata file) public view {
for (uint256 i; i < lines; i++) {
string memory name = vm.readLine(file);
bytes32 label = keccak256(bytes(name));
uint256 id = uint256(label);
if (BaseRegistrar(BASE_REGISTRAR).nameExpires(id) == 0) {
console.log("Not minted: ", name);
} else if (BaseRegistrar(BASE_REGISTRAR).ownerOf(id) != BASE_ECOSYSTEM_MULTISIG) {
console.log("Not owned by ecosystem multisig", name);
}
}
}
}
Loading

0 comments on commit b2f909f

Please sign in to comment.