IDotnsNameEscrow
Title: Dotns Name Escrow Interface
Escrows refundable deposits for registered names and manages the release lifecycle.
Note: security-contact: admin@parity.io
Functions
reserves
Returns total amount of assets liabilities reserved for withdrawals.
function reserves(address asset) external view returns (uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
asset | address | Asset address. address(0) denotes native token. |
getReleasePosition
Returns the escrow state for a token.
function getReleasePosition(uint256 tokenId)
external
view
returns (ReleasePosition memory position);
releasedTokenCount
Returns the number of tokens currently held by escrow pending reclaim or withdrawal.
function releasedTokenCount() external view returns (uint256 count);
Returns
| Name | Type | Description |
|---|---|---|
count | uint256 | Number of released tokens not yet reclaimed. |
releasedTokens
Returns a bounded paginated slice of released token identifiers.
limit must be non-zero and at most MAX_RELEASED_PAGE_SIZE, otherwise
Note: reverts: InvalidPageSize.
function releasedTokens(
uint256 start,
uint256 limit
)
external
view
returns (uint256[] memory tokenIds);
Parameters
| Name | Type | Description |
|---|---|---|
start | uint256 | Start index into the released-token set. |
limit | uint256 | Maximum number of token identifiers to return. |
deposit
Records an asset deposit position for a token.
Only the configured controller may call this, otherwise @custom:reverts NotController.
params.amount must equal msg.value, otherwise @custom:reverts InvalidAmount; a
zero amount is accepted so cross-payer and free-tier registrations can still seed a
position that the release lifecycle can advance. Only native deposits are accepted
today, so a non-zero params.asset triggers @custom:reverts AssetNotSupported, and
a zero params.recipient triggers @custom:reverts InvalidRecipient. The slot for
params.tokenId must be empty (sentinel: position.recipient == address(0)):
a previously funded position triggers @custom:reverts PositionAlreadyFunded, and a
position already in the released phase triggers @custom:reverts AlreadyReleased.
Emits @custom:emits NativeDepositRecorded once the deposit is booked.
function deposit(DepositParams calldata params) external payable;
depositProtocolFee
Records a cross-paid registration fee into the protocol fee pot.
Only the configured controller may call this, otherwise @custom:reverts NotController.
msg.value must be non-zero, otherwise @custom:reverts InvalidAmount. Emits
Note:
emits: CrossTierFeePaid with isRegistration = true once the fee is booked.
function depositProtocolFee(ProtocolFeeDepositParams calldata params) external payable;
creditOverpayment
Credits msg.value to recipient's pull-payment ledger so the caller can later
pull the balance with @custom:func claimWithdrawal.
Only the configured controller may call this, otherwise @custom:reverts NotController.
recipient must be non-zero (@custom:reverts InvalidRecipient) and msg.value must
be non-zero (@custom:reverts InvalidAmount). Used by the registrar controller to
refund overpayment without pushing native value into a potentially reverting
contract receiver. Emits @custom:emits OverpaymentRefunded once the credit lands.
function creditOverpayment(address recipient) external payable;
Parameters
| Name | Type | Description |
|---|---|---|
recipient | address | Address whose pending balance should grow by msg.value. |
chargeTransferFee
Charges the transfer fee and rebinds the token's escrow position to the new holder.
Only the configured registrar may call this, otherwise @custom:reverts NotRegistrar. When a fee is owed, the attached value must cover it or @custom:reverts InsufficientValue. Whenever a position exists for the token and the NFT is leaving its prior recipient, the position recipient is rebound to the new holder so the deposit (when funded) and the lifecycle marker (when zero-amount) both follow the NFT. The escrow does not refund anyone at transfer time; the only path back to the locked deposit is for the current holder to release into escrow and wait the cooldown. Emits @custom:emits CrossTierFeePaid (non-registration) when a non-zero fee is credited to the protocol fee pot, and credits any surplus value to the payer on the time-locked refund ledger via @custom:emits RefundCredited.
function chargeTransferFee(ChargeTransferFeeParams calldata params)
external
payable
returns (uint256 charged);
Returns
| Name | Type | Description |
|---|---|---|
charged | uint256 | Amount actually credited to the protocol fee pot. |
protocolFees
Returns the cumulative protocol fee balance, non-refundable and accumulating.
function protocolFees() external view returns (uint256 balance);
Returns
| Name | Type | Description |
|---|---|---|
balance | uint256 | Current protocol fee balance, in wei. |
release
Releases a token into escrow and starts the withdrawal cooldown.
First step of the phased lifecycle. The caller must be the current NFT holder and the
current position recipient (the field is rebound to the holder on every transfer that
moves the name off the prior recipient), otherwise @custom:reverts NotRefundRecipient.
Approved operators cannot release on behalf of the holder because the recipient field
is keyed to the holder, not to any approval set, which keeps the deposit refund tied
to the on-chain owner. The slot for tokenId must already hold a position (sentinel:
position.recipient != address(0)); an unseeded slot triggers @custom:reverts
DepositNotConfigured, and a position already in the released phase triggers
Note:
reverts: AlreadyReleased. Zero-amount positions are still releasable so every
minted name has a reachable lifecycle. The escrow must additionally be approved to
move the NFT, otherwise @custom:reverts EscrowNotApproved. Emits @custom:emits
NameReleased once the NFT is moved into custody.
Release stamps two independent clocks. withdrawAvailableAt (release + cooldown)
opens the deposit withdrawal; redeemableUntil (release + redeemWindow) closes the
holder's exclusive redeem phase and opens permissionless reclaim. Both are snapshots
so later policy changes never move an in-flight position. A release attempted while
redeemWindow is unseeded triggers @custom:reverts RedeemWindowNotConfigured.
function release(uint256 tokenId) external;
withdraw
Credits the refundable deposit for a released token to the recipient's pending balance.
Second step of the phased lifecycle. The position must already be released
(@custom:reverts NotReleased otherwise) and not yet claimed (@custom:reverts
AlreadyClaimed on re-entry). Only the current position recipient (the address that
released the name, which mirrored the NFT holder at that moment) may call this,
otherwise @custom:reverts NotRefundRecipient, and block.timestamp must have reached
withdrawAvailableAt, otherwise @custom:reverts WithdrawalTooEarly. Refunds are backed
entirely by the per-asset tokenReserved pool; if that reserve is short,
Note: reverts: InsufficientFunds. Protocol fees never back a refund. Funds are not transferred here, only credited to the pull-payment ledger. Emits @custom:emits RefundWithdrawn once the credit lands.
function withdraw(uint256 tokenId) external;
claimWithdrawal
Pulls the caller's accumulated pending refund balance.
Final step of the phased lifecycle. Pull-payment isolation: each recipient owns an independent ledger entry, so a failing or reentrant receiver cannot block other users' withdrawals. The caller must have a positive pending balance, otherwise
Notes:
-
reverts: NoPendingWithdrawal; a failing native transfer triggers
-
reverts: RefundFailed. Emits @custom:emits WithdrawalClaimed once the transfer succeeds.
function claimWithdrawal() external returns (uint256 amount);
Returns
| Name | Type | Description |
|---|---|---|
amount | uint256 | Native amount transferred to the caller. |
pendingWithdrawal
Returns the pending refund balance owed to recipient.
function pendingWithdrawal(address recipient) external view returns (uint256 amount);
Returns
| Name | Type | Description |
|---|---|---|
amount | uint256 | Native amount currently credited to recipient and pullable via claimWithdrawal. |
reclaim
Transfers a released token whose redeem window has elapsed to a new owner.
Hands the NFT back to the controller for re-registration. Only the configured
controller may call this, otherwise @custom:reverts NotController, and the position
must be released with redeemableUntil reached, otherwise @custom:reverts
NotReclaimable. Emits @custom:emits NameReclaimed once custody is transferred.
Reclaim does not require the deposit to have been withdrawn first. If the position
still holds value, this call settles it: the amount is debited from tokenReserved
(@custom:reverts InsufficientFunds if the reserve is short) and credited to the
previous recipient's pull-payment balance, claimable through @custom:function
claimWithdrawal with no deadline. That is what keeps a name recyclable when its
previous holder never returns: the value follows them, the name does not wait for them.
Emits @custom:emits RefundWithdrawn on settlement.
function reclaim(uint256 tokenId, address newOwner) external;
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
newOwner | address | Address of the new registrant taking over the name. |
isReclaimable
Returns whether a token may currently be reclaimed out of escrow custody.
True once the position is released and its redeem window has elapsed. Whether the
deposit was ever withdrawn makes no difference: @custom:function reclaim settles any
outstanding amount as part of the transfer.
Both @custom:function reclaim and @custom:function IDotnsRegistrar.available derive
their answer from isReclaimable, so a name is advertised as registrable exactly when
registering it would succeed. Consumers should call isReclaimable rather than
rebuilding the condition from @custom:function getReleasePosition.
function isReclaimable(uint256 tokenId) external view returns (bool reclaimable);
Returns
| Name | Type | Description |
|---|---|---|
reclaimable | bool | True when @custom:function reclaim would succeed for tokenId. |
redeem
Returns a released token to its previous holder during the redeem window.
The undo for an accidental release, and the reason the redeem window exists. Only the
position recipient may call this (@custom:reverts NotRefundRecipient otherwise), the
position must be released and not yet withdrawn, and block.timestamp must still be
below redeemableUntil; a position failing any of those is not redeemable and
Note: reverts: NotRedeemable. No value moves. The position keeps its recipient, asset and amount, so the deposit stays locked exactly as it was before the release and the name returns to its pre-release state, releasable again later on a fresh pair of clocks. Excluding withdrawn positions is deliberate: a holder who has already pulled the deposit would otherwise recover the name without it being deposit-backed, breaking the one-deposit- per-live-name bound. The choice is therefore exclusive — take the value back, or take the name back. Emits @custom:emits NameRedeemed once custody returns.
function redeem(uint256 tokenId) external;
updateCooldown
Updates the cooldown duration for future releases.
Owner-only. Affects only releases recorded after this call; positions already released
keep the withdrawAvailableAt snapshot taken at their release time. newCooldown
must be non-zero, otherwise @custom:reverts InvalidCooldown, and must not exceed the
contract's MAX_COOLDOWN upper bound, otherwise @custom:reverts CooldownTooLong; the
bound keeps the release-to-reclaim window short and protects the uint64 cast in
release from truncation. Emits @custom:emits CooldownUpdated with the prior and new
values.
function updateCooldown(uint256 newCooldown) external;
updateRedeemWindow
Updates the redeem window for future releases.
Owner-only. Affects only releases recorded after this call; positions already released
keep the redeemableUntil snapshot taken at their release time. newRedeemWindow must
fall within MIN_REDEEM_WINDOW and MAX_REDEEM_WINDOW inclusive, otherwise
Note:
reverts: RedeemWindowTooShort or @custom:reverts RedeemWindowTooLong. The floor
keeps the window long enough to be worth having, so no setting the owner can choose
leaves a holder without a usable chance to recover an accidental release; the ceiling
limits how long a released name can be held out of circulation and protects the
uint64 cast in release from truncation. Emits @custom:emits RedeemWindowUpdated with
the prior and new values.
This is also the post-upgrade seeding hook: pair it with upgradeToAndCall so an
upgraded proxy never runs with an unseeded window.
function updateRedeemWindow(uint256 newRedeemWindow) external;
cooldown
Delay after release before the deposit withdrawal may be credited.
function cooldown() external view returns (uint256 duration);
Returns
| Name | Type | Description |
|---|---|---|
duration | uint256 | Current cooldown in seconds. |
redeemWindow
Period after release during which only the previous holder may act.
function redeemWindow() external view returns (uint256 duration);
Returns
| Name | Type | Description |
|---|---|---|
duration | uint256 | Current redeem window in seconds. |
claimRefund
Pulls a single time-locked refund entry.
Caller must be the entry's recipient (@custom:reverts NotRefundRecipient otherwise),
the entry must exist (@custom:reverts NoSuchRefundEntry on a deleted or unknown id),
and block.timestamp must have reached availableAt (@custom:reverts
RefundLocked otherwise). The entry is deleted before the transfer; a failing native
transfer triggers @custom:reverts RefundFailed. Emits @custom:emits RefundClaimed.
function claimRefund(uint256 entryId) external returns (uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
entryId | uint256 | Identifier of the entry to claim. |
Returns
| Name | Type | Description |
|---|---|---|
amount | uint256 | Native amount transferred to the caller. |
claimRefundsBatch
Pulls multiple time-locked refund entries in one call.
Atomic: any invalid entry in the batch (wrong recipient, missing, or locked) reverts
the entire call. The batch size is bounded by MAX_REFUND_PAGE_SIZE
(@custom:reverts InvalidPageSize otherwise). Aggregates the per-entry amounts and
transfers once; on transfer failure @custom:reverts RefundFailed. Emits
Note: emits: RefundClaimed once per entry.
function claimRefundsBatch(uint256[] calldata entryIds) external returns (uint256 totalAmount);
Parameters
| Name | Type | Description |
|---|---|---|
entryIds | uint256[] | List of entry identifiers to claim. |
Returns
| Name | Type | Description |
|---|---|---|
totalAmount | uint256 | Sum of the credited amounts transferred to the caller. |
pendingRefundCount
Returns the number of pending refund entries owed to recipient.
function pendingRefundCount(address recipient) external view returns (uint256 count);
pendingRefundIds
Returns up to limit pending refund entry ids for recipient, starting at
offset.
Limit must be in (0, MAX_REFUND_PAGE_SIZE], otherwise @custom:reverts
InvalidPageSize.
function pendingRefundIds(
address recipient,
uint256 offset,
uint256 limit
)
external
view
returns (uint256[] memory entryIds);
pendingRefunds
Returns up to limit pending refund entries for recipient, paired with their
entry ids.
Limit must be in (0, MAX_REFUND_PAGE_SIZE], otherwise @custom:reverts
InvalidPageSize.
function pendingRefunds(
address recipient,
uint256 offset,
uint256 limit
)
external
view
returns (uint256[] memory entryIds, RefundEntry[] memory entries);
refundEntry
Returns a single refund entry by id, or a zero-filled struct if the id is unknown.
function refundEntry(uint256 entryId) external view returns (RefundEntry memory entry);
Events
NativeDepositRecorded
Emitted when a native-token deposit is recorded.
event NativeDepositRecorded(uint256 indexed tokenId, uint256 amount);
NameReleased
Emitted when a token is released into escrow.
event NameReleased(
uint256 indexed tokenId,
address indexed recipient,
address indexed asset,
uint256 amount,
uint256 withdrawAvailableAt,
uint256 redeemableUntil
);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
recipient | address | Refund recipient snapshotted at release time. |
asset | address | Deposit asset. address(0) denotes native token. |
amount | uint256 | |
withdrawAvailableAt | uint256 | Earliest withdrawal timestamp. |
redeemableUntil | uint256 | Timestamp at which the redeem window closes and reclaim opens. |
RefundWithdrawn
Emitted when a refund is credited to the recipient's pending balance.
event RefundWithdrawn(
uint256 indexed tokenId, address indexed recipient, address indexed asset, uint256 amount
);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
recipient | address | |
asset | address | Refund asset. address(0) denotes native token. |
amount | uint256 |
WithdrawalClaimed
Emitted when a recipient pulls their accumulated pending refund balance.
event WithdrawalClaimed(address indexed recipient, uint256 amount);
RefundCredited
Emitted when a refund is credited to the time-locked refund ledger.
event RefundCredited(
address indexed recipient,
uint256 indexed entryId,
uint256 amount,
uint64 availableAt,
uint256 indexed tokenId
);
Parameters
| Name | Type | Description |
|---|---|---|
recipient | address | Address that may claim the entry once availableAt has elapsed. |
entryId | uint256 | Newly-assigned identifier for the credited entry. |
amount | uint256 | Native value credited. |
availableAt | uint64 | Earliest block timestamp at which the recipient may claim. |
tokenId | uint256 | Token associated with the credit, retained for traceability. |
RefundClaimed
Emitted when a recipient claims a single refund entry.
event RefundClaimed(address indexed recipient, uint256 indexed entryId, uint256 amount);
Parameters
| Name | Type | Description |
|---|---|---|
recipient | address | Address that pulled the entry. |
entryId | uint256 | Identifier of the claimed entry, now deleted. |
amount | uint256 | Native value transferred to recipient. |
NameReclaimed
Emitted when a released token is reclaimed by a new owner via registration.
event NameReclaimed(
uint256 indexed tokenId, address indexed previousRecipient, address indexed newOwner
);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
previousRecipient | address | Address that received the refund for the prior registration. |
newOwner | address |
CooldownUpdated
Emitted when the cooldown duration for future releases is updated.
event CooldownUpdated(uint256 indexed currentCooldown, uint256 indexed newCooldown);
RedeemWindowUpdated
Emitted when the redeem window for future releases is updated.
event RedeemWindowUpdated(uint256 indexed currentRedeemWindow, uint256 indexed newRedeemWindow);
NameRedeemed
Emitted when a released token is redeemed by its previous holder.
The counterpart to @custom:emits NameReleased: custody returns to recipient and the
deposit stays locked, so no value event accompanies this.
event NameRedeemed(uint256 indexed tokenId, address indexed recipient);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
recipient | address | Address the NFT was returned to, which is also the position recipient. |
CrossTierFeePaid
Emitted when a cross-paid fee is paid into the protocol fee pot.
event CrossTierFeePaid(
uint256 indexed tokenId,
address indexed payer,
address indexed recipient,
uint256 amount,
bool isRegistration
);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
payer | address | Original msg.sender whose value funded the fee. |
recipient | address | |
amount | uint256 | |
isRegistration | bool | True when emitted from depositProtocolFee; false from chargeTransferFee. |
OverpaymentRefunded
Emitted when overpayment is refunded to the payer.
event OverpaymentRefunded(address indexed payer, uint256 amount);
Errors
NotController
Thrown when the caller is not the configured registrar controller.
error NotController(address caller);
NotRegistrar
Thrown when the caller is not the configured registrar.
error NotRegistrar(address caller);
InvalidRecipient
Thrown when the supplied refund recipient is invalid (e.g. zero address).
error InvalidRecipient();
InsufficientValue
Thrown when the attached call value is insufficient to cover the computed charge.
error InsufficientValue();
InsufficientFunds
Thrown when the per-asset reserve cannot cover the refund owed.
error InsufficientFunds(uint256 tokenId, uint256 owed, uint256 available);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
owed | uint256 | |
available | uint256 | Reserve balance available for the asset. |
AssetNotSupported
Thrown when assets being deposited are not supported by the escrow.
error AssetNotSupported(address asset);
InvalidPageSize
Thrown when the configured page size is invalid.
error InvalidPageSize(uint256 limit);
InvalidCooldown
Thrown when the configured cooldown is invalid.
error InvalidCooldown();
CooldownTooLong
Thrown when the supplied cooldown exceeds the contract's configured upper bound.
error CooldownTooLong(uint256 supplied, uint256 maxAllowed);
Parameters
| Name | Type | Description |
|---|---|---|
supplied | uint256 | Cooldown value the caller asked for. |
maxAllowed | uint256 | Upper bound enforced by the contract. |
RedeemWindowNotConfigured
Thrown by release when the redeem window has never been seeded.
A configuration fault rather than a bad argument: the caller supplied nothing, and the deployment is missing a policy value. Fails the release closed rather than collapsing the holder's exclusive redeem phase to zero length, which would hand the name to whoever is watching the moment it is released. Cleared by calling
Note: function: updateRedeemWindow.
error RedeemWindowNotConfigured();
RedeemWindowTooShort
Thrown when the supplied redeem window is below the contract's configured lower bound.
error RedeemWindowTooShort(uint256 supplied, uint256 minAllowed);
Parameters
| Name | Type | Description |
|---|---|---|
supplied | uint256 | Redeem window value the caller asked for. |
minAllowed | uint256 | Lower bound enforced by the contract. |
RedeemWindowTooLong
Thrown when the supplied redeem window exceeds the contract's configured upper bound.
error RedeemWindowTooLong(uint256 supplied, uint256 maxAllowed);
Parameters
| Name | Type | Description |
|---|---|---|
supplied | uint256 | Redeem window value the caller asked for. |
maxAllowed | uint256 | Upper bound enforced by the contract. |
InvalidAmount
Thrown when the supplied amount is invalid.
error InvalidAmount();
InvalidAsset
Thrown when the supplied ERC20 asset is invalid.
error InvalidAsset();
PositionAlreadyFunded
Thrown when a deposit position is already funded.
error PositionAlreadyFunded(uint256 tokenId);
DepositNotConfigured
Thrown when no deposit is configured for the token.
error DepositNotConfigured(uint256 tokenId);
AlreadyReleased
Thrown when the token has already been released.
error AlreadyReleased(uint256 tokenId);
NotReleased
Thrown when the token has not been released.
error NotReleased(uint256 tokenId);
AlreadyClaimed
Thrown when the refund has already been claimed.
error AlreadyClaimed(uint256 tokenId);
NotReclaimable
Thrown when a token is not in a reclaimable state.
Reclaimable means released with the redeem window elapsed. A released token still inside its window is deliberately not reclaimable: that window belongs to the previous holder. Whether the deposit was withdrawn is irrelevant, because reclaim settles any unwithdrawn amount itself.
error NotReclaimable(uint256 tokenId);
NotRedeemable
Thrown when a token is not in a redeemable state.
Redeemable means released, not yet withdrawn, and still inside the redeem window. A withdrawn position is excluded on purpose: the holder has already taken the deposit value out, so returning the name as well would leave it unbacked.
error NotRedeemable(uint256 tokenId);
EscrowNotApproved
Thrown when escrow is not approved to transfer the token.
error EscrowNotApproved(uint256 tokenId);
NotRefundRecipient
Thrown when the caller is not the refund recipient.
error NotRefundRecipient(address caller, uint256 tokenId);
WithdrawalTooEarly
Thrown when withdrawal is attempted before cooldown has elapsed.
error WithdrawalTooEarly(uint256 tokenId, uint256 availableAt, uint256 currentTime);
Parameters
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
availableAt | uint256 | Earliest withdrawal timestamp. |
currentTime | uint256 | Current block timestamp. |
RefundFailed
Thrown when a refund transfer fails.
error RefundFailed(uint256 tokenId);
NoPendingWithdrawal
Thrown when claimWithdrawal() is called but the caller has no pending balance.
error NoPendingWithdrawal();
NoSuchRefundEntry
Thrown when a refund entry is referenced but does not exist.
error NoSuchRefundEntry(uint256 entryId);
RefundLocked
Thrown when a refund entry is claimed before its availableAt cooldown has
elapsed.
error RefundLocked(uint256 entryId, uint64 availableAt);
NotAcceptedTransfer
Thrown when escrow receives an ERC721 transfer from a non-registrar source.
error NotAcceptedTransfer(address caller);
UnsolicitedDeposit
Thrown when escrow receives a registrar-sourced ERC721 transfer that does not correspond to a live release. Blocks holders who try to push a token into custody by calling @custom:function safeTransferFrom directly without going through @custom:function release, which would otherwise trap the NFT and any deposit permanently.
error UnsolicitedDeposit(uint256 tokenId);
Structs
DepositParams
Parameters for recording a deposit position.
The refund recipient is seeded at deposit time but is not locked: it rebinds to the current NFT holder on every transfer that moves the name off the prior recipient, so the deposit follows the name rather than the original payer. Only the current holder can release into escrow and pull the refund.
struct DepositParams {
uint256 tokenId;
address asset;
uint256 amount;
address recipient;
}
Properties
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
asset | address | Deposit asset. The zero address denotes the native token. |
amount | uint256 | |
recipient | address | Initial refund recipient; rebound to the current NFT holder on transfer. |
ProtocolFeeDepositParams
Parameters for recording a cross-paid registration fee into the protocol fee pot.
The pot is non-refundable and only accumulates; it never backs a refund. payer is
preserved purely for event accounting since the fee itself is non-refundable.
struct ProtocolFeeDepositParams {
uint256 tokenId;
address payer;
address recipient;
}
Properties
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | |
payer | address | Original msg.sender of the controller's register call. |
recipient | address | The NFT registrant the fee was paid on behalf of. |
ChargeTransferFeeParams
Inputs for charging transfer friction and rebinding the escrow position.
The fee charged is the name's own price returned by @custom:function PopRules.transferFloor, settled to the protocol fee pot. The deposit, when present, travels with the NFT: the position is rebound to the recipient so the new holder is the only address that can later release into escrow and unlock the locked value. There is no transfer-time refund path.
struct ChargeTransferFeeParams {
uint256 tokenId;
uint256 transferFee;
address payer;
address to;
}
Properties
| Name | Type | Description |
|---|---|---|
tokenId | uint256 | Token whose escrow position is charged and rebound to the recipient. |
transferFee | uint256 | The name's own curve price on a downward or cross-reach transfer. |
payer | address | Original sender of the registrar transfer entrypoint. |
to | address | NFT recipient. Becomes the new position recipient whenever a position exists. |
ReleasePosition
Canonical escrow state for a token.
Tracks the phased lifecycle as two flags: released flips on release (NFT in escrow,
cooldown started); claimed flips on withdraw (refund credited to the pull-payment
ledger). The position is deleted on reclaim, freeing the slot for re-registration.
struct ReleasePosition {
address recipient;
address asset;
uint256 amount;
uint64 withdrawAvailableAt;
bool released;
bool claimed;
uint64 redeemableUntil;
}
Properties
| Name | Type | Description |
|---|---|---|
recipient | address | |
asset | address | Deposit asset. address(0) denotes native token. |
amount | uint256 | |
withdrawAvailableAt | uint64 | Earliest timestamp at which withdrawal is permitted. |
released | bool | |
claimed | bool | |
redeemableUntil | uint64 | Timestamp at which the holder's exclusive redeem window closes and permissionless reclaim opens. Appended last so every pre-existing field keeps its byte offset across the upgrade; it packs into the trailing slot alongside withdrawAvailableAt, released and claimed without consuming a new one. |
RefundEntry
Time-locked refund entry produced when the protocol owes a recipient value outside the registration-overpayment path.
Every credit creates a fresh entry with its own availableAt; later credits do not
reset earlier entries' clocks. Recipients claim entries individually or in batches.
struct RefundEntry {
address recipient;
uint256 amount;
uint64 availableAt;
uint256 tokenId;
}
Properties
| Name | Type | Description |
|---|---|---|
recipient | address | Address that may claim this entry once availableAt has elapsed. |
amount | uint256 | Native value credited. |
availableAt | uint64 | Earliest block timestamp at which the recipient may claim. |
tokenId | uint256 | Token this entry was produced for, retained for traceability. |