编译器
0.8.26+commit.8a97fa7a
文件 1 的 4:Create2.sol
pragma solidity ^0.8.20;
library Create2 {
error Create2InsufficientBalance(uint256 balance, uint256 needed);
error Create2EmptyBytecode();
error Create2FailedDeployment();
function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
if (address(this).balance < amount) {
revert Create2InsufficientBalance(address(this).balance, amount);
}
if (bytecode.length == 0) {
revert Create2EmptyBytecode();
}
assembly {
addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
}
if (addr == address(0)) {
revert Create2FailedDeployment();
}
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
return computeAddress(salt, bytecodeHash, address(this));
}
function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x40), bytecodeHash)
mstore(add(ptr, 0x20), salt)
mstore(ptr, deployer)
let start := add(ptr, 0x0b)
mstore8(start, 0xff)
addr := keccak256(start, 85)
}
}
}
文件 2 的 4:IUniswapV4DeployerCompetition.sol
pragma solidity 0.8.26;
interface IUniswapV4DeployerCompetition {
event NewAddressFound(address indexed bestAddress, address indexed submitter, uint256 score);
error InvalidBytecode();
error CompetitionNotOver(uint256 currentTime, uint256 deadline);
error CompetitionOver(uint256 currentTime, uint256 deadline);
error NotAllowedToDeploy(address sender, address deployer);
error WorseAddress(address newAddress, address bestAddress, uint256 newScore, uint256 bestScore);
error InvalidSender(bytes32 salt, address sender);
function updateBestAddress(bytes32 salt) external;
function deploy(bytes memory bytecode) external;
}
文件 3 的 4:UniswapV4DeployerCompetition.sol
pragma solidity 0.8.26;
import {Create2} from "@openzeppelin/contracts/utils/Create2.sol";
import {VanityAddressLib} from "./libraries/VanityAddressLib.sol";
import {IUniswapV4DeployerCompetition} from "./interfaces/IUniswapV4DeployerCompetition.sol";
contract UniswapV4DeployerCompetition is IUniswapV4DeployerCompetition {
using VanityAddressLib for address;
bytes32 public bestAddressSalt;
address public bestAddressSubmitter;
uint256 public immutable competitionDeadline;
bytes32 public immutable initCodeHash;
address public immutable deployer;
uint256 public immutable exclusiveDeployDeadline;
constructor(
bytes32 _initCodeHash,
uint256 _competitionDeadline,
address _exclusiveDeployer,
uint256 _exclusiveDeployLength
) {
initCodeHash = _initCodeHash;
competitionDeadline = _competitionDeadline;
exclusiveDeployDeadline = _competitionDeadline + _exclusiveDeployLength;
deployer = _exclusiveDeployer;
}
function updateBestAddress(bytes32 salt) external {
if (block.timestamp > competitionDeadline) {
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 _bestAddress = bestAddress();
if (!newAddress.betterThan(_bestAddress)) {
revert WorseAddress(newAddress, _bestAddress, newAddress.score(), _bestAddress.score());
}
bestAddressSalt = salt;
bestAddressSubmitter = msg.sender;
emit NewAddressFound(newAddress, msg.sender, newAddress.score());
}
function deploy(bytes memory bytecode) external {
if (keccak256(bytecode) != initCodeHash) {
revert InvalidBytecode();
}
if (block.timestamp <= competitionDeadline) {
revert CompetitionNotOver(block.timestamp, competitionDeadline);
}
if (msg.sender != deployer && block.timestamp <= exclusiveDeployDeadline) {
revert NotAllowedToDeploy(msg.sender, deployer);
}
Create2.deploy(0, bestAddressSalt, bytecode);
}
function bestAddress() public view returns (address) {
return Create2.computeAddress(bestAddressSalt, initCodeHash);
}
}
文件 4 的 4:VanityAddressLib.sol
pragma solidity ^0.8.0;
library VanityAddressLib {
function betterThan(address first, address second) internal pure returns (bool better) {
return score(first) > score(second);
}
function score(address addr) internal pure returns (uint256 calculatedScore) {
bytes20 addrBytes = bytes20(addr);
unchecked {
uint256 leadingZeroCount = getLeadingNibbleCount(addrBytes, 0, 0);
calculatedScore += (leadingZeroCount * 10);
uint256 leadingFourCount = getLeadingNibbleCount(addrBytes, leadingZeroCount, 4);
if (leadingFourCount == 0) {
return 0;
} else if (leadingFourCount == 4) {
calculatedScore += 60;
} else if (leadingFourCount > 4) {
calculatedScore += 40;
}
for (uint256 i = 0; i < addrBytes.length * 2; i++) {
uint8 currentNibble = getNibble(addrBytes, i);
if (currentNibble == 4) {
calculatedScore += 1;
}
}
if (addrBytes[18] == 0x44 && addrBytes[19] == 0x44) {
calculatedScore += 20;
}
}
}
function getLeadingNibbleCount(bytes20 addrBytes, uint256 startIndex, uint8 comparison)
internal
pure
returns (uint256 count)
{
if (startIndex >= addrBytes.length * 2) {
return count;
}
for (uint256 i = startIndex; i < addrBytes.length * 2; i++) {
uint8 currentNibble = getNibble(addrBytes, i);
if (currentNibble != comparison) {
return count;
}
count += 1;
}
}
function getNibble(bytes20 input, uint256 nibbleIndex) internal pure returns (uint8 currentNibble) {
uint8 currByte = uint8(input[nibbleIndex / 2]);
if (nibbleIndex % 2 == 0) {
currentNibble = currByte >> 4;
} else {
currentNibble = currByte & 0x0F;
}
}
}
{
"compilationTarget": {
"src/UniswapV4DeployerCompetition.sol": "UniswapV4DeployerCompetition"
},
"evmVersion": "cancun",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"runs": 44444444
},
"remappings": [
":@ensdomains/=lib/v4-core/node_modules/@ensdomains/",
":@openzeppelin/=lib/v4-core/lib/openzeppelin-contracts/",
":@openzeppelin/contracts/=lib/v4-core/lib/openzeppelin-contracts/contracts/",
":@uniswap/v4-core/=lib/v4-core/",
":ds-test/=lib/v4-core/lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/v4-core/lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-gas-snapshot/=lib/forge-gas-snapshot/src/",
":forge-std/=lib/v4-core/lib/forge-std/src/",
":hardhat/=lib/v4-core/node_modules/hardhat/",
":openzeppelin-contracts/=lib/v4-core/lib/openzeppelin-contracts/",
":permit2/=lib/permit2/",
":solmate/=lib/v4-core/lib/solmate/",
":v4-core/=lib/v4-core/src/"
],
"viaIR": true
}
[{"inputs":[{"internalType":"bytes32","name":"_initCodeHash","type":"bytes32"},{"internalType":"uint256","name":"_competitionDeadline","type":"uint256"},{"internalType":"address","name":"_exclusiveDeployer","type":"address"},{"internalType":"uint256","name":"_exclusiveDeployLength","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"currentTime","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"CompetitionNotOver","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentTime","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"CompetitionOver","type":"error"},{"inputs":[],"name":"Create2EmptyBytecode","type":"error"},{"inputs":[],"name":"Create2FailedDeployment","type":"error"},{"inputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"Create2InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidBytecode","type":"error"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"address","name":"sender","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"deployer","type":"address"}],"name":"NotAllowedToDeploy","type":"error"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"address","name":"bestAddress","type":"address"},{"internalType":"uint256","name":"newScore","type":"uint256"},{"internalType":"uint256","name":"bestScore","type":"uint256"}],"name":"WorseAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"bestAddress","type":"address"},{"indexed":true,"internalType":"address","name":"submitter","type":"address"},{"indexed":false,"internalType":"uint256","name":"score","type":"uint256"}],"name":"NewAddressFound","type":"event"},{"inputs":[],"name":"bestAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bestAddressSalt","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bestAddressSubmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"competitionDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"bytecode","type":"bytes"}],"name":"deploy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deployer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exclusiveDeployDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initCodeHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"updateBestAddress","outputs":[],"stateMutability":"nonpayable","type":"function"}]