Skip to content

Commit

Permalink
Include address in salt
Browse files Browse the repository at this point in the history
  • Loading branch information
hensha256 committed Nov 1, 2024
1 parent 81791ba commit 58fa41b
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 37 deletions.
3 changes: 3 additions & 0 deletions src/UniswapV4DeployerCompetition.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ contract UniswapV4DeployerCompetition is IUniswapV4DeployerCompetition {
revert CompetitionOver(block.timestamp, competitionDeadline);
}

address saltSubAddress = address(bytes20(salt));
if (saltSubAddress != msg.sender && saltSubAddress != address(0)) revert InvalidSender(salt, msg.sender);

address newAddress = Create2.computeAddress(salt, initCodeHash, address(this));
if (bestAddress != address(0) && !newAddress.betterThan(bestAddress)) {
revert WorseAddress(newAddress, bestAddress, newAddress.score(), bestAddress.score());
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IUniswapV4DeployerCompetition.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ interface IUniswapV4DeployerCompetition {
error CompetitionOver(uint256 currentTime, uint256 deadline);
error NotAllowedToDeploy(address sender, address deployer);
error WorseAddress(address newAddress, address bestAddress, uint256 newScore, uint256 bestScore);
error InvalidTokenId(uint256 tokenId);
error InvalidSender(bytes32 salt, address sender);

/// @notice Updates the best address if the new address has a better vanity score
/// @param salt The salt to use to compute the new address with CREATE2
Expand Down
2 changes: 0 additions & 2 deletions src/libraries/VanityAddressLib.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

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

/// @title VanityAddressLib
/// @notice A library to score addresses based on their vanity
library VanityAddressLib {
Expand Down
97 changes: 66 additions & 31 deletions test/UniswapV4DeployerCompetition.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity ^0.8.20;

import {Owned} from "solmate/src/auth/Owned.sol";
import {Test, console2} from "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
import {console2} from "forge-std/console2.sol";
import {PoolManager} from "@uniswap/v4-core/src/PoolManager.sol";
import {UniswapV4DeployerCompetition} from "../src/UniswapV4DeployerCompetition.sol";
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
Expand All @@ -20,6 +21,8 @@ contract UniswapV4DeployerCompetitionTest is Test {
address winner;
uint256 competitionDeadline;

bytes32 mask20bytes = bytes32(uint256(type(uint96).max));

function setUp() public {
competitionDeadline = block.timestamp + 7 days;
v4Owner = makeAddr("V4Owner");
Expand All @@ -31,7 +34,9 @@ contract UniswapV4DeployerCompetitionTest is Test {
assertEq(competition.v4Owner(), v4Owner);
}

function testUpdateBestAddress(bytes32 salt) public {
function test_updateBestAddress_succeeds(bytes32 salt) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

assertEq(competition.bestAddress(), address(0));
assertEq(competition.bestAddressSubmitter(), address(0));
assertEq(competition.bestAddressSalt(), bytes32(0));
Expand All @@ -57,7 +62,7 @@ contract UniswapV4DeployerCompetitionTest is Test {
assertEq(address(competition).balance, 0 ether);
}

function testCompetitionOver(bytes32 salt) public {
function test_updateBestAddress_reverts_CompetitionOver(bytes32 salt) public {
vm.warp(competition.competitionDeadline() + 1);
vm.expectRevert(
abi.encodeWithSelector(
Expand All @@ -69,7 +74,52 @@ contract UniswapV4DeployerCompetitionTest is Test {
competition.updateBestAddress(salt);
}

function testUpdateBestAddressOpen(bytes32 salt) public {
function test_updateBestAddress_reverts_InvalidSigner(bytes32 salt) public {
vm.assume(bytes20(salt) != bytes20(0));
vm.assume(bytes20(salt) != bytes20(winner));

vm.expectRevert(abi.encodeWithSelector(IUniswapV4DeployerCompetition.InvalidSender.selector, salt, winner));
vm.prank(winner);
competition.updateBestAddress(salt);
}

function test_updateBestAddress_equalSalt_reverts_WorseAddress(bytes32 salt) public {
vm.assume(salt != bytes32(0));
console2.logBytes32(salt);
salt = (salt & mask20bytes) | bytes32(bytes20(winner));
console2.logBytes32(salt);

vm.prank(winner);
competition.updateBestAddress(salt);
assertFalse(competition.bestAddress() == address(0));
assertEq(competition.bestAddressSubmitter(), winner);
assertEq(competition.bestAddressSalt(), salt);

bytes32 newSalt = (salt & mask20bytes) | bytes32(bytes20(address(1)));
address newAddr = Create2.computeAddress(newSalt, initCodeHash, address(competition));
if (!newAddr.betterThan(competition.bestAddress())) {
vm.expectRevert(
abi.encodeWithSelector(
IUniswapV4DeployerCompetition.WorseAddress.selector,
newAddr,
competition.bestAddress(),
newAddr.score(),
competition.bestAddress().score()
)
);
vm.prank(address(1));
competition.updateBestAddress(newSalt);
} else {
vm.prank(address(1));
competition.updateBestAddress(newSalt);
assertEq(competition.bestAddressSubmitter(), address(1));
assertEq(competition.bestAddressSalt(), newSalt);
}
}

function test_deploy_succeeds(bytes32 salt) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

vm.prank(winner);
competition.updateBestAddress(salt);
address v4Core = competition.bestAddress();
Expand All @@ -81,7 +131,9 @@ contract UniswapV4DeployerCompetitionTest is Test {
assertEq(TickMath.MAX_TICK_SPACING, type(int16).max);
}

function testCompetitionNotOver(bytes32 salt, uint256 timestamp) public {
function test_deploy_reverts_CompetitionNotOver(bytes32 salt, uint256 timestamp) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

vm.assume(timestamp < competition.competitionDeadline());
vm.prank(winner);
competition.updateBestAddress(salt);
Expand All @@ -94,15 +146,19 @@ contract UniswapV4DeployerCompetitionTest is Test {
competition.deploy(abi.encodePacked(type(PoolManager).creationCode, uint256(uint160(v4Owner))));
}

function testInvalidBytecode(bytes32 salt) public {
function test_deploy_reverts_InvalidBytecode(bytes32 salt) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

vm.prank(winner);
competition.updateBestAddress(salt);
vm.expectRevert(IUniswapV4DeployerCompetition.InvalidBytecode.selector);
// set the owner as the winner not the correct owner
competition.deploy(abi.encodePacked(type(PoolManager).creationCode, uint256(uint160(winner))));
}

function testInvalidMsgSender(bytes32 salt) public {
function test_deploy_reverts_InvalidMsgSender(bytes32 salt) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

vm.prank(winner);
competition.updateBestAddress(salt);
vm.warp(competition.competitionDeadline() + 1);
Expand All @@ -113,34 +169,13 @@ contract UniswapV4DeployerCompetitionTest is Test {
competition.deploy(abi.encodePacked(type(PoolManager).creationCode, uint256(uint160(v4Owner))));
}

function testAfterExcusiveDeployDeadline(bytes32 salt) public {
function test_deploy_afterExcusiveDeployDeadline(bytes32 salt) public {
salt = (salt & mask20bytes) | bytes32(bytes20(winner));

vm.prank(winner);
competition.updateBestAddress(salt);
vm.warp(competition.exclusiveDeployDeadline() + 1);
vm.prank(address(1));
competition.deploy(abi.encodePacked(type(PoolManager).creationCode, uint256(uint160(v4Owner))));
}

function testEqualSaltNotChanged(bytes32 salt) public {
vm.prank(winner);
competition.updateBestAddress(salt);
assertFalse(competition.bestAddress() == address(0));
assertEq(competition.bestAddressSubmitter(), winner);
assertEq(competition.bestAddressSalt(), salt);

address newAddr = Create2.computeAddress(salt >> 1, initCodeHash, address(competition));
vm.assume(competition.bestAddress().betterThan(newAddr));

vm.prank(address(1));
vm.expectRevert(
abi.encodeWithSelector(
IUniswapV4DeployerCompetition.WorseAddress.selector,
newAddr,
competition.bestAddress(),
newAddr.score(),
competition.bestAddress().score()
)
);
competition.updateBestAddress(salt >> 1);
}
}
2 changes: 1 addition & 1 deletion test/libraries/VanityAddressLib.t.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

import {Test, console} from "forge-std/Test.sol";
import {Test} from "forge-std/Test.sol";
import {VanityAddressLib} from "../../src/libraries/VanityAddressLib.sol";

contract VanityAddressLibTest is Test {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import {ActionConstants} from "../../src/libraries/ActionConstants.sol";
import {Planner, Plan} from "../shared/Planner.sol";
import {DeltaResolver} from "../../src/base/DeltaResolver.sol";

import "forge-std/console2.sol";

contract PositionManagerModifyLiquiditiesTest is Test, PosmTestSetup, LiquidityFuzzers {
using StateLibrary for IPoolManager;
using PoolIdLibrary for PoolKey;
Expand Down

0 comments on commit 58fa41b

Please sign in to comment.