Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
2df0232
add and verify ability to encode and decode struct data correctly
JamesEarle Apr 25, 2025
0432849
wip add templates for extra funcs in registry to for additional data
JamesEarle Apr 25, 2025
58d0743
add storage in registry for pricer and priceConfig, create getters an…
JamesEarle Apr 25, 2025
c4a5658
WIP add flow in registrars (mostly) and specifics for fixed pricer as…
JamesEarle Apr 30, 2025
d561661
WIP flesh out flow more with registrars and update test helpers, test…
JamesEarle May 7, 2025
7dfd0fb
resolve merge conflicts with stashed code for checkpoint
JamesEarle May 16, 2025
feffe29
all tests passing for finalized pricer abstraction changes
JamesEarle May 20, 2025
f83ce65
cleanup, lint, remove comments and any debug code
JamesEarle May 20, 2025
fedaaef
extra cleanup
JamesEarle May 21, 2025
765d3ab
fix after some feedback, all tests passing again
JamesEarle May 23, 2025
993ada6
all tests, lint, and build
JamesEarle May 24, 2025
3fae375
add a few extra tests for length checks in validation and anything mi…
JamesEarle May 27, 2025
cbf09de
add await for lint in CI
JamesEarle May 27, 2025
9ba991f
last few changes + dod addition
JamesEarle May 27, 2025
3eaf131
adjust workflow file structure
JamesEarle May 27, 2025
54cb494
temp make always run for action
JamesEarle May 27, 2025
a013b84
run on ubuntu-latest
JamesEarle May 27, 2025
8d44688
edit yaml back to PR opened or edited
JamesEarle May 27, 2025
bf96816
give path to file
JamesEarle May 27, 2025
5c85f96
remove testing for gh actions for dod, adjust rootPriceConfig tests t…
JamesEarle May 27, 2025
840d319
remove unnecessary address(0) check
JamesEarle May 27, 2025
be1cfa7
fixes for last comments
JamesEarle May 29, 2025
b4e2ee9
lint
JamesEarle May 29, 2025
0bff9b9
Merge branch 'rc/zchain-native-main' into feat/polymorphic-pricer-con…
JamesEarle May 29, 2025
99bdd4d
remove unused error
JamesEarle May 29, 2025
9c5722c
all tests passing
JamesEarle Jun 2, 2025
0a8cf7b
Merge branch 'rc/zchain-native-main' into feat/polymorphic-pricer-con…
JamesEarle Jun 2, 2025
b40e3f8
all tests passing, but there are type errors for some reason, seems f…
JamesEarle Jun 2, 2025
8073abb
fix all build errors and tests, except 2 remaining in subregistrar
JamesEarle Jun 4, 2025
d0ea88c
fix final test issues, clean, lint
JamesEarle Jun 4, 2025
4312fca
add dangling comma
JamesEarle Jun 4, 2025
320fe6c
lint again
JamesEarle Jun 4, 2025
cbe24ae
remove type and tokenOwner prop where not needed
JamesEarle Jun 4, 2025
570f996
fix NatSpec comment
Whytecrowe Jun 5, 2025
2d00727
rename fixed price config to FixedPriceConfig
Whytecrowe Jun 5, 2025
3e850d9
pack DistributionConfig more efficiently
Whytecrowe Jun 5, 2025
2a1ff96
small optimization in the pricer
Whytecrowe Jun 5, 2025
aceb2ec
fix return type in the getter
Whytecrowe Jun 5, 2025
046f3ff
fix subregistrar mock to have the same order of props
Whytecrowe Jun 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 49 additions & 94 deletions contracts/price/IZNSCurvePricer.sol
Original file line number Diff line number Diff line change
@@ -1,115 +1,70 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { ICurvePriceConfig } from "../types/ICurvePriceConfig.sol";
import { IZNSPricer } from "../types/IZNSPricer.sol";
import { IZNSPricer } from "./IZNSPricer.sol";


interface IZNSCurvePricer is ICurvePriceConfig, IZNSPricer {
interface IZNSCurvePricer is IZNSPricer {

/**
* @notice Reverted when multiplier passed by the domain owner
* is equal to 0 or more than 10^18, which is too large.
* @notice Struct for each configurable variable for price and fee calculations.
*/
error InvalidPrecisionMultiplierPassed(bytes32 domainHash);
struct CurvePriceConfig {
/**
* @notice Maximum price for a domain returned at <= `baseLength`
*/
uint256 maxPrice;
/**
* @notice Multiplier which we use to bend a curve of price on interval from `baseLength` to `maxLength`.
*/
uint256 curveMultiplier;
/**
* @notice Maximum length of a domain name. If the name is longer than this
* value we return the price that was at the `maxLength`
*/
uint256 maxLength;
/**
* @notice Base length of a domain name. If the name is less than or equal to
* this value we return the `maxPrice`
*/
uint256 baseLength;
/**
* @notice The precision multiplier of the price. This multiplier
* should be picked based on the number of token decimals to calculate properly.
* e.g. if we use a token with 18 decimals, and want precision of 2,
* our precision multiplier will be equal 10^18 - 10^2 = 10^16
*/
uint256 precisionMultiplier;
/**
* @notice The registration fee value in percentage as basis points (parts per 10,000)
* so the 2% value would be represented as 200.
* See [getRegistrationFee](#getregistrationfee) for the actual fee calc process.
*/
uint256 feePercentage;
}

/**
* @notice Emitted when the `maxPrice` is set in `CurvePriceConfig`
* @param price The new maxPrice value
*/
event MaxPriceSet(bytes32 domainHash, uint256 price);

/**
* @notice Emitted when the `baseLength` is set in `CurvePriceConfig`
* @param length The new baseLength value
*/
event BaseLengthSet(bytes32 domainHash, uint256 length);

/**
* @notice Emitted when the `maxLength` is set in `CurvePriceConfig`
* @param length The new maxLength value
*/
event MaxLengthSet(bytes32 domainHash, uint256 length);

/**
* @notice Emitted when the `precisionMultiplier` is set in `CurvePriceConfig`
* @param precision The new precisionMultiplier value
*/
event PrecisionMultiplierSet(bytes32 domainHash, uint256 precision);

/**
* @notice Emitted when the `feePercentage` is set in state
* @param feePercentage The new feePercentage value
* @notice Reverted when multiplier passed by the domain owner
* is equal to 0 or more than 10^18, which is too large.
*/
event FeePercentageSet(bytes32 domainHash, uint256 feePercentage);
error InvalidPrecisionMultiplierPassed();

/**
* @notice Emitted when the `curveMultiplier` is set in state
* @param curveMultiplier The new curveMultiplier value
* @notice Reverted when `maxLength` smaller than `baseLength`.
*/
event CurveMultiplierSet(bytes32 domainHash, uint256 curveMultiplier);

error MaxLengthSmallerThanBaseLength();

/**
* @notice Emitted when the full `CurvePriceConfig` is set in state
* @param maxPrice The new `maxPrice` value
* @param curveMultiplier The new `curveMultiplier` value
* @param maxLength The new `maxLength` value
* @param baseLength The new `baseLength` value
* @param precisionMultiplier The new `precisionMultiplier` value
* @notice Reverted when `curveMultiplier` AND `baseLength` are 0.
*/
event PriceConfigSet(
bytes32 domainHash,
uint256 maxPrice,
uint256 curveMultiplier,
uint256 maxLength,
uint256 baseLength,
uint256 precisionMultiplier,
uint256 feePercentage
);

function initialize(
address accessController_,
address registry_,
CurvePriceConfig calldata zeroPriceConfig_
) external;

function getPrice(
bytes32 parentHash,
string calldata label,
bool skipValidityCheck
) external view returns (uint256);

function getFeeForPrice(
bytes32 parentHash,
uint256 price
) external view returns (uint256);

function getPriceAndFee(
bytes32 parentHash,
string calldata label,
bool skipValidityCheck
) external view returns (
uint256 price,
uint256 stakeFee
);

function setPriceConfig(
bytes32 domainHash,
CurvePriceConfig calldata priceConfig
) external;

function setMaxPrice(bytes32 domainHash, uint256 maxPrice) external;

function setBaseLength(bytes32 domainHash, uint256 length) external;

function setMaxLength(bytes32 domainHash, uint256 length) external;

function setCurveMultiplier(bytes32 domainHash, uint256 curveMultiplier) external;
error DivisionByZero();

function setPrecisionMultiplier(bytes32 domainHash, uint256 multiplier) external;
function encodeConfig(
CurvePriceConfig calldata config
) external pure returns (bytes memory);

function setFeePercentage(bytes32 domainHash, uint256 feePercentage) external;

function setRegistry(address registry_) external;
function decodePriceConfig(
bytes memory priceConfig
) external pure returns (CurvePriceConfig memory);
}
49 changes: 12 additions & 37 deletions contracts/price/IZNSFixedPricer.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.26;

import { IZNSPricer } from "../types/IZNSPricer.sol";
import { IZNSPricer } from "./IZNSPricer.sol";


/**
* @title IZNSFixedPricer.sol Below is the doc for PriceConfig struct.
* @title IZNSFixedPricer.sol Below is the doc for FixedPriceConfig struct.
* @notice Struct for price configurations per domainHash that is used in the `priceConfigs` mapping
* - price The value determining how much a subdomain under a particular parent would cost
* - feePercentage The value determining how much fee is charged for a subdomain registration
Expand All @@ -14,55 +15,29 @@ import { IZNSPricer } from "../types/IZNSPricer.sol";
*/
interface IZNSFixedPricer is IZNSPricer {
/**
* @notice Emitted when the `PriceConfig.price` is set in state for a specific `domainHash`
* @notice Emitted when the `FixedPriceConfig.price` is set in state for a specific `domainHash`
* @param domainHash The hash of the domain who sets the price for subdomains
* @param newPrice The new price value set
*/
event PriceSet(bytes32 indexed domainHash, uint256 indexed newPrice);

/**
* @notice Emitted when the `PriceConfig.feePercentage` is set in state for a specific `domainHash`
* @notice Emitted when the `FixedPriceConfig.feePercentage` is set in state for a specific `domainHash`
* @param domainHash The hash of the domain who sets the feePercentage for subdomains
* @param feePercentage The new feePercentage value set
*/
event FeePercentageSet(bytes32 indexed domainHash, uint256 indexed feePercentage);

struct PriceConfig {
struct FixedPriceConfig {
uint256 price;
uint256 feePercentage;
bool isSet;
}

function initialize(address _accessController, address _registry) external;

function setPrice(bytes32 domainHash, uint256 _price) external;

function getPrice(
bytes32 parentHash,
string calldata label,
bool skipValidityCheck
) external view returns (uint256);

function setFeePercentage(
bytes32 domainHash,
uint256 feePercentage
) external;

function getFeeForPrice(
bytes32 parentHash,
uint256 price
) external view returns (uint256);

function getPriceAndFee(
bytes32 parentHash,
string calldata label,
bool skipValidityCheck
) external view returns (uint256 price, uint256 fee);

function setPriceConfig(
bytes32 domainHash,
PriceConfig calldata priceConfig
) external;
function encodeConfig(
FixedPriceConfig memory config
) external pure returns (bytes memory);

function setRegistry(address registry_) external;
function decodePriceConfig(
bytes memory priceConfig
) external pure returns (FixedPriceConfig memory);
}
35 changes: 16 additions & 19 deletions contracts/types/IZNSPricer.sol → contracts/price/IZNSPricer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,16 @@ pragma solidity 0.8.26;
*/
interface IZNSPricer {
/**
* @notice Reverted when someone is trying to buy a subdomain under a parent that is not set up for distribution.
* Specifically it's prices for subdomains.
* @notice Emitted when the given price config is not the expected length
*/
error ParentPriceConfigNotSet(bytes32 parentHash);
error IncorrectPriceConfigLength();

/**
* @notice Reverted when domain owner is trying to set it's stake fee percentage
* higher than 100% (uint256 "10,000").
*/
error FeePercentageValueTooLarge(uint256 feePercentage, uint256 maximum);

/**
* @notice Reverted when `maxLength` smaller than `baseLength`.
*/
error MaxLengthSmallerThanBaseLength(bytes32 domainHash);

/**
* @notice Reverted when `curveMultiplier` AND `baseLength` are 0.
*/
error DivisionByZero(bytes32 domainHash);

/**
* @dev `parentHash` param is here to allow pricer contracts
* to have different price configs for different subdomains
Expand All @@ -41,28 +30,36 @@ interface IZNSPricer {
* possible to register.
*/
function getPrice(
bytes32 parentHash,
bytes memory parentPriceConfig,
string calldata label,
bool skipValidityCheck
) external view returns (uint256);
) external pure returns (uint256);

/**
* @dev Fees are only supported for PaymentType.STAKE !
* This function will NOT be called if PaymentType != PaymentType.STAKE
* Instead `getPrice()` will be called.
*/
function getPriceAndFee(
bytes32 parentHash,
bytes memory parentPriceConfig,
string calldata label,
bool skipValidityCheck
) external view returns (uint256 price, uint256 fee);
) external pure returns (uint256 price, uint256 fee);

/**
* @notice Returns the fee for a given price.
* @dev Fees are only supported for PaymentType.STAKE !
*/
function getFeeForPrice(
bytes32 parentHash,
bytes memory parentPriceConfig,
uint256 price
) external view returns (uint256);
) external pure returns (uint256);

/**
* @notice Validate a given price config
* @param priceConfig The price config to validate
*/
function validatePriceConfig(
bytes memory priceConfig
) external pure;
}
Loading