Skip to content

Commit

Permalink
change scoring algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dianakocsis committed Oct 11, 2024
1 parent e8a4854 commit 0bbf0dc
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 63 deletions.
81 changes: 54 additions & 27 deletions src/libraries/VanityAddressLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,45 +16,72 @@ library VanityAddressLib {
/// @param addr The address to score
/// @return calculatedScore The vanity score of the address
function score(address addr) internal pure returns (uint256 calculatedScore) {
// 10 points for every leading 0
// 3 points for every leading 4
// 1 point for every 4 after that
// Requirement: The first nonzero nibble must be 4
// 10 points for every leading 0 nibble
// 40 points if the first 4 is followed by 3 more 4s
// 20 points if the first nibble after the 4 4s is NOT a 4
// 20 points if the last 4 nibbles are 4s
// 1 point for every 4
bytes20 addrBytes = bytes20(addr);

bool startingZeros = true;
bool startingFours = true;
// iterate over the bytes of the address
for (uint256 i = 0; i < 20; i++) {
if (startingZeros && addrBytes[i] == 0x00) {
calculatedScore += 20;
continue;
} else if (startingZeros && (addrBytes[i] & 0xF0) == 0x00) {
calculatedScore += 10;
startingZeros = false;
bool firstFour = true;
uint8 fourCounts; // counter for the number of 4s
// iterate over the nibbles of the address
for (uint256 i = 0; i < addrBytes.length * 2; i++) {
uint8 currentNibble;
if (i % 2 == 0) {
// Get the higher nibble of the byte
currentNibble = uint8(addrBytes[i / 2] >> 4);
} else {
startingZeros = false;
// Get the lower nibble of the byte
currentNibble = uint8(addrBytes[i / 2] & 0x0F);
}
if (startingFours && addrBytes[i] == 0x44) {
calculatedScore += 6;
continue;
} else if (startingFours && (addrBytes[i] & 0xF0 == 0x40) || (addrBytes[i] & 0xFF == 0x04)) {
calculatedScore += 3;
startingFours = false;

// leading 0s
if (startingZeros && currentNibble == 0) {
calculatedScore += 10;
continue;
} else {
startingFours = false;
startingZeros = false;
}

if (!startingZeros && !startingFours) {
// count each nibble separately
if (addrBytes[i] & 0xFF == 0x44) {
calculatedScore += 2;
} else if (addrBytes[i] & 0x0F == 0x04) {
calculatedScore += 1;
} else if (addrBytes[i] & 0xF0 == 0x40) {
calculatedScore += 1;
// leading 4s
if (startingFours) {
// If the first nonzero nibble is not 4, the score is an automatic 0
if (firstFour && currentNibble != 4) {
return 0;
}

if (currentNibble == 4) {
fourCounts += 1;
if (fourCounts == 4) {
calculatedScore += 40;
// If the leading 4 4s are also the last 4 nibbles, add 20 points
if (i == addrBytes.length * 2 - 1) {
calculatedScore += 20;
}
}
} else {
// If the first nibble after the 4 4s is not a 4, add 20 points
if (fourCounts == 4) {
calculatedScore += 20;
}
startingFours = false;
}
firstFour = false;
}

// count each 4 nibble separately
if (currentNibble == 4) {
calculatedScore += 1;
}
}

// If the last 4 nibbles are 4s, add 20 points
if (addrBytes[18] & 0xFF == 0x44 && addrBytes[19] & 0xFF == 0x44) {
calculatedScore += 20;
}
}
}
13 changes: 1 addition & 12 deletions test/UniswapV4DeployerCompetition.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ contract UniswapV4DeployerCompetitionTest is Test {
function testEqualSaltNotChanged(bytes32 salt) public {
vm.prank(winner);
deployer.updateBestAddress(salt);
assertFalse(deployer.bestAddress() == address(0));
assertEq(deployer.bestAddressSender(), winner);
assertEq(deployer.bestAddressSalt(), salt);

Expand All @@ -139,18 +140,6 @@ contract UniswapV4DeployerCompetitionTest is Test {
deployer.updateBestAddress(salt >> 1);
}

function testUpdateNotEqual() public {
bytes32 salt1 = keccak256(abi.encodePacked(uint256(1)));
bytes32 salt2 = keccak256(abi.encodePacked(uint256(2)));
vm.prank(winner);
deployer.updateBestAddress(salt1);
vm.prank(winner);
deployer.updateBestAddress(salt2);
assertFalse(deployer.bestAddress() == address(0));
assertEq(deployer.bestAddressSender(), winner);
assertEq(deployer.bestAddressSalt(), salt2);
}

function testTokenURI(bytes32 salt) public {
vm.prank(winner);
deployer.updateBestAddress(salt);
Expand Down
67 changes: 43 additions & 24 deletions test/libraries/VanityAddressLib.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ contract VanityAddressLibTest is Test {
function test_scoreAllZeros() public pure {
address addr = address(0);
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 400; // 20 * 10
uint256 expected = 400; // not a 4 after the zeros
assertEq(score, expected);
}

function test_scoreAllFours() public pure {
address addr = address(0x4444444444444444444444444444444444444444);
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 120; // 6 * 20
uint256 expected = 100; // 40 + 40 + 20 = 100
assertEq(score, expected);
}

function test_scoreLaterFours() public pure {
address addr = address(0x1444444444444444444444444444444444444444);
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 39; // 1 + (5 * 19) = 39
uint256 expected = 0; // no leading 4
assertEq(score, expected);
}

Expand All @@ -33,7 +33,7 @@ contract VanityAddressLibTest is Test {
// does not count future null bytes
// counts 4 nibbles after that
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 28; // 20+6+1+1
uint256 expected = 24; // 10 * 2 + 2 + 2 = 24
assertEq(score, expected);
}

Expand All @@ -44,7 +44,7 @@ contract VanityAddressLibTest is Test {
// does not count future null bytes
// counts 4 nibbles after that
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 30; // 20+6+2+2
uint256 expected = 46; // 10 * 2 + 6 + 20 = 46
assertEq(score, expected);
}

Expand All @@ -53,31 +53,50 @@ contract VanityAddressLibTest is Test {
// counts first null byte
// counts first leading 4s after that
uint256 score = VanityAddressLib.score(addr);
uint256 expected = 33; // 20+10+3
uint256 expected = 31; // 10 * 3 + 1 = 31
assertEq(score, expected);
}

function test_scores_succeed() public pure {
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000000082)), 0); // 0
assertEq(VanityAddressLib.score(address(0x0400000000000000000000000000000000000000)), 11); // 10 * 1 + 1 = 11
assertEq(VanityAddressLib.score(address(0x0044000000000000000000000000000000004444)), 46); // 10 * 2 + 6 + 20 = 46
assertEq(VanityAddressLib.score(address(0x4444000000000000000000000000000000004444)), 88); // 40 + 20 + 20 + 8 = 88
assertEq(VanityAddressLib.score(address(0x0044440000000000000000000000000000000044)), 86); // 10 * 2 + 40 + 20 + 6 = 86
assertEq(VanityAddressLib.score(address(0x0000444400000000000000000000000000004444)), 128); // 10 * 4 + 40 + 20 + 20 + 8 = 128
assertEq(VanityAddressLib.score(address(0x0040444444444444444444444444444444444444)), 77); // 10 * 2 + 37 + 20 = 77
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000000444)), 373); // 10 * 37 + 3 = 373
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000044444444)), 388); // 10 * 32 + 40 + 20 + 8 = 388
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000454444)), 365); // 10 * 34 + 20 + 5 = 365
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000000044)), 382); // 10 * 38 + 2 = 382
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000000004)), 391); // 10 * 39 + 1 = 391
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000444444)), 406); // 10 * 34 + 40 + 20 + 6 = 406
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000044444)), 415); // 10 * 35 + 40 + 20 + 5 = 415
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000444455)), 404); // 10 * 34 + 40 + 20 + 4 = 404
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000044445)), 414); // 10 * 35 + 40 + 20 + 4 = 414
assertEq(VanityAddressLib.score(address(0x0000000000000000000000000000000000004444)), 444); // 10 * 36 + 40 + 20 + 20 + 4 = 444
}

function test_betterThan() public pure {
address addr1 = address(0x0011111111111111111111111111111111111111); // 20 points
address addr2 = address(0x0000111111111111111111111111111111111111); // 40 points
address addr3 = address(0x0000411111111111111111111111111111111111); // 43 points
address addr4 = address(0x0000441111111111111111111111111111111111); // 46 points
address addr5 = address(0x0000440011111111111111111111111111111111); // 46 points
assertTrue(VanityAddressLib.betterThan(addr2, addr1)); // 40 > 20
assertTrue(VanityAddressLib.betterThan(addr3, addr2)); // 43 > 40
assertTrue(VanityAddressLib.betterThan(addr3, addr1)); // 43 > 20
assertTrue(VanityAddressLib.betterThan(addr4, addr3)); // 46 > 43
assertTrue(VanityAddressLib.betterThan(addr4, addr2)); // 46 > 40
assertTrue(VanityAddressLib.betterThan(addr4, addr1)); // 46 > 20
assertFalse(VanityAddressLib.betterThan(addr5, addr4)); // 46 == 46
assertEq(VanityAddressLib.score(addr5), VanityAddressLib.score(addr4)); // 46 == 46
assertTrue(VanityAddressLib.betterThan(addr5, addr3)); // 46 > 43
assertTrue(VanityAddressLib.betterThan(addr5, addr2)); // 46 > 40
assertTrue(VanityAddressLib.betterThan(addr5, addr1)); // 46 > 20
address addr1 = address(0x0011111111111111111111111111111111111111); // 0 points
address addr2 = address(0x4000111111111111111111111111111111111111); // 1 points
address addr3 = address(0x0000411111111111111111111111111111111111); // 10 * 4 + 1 = 41 points
address addr4 = address(0x0000441111111111111111111111111111111111); // 10 * 4 + 2 = 42 points
address addr5 = address(0x0000440011111111111111111111111111111111); // 10 * 4 + 2 = 42 points
assertTrue(VanityAddressLib.betterThan(addr2, addr1)); // 1 > 0
assertTrue(VanityAddressLib.betterThan(addr3, addr2)); // 41 > 1
assertTrue(VanityAddressLib.betterThan(addr3, addr1)); // 41 > 0
assertTrue(VanityAddressLib.betterThan(addr4, addr3)); // 42 > 41
assertTrue(VanityAddressLib.betterThan(addr4, addr2)); // 42 > 1
assertTrue(VanityAddressLib.betterThan(addr4, addr1)); // 42 > 0
assertFalse(VanityAddressLib.betterThan(addr5, addr4)); // 42 == 42
assertEq(VanityAddressLib.score(addr5), VanityAddressLib.score(addr4)); // 42 == 42
assertTrue(VanityAddressLib.betterThan(addr5, addr3)); // 42 > 41
assertTrue(VanityAddressLib.betterThan(addr5, addr2)); // 42 > 1
assertTrue(VanityAddressLib.betterThan(addr5, addr1)); // 42 > 0

// is this intentional?
address addr6 = address(0x0000000000000000000000000000000000004444);
address addr7 = address(0x0000000000000000000000000000000000000082);
assertFalse(VanityAddressLib.betterThan(addr6, addr7)); // 20 * 18 + 6 + 6 = 372 < 20 * 19 = 380
assertTrue(VanityAddressLib.betterThan(addr6, addr7)); // 10 * 36 + 40 + 20 + 20 + 4 = 444 > 0
}
}

0 comments on commit 0bbf0dc

Please sign in to comment.