V3 Locker
V3 Locker は、許可リスト登録済みの INonfungiblePositionManager が発行した ERC721 流動性ポジションを保管します。ロック中は NFT の価格レンジを変更できません。承認されたアカウントは手数料を回収でき、任意のユーザーが流動性を追加できます。
ETERNAL_LOCK は type(uint256).max です。永久ロックは引き出しや流動性削減ができませんが、移転、手数料回収、流動性追加は可能です。
書き込み関数
lock
function lock(LockParams calldata params)
external
payable
returns (uint256 lockId)
ポジション NFT を保管し、ロック前の累積手数料を回収して、選択したロック手数料を適用しロックを作成します。
| フィールド | 型 | 説明 |
|---|---|---|
params.nftPositionManager | INonfungiblePositionManager | 許可リスト登録済み Position Manager。 |
params.nft_id | uint256 | 呼び出し元が所有し承認済みの NFT ID。 |
params.dustRecipient | address | ロック前の累積手数料の受取先。 |
params.owner | address | 初期ロック Owner。ゼロ不可。 |
params.additionalCollector | address | 任意の Additional Collector。 |
params.collectAddress | address | 自動回収の純収益受取先。ゼロ不可。 |
params.unlockDate | uint256 | 秒単位の将来の Unix 時刻、または ETERNAL_LOCK。 |
params.countryCode | uint16 | COUNTRY_LIST が受け付けるコード。 |
params.feeName | string | 通常は DEFAULT。r が空でない場合は無視されます。 |
params.r | bytes[] | 名前付き手数料では空。動的手数料では FeeResolver payload。 |
新しいロック ID lockId を返します。
アクセス / payable: NFT Owner/呼び出し元;payable;nonReentrant。
Position Manager、Owner、回収先、日時、国・地域が有効で、NFT が承認済みである必要があります。既存の累積手数料は先に dustRecipient へ回収され、新たなロック流動性として課金されません。ネイティブ固定手数料では msg.value が完全一致し、ERC20 固定手数料では allowance が必要です。保存される ucf は選択した回収手数料率です。NONCE を増加し onLock を発行します。
params.r が空でない場合、FEE_RESOLVER.useFee(params.r, msg.sender) が動的手数料を提供します。署名 payload は nonce、ユーザー、チェーン、Resolver を拘束します。
collect
function collect(
uint256 _lockId,
address _recipient,
uint128 _amount0Max,
uint128 _amount1Max
) external returns (
uint256 amount0,
uint256 amount1,
uint256 fee0,
uint256 fee1
)
ロック済みポジションから token0/token1 手数料を回収します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 手数料を回収するロック。 |
_recipient | address | 通常呼び出し時の純収益受取先。Auto Collector ではプロトコル手数料の受取先。 |
_amount0Max | uint128 | token0 の最大回収量。 |
_amount1Max | uint128 | token1 の最大回収量。 |
| 戻り値 | 型 | 説明 |
|---|---|---|
amount0 | uint256 | ユーザー側受取先へ渡す token0 純額。 |
amount1 | uint256 | ユーザー側受取先へ渡す token1 純額。 |
fee0 | uint256 | token0 のプロトコル手数料。 |
fee1 | uint256 | token1 のプロトコル手数料。 |
アクセス / payable: ロック Owner、additionalCollector、または AUTO_COLLECT_ACCOUNT;nonpayable;nonReentrant。
通常の呼び出しではプロトコル手数料を FEE_ADDR_COLLECT、純収益を _recipient に送ります。AUTO_COLLECT_ACCOUNT では手数料を _recipient、純収益をロックの collectAddress に送ります。ucf == 0 の場合、Auto Collector を含め Position Manager は全額を _recipient に直接送ります。AUTO_COLLECT_ACCOUNT は信頼済みアカウントとして扱い、ゼロ受取先は避けてください。純額 amount0/amount1 と手数料 fee0/fee1 を返します。
collectBatchPreview
function collectBatchPreview(
uint256[] calldata lockIds,
address[] calldata recipients,
uint128[] calldata amount0Maxs,
uint128[] calldata amount1Maxs
) external
複数の collect をシミュレーションし、意図的な revert で正確な結果を返します。
| 名前 | 型 | 説明 |
|---|---|---|
lockIds | uint256[] | プレビュー対象のロック。 |
recipients | address[] | 各 collect の受取先パラメータ。 |
amount0Maxs | uint128[] | 各ロックの token0 最大値。 |
amount1Maxs | uint128[] | 各ロックの token1 最大値。 |
アクセス / payable: 各項目は collect と同じ認可を使用;nonpayable;nonReentrant。
配列長が異なると LengthMismatch() で revert します。eth_call のみで呼び出してください。成功時は次のエラーで revert します。
error CollectBatchPreviewResult(CollectPreviewItem[] previews);
各項目にはロック ID、受取先、トークンアドレス、純額、手数料が含まれます。revert により Position Manager、トークン、Locker の状態が原子的に戻ります。ほかの revert は実際の失敗です。トランザクションとして送信しないでください。
increaseLiquidity
function increaseLiquidity(
uint256 _lockId,
INonfungiblePositionManager.IncreaseLiquidityParams calldata params
) external payable returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
)
token0/token1 の流動性を追加します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 流動性を受け取るロック。 |
params.tokenId | uint256 | ロックの NFT ID と一致する必要があります。 |
params.amount0Desired | uint256 | 呼び出し元から転送する token0 の最大量。 |
params.amount1Desired | uint256 | 呼び出し元から転送する token1 の最大量。 |
params.amount0Min | uint256 | token0 の最小使用量。 |
params.amount1Min | uint256 | token1 の最小使用量。 |
params.deadline | uint256 | Position Manager の期限。 |
| 戻り値 | 型 | 説明 |
|---|---|---|
liquidity | uint128 | 追加された流動性。 |
amount0 | uint256 | 使用した token0 数量。 |
amount1 | uint256 | 使用した token1 数量。 |
アクセス / payable: 任意の呼び出し元;payable;nonReentrant。
両トークンの承認が必要です。未使用分は呼び出し元へ返金され、onIncreaseLiquidity を発行します。msg.value は転送されないため、ネイティブトークンは 0 にしてください。互換性があれば Position Manager への直接操作の方が Gas を抑えられる場合があります。
decreaseLiquidity
function decreaseLiquidity(
uint256 _lockId,
INonfungiblePositionManager.DecreaseLiquidityParams calldata params
) external payable returns (uint256 amount0, uint256 amount1)
時限ロックの期限後に流動性を削減し、トークンを Owner へ送ります。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 流動性を削減するロック。 |
params.tokenId | uint256 | ロックの NFT ID と一致する必要があります。 |
params.liquidity | uint128 | 削減する流動性。 |
params.amount0Min | uint256 | 計上される token0 の最小量。 |
params.amount1Min | uint256 | 計上される token1 の最小量。 |
params.deadline | uint256 | Position Manager の期限。 |
| 戻り値 | 型 | 説明 |
|---|---|---|
amount0 | uint256 | decreaseLiquidity が計上した token0 数量。 |
amount1 | uint256 | decreaseLiquidity が計上した token1 数量。 |
アクセス / payable: ロック Owner のみ;payable;nonReentrant。
期限切れの非永久ロックが必要です。現在の累積手数料を Locker の手数料経路で回収してから、NFT が支払う全トークンを呼び出し元へ回収します。msg.value は転送されないため 0 を送信してください。onDecreaseLiquidity を発行します。
relock
function relock(uint256 _lockId, uint256 _unlockDate) external
期間を延長または永久化します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 延長するロック。 |
_unlockDate | uint256 | 秒単位の新しいタイムスタンプ、または ETERNAL_LOCK。 |
アクセス / payable: ロック Owner のみ;nonpayable;nonReentrant。
日時は現在の unlockDate と block.timestamp の両方を超え、永久ロック以外は 10_000_000_000 未満である必要があります。期間短縮はできません。onRelock を発行します。
withdraw
function withdraw(uint256 _lockId, address _receiver) external
期限切れ時限ロックから NFT 全体を移転します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 引き出すロック。 |
_receiver | address | NFT 受取先。 |
アクセス / payable: ロック Owner のみ;nonpayable;nonReentrant。
期限切れの非永久ロックが必要です。ucf > 0 なら _receiver を通常受取先として全手数料を先に回収します。その後 NFT を移転し、ユーザーインデックスと LOCKS を削除し、onWithdraw を発行します。safe ERC721 転送を受け取れるアドレスを使用してください。
setAdditionalCollector
function setAdditionalCollector(uint256 _lockId, address _additionalCollector) external
collect を呼べる任意アカウントを設定します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 設定するロック。 |
_additionalCollector | address | Collector アドレス。ゼロアドレスで解除できます。 |
アクセス / payable: ロック Owner のみ;nonpayable;nonReentrant。ロックを更新し onSetAdditionalCollector を発行します。
setCollectAddress
function setCollectAddress(uint256 _lockId, address _collectAddress) external
自動回収の純収益受取先を設定します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 設定するロック。 |
_collectAddress | address | 非ゼロの自動回収受取先。 |
アクセス / payable: ロック Owner のみ;nonpayable;nonReentrant。onSetCollectAddress を発行します。
transferLockOwnership
function transferLockOwnership(uint256 _lockId, address _newOwner) external
2 段階の所有権移転を開始します。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 移転するロック。 |
_newOwner | address | 提案する Owner。 |
アクセス / payable: ロック Owner のみ;nonpayable;nonReentrant。
新 Owner は呼び出し元と異なる必要があります。ゼロアドレスは受け付けますが、ゼロの pending Owner は承認できません。新提案は既存の pending Owner を上書きします。onLockOwnershipTransferStarted を発行します。
acceptLockOwnership
function acceptLockOwnership(uint256 _lockId, address _collectAddress) external
移転を承認し、新しい自動回収先を選びます。
| 名前 | 型 | 説明 |
|---|---|---|
_lockId | uint256 | 承認するロック。 |
_collectAddress | address | 新しく保存する回収先。 |
アクセス / payable: pending Owner のみ;nonpayable;nonReentrant。
ユーザーインデックスを移動し、pendingOwner と additionalCollector を消去して _collectAddress を保存します。この関数はゼロの回収先を受け付けるため、クライアントで拒否してください。onTransferLockOwnership を発行します。
読み取り関数
getLock / LOCKS
function getLock(uint256 _lockId)
external view returns (Lock memory _lock);
function LOCKS(uint256 lockId) external view returns (
uint256 lock_id,
INonfungiblePositionManager nftPositionManager,
address pool,
uint256 nft_id,
address owner,
address pendingOwner,
address additionalCollector,
address collectAddress,
uint256 unlockDate,
uint16 countryCode,
uint256 ucf
);
同じフィールドを返します。getLock は struct、mapping Getter は ABI tuple です。引き出し済みまたは未知の ID は全ゼロを返します。
| パラメータ | 説明 |
|---|---|
_lockId / lockId | 読み取るロック ID。 |
getLocksLength / NONCE
function getLocksLength() external view returns (uint256);
function NONCE() external view returns (uint256);
両方とも履歴を含む次のロック ID を返し、有効ロック数ではありません。
ユーザー列挙
function getNumUserLocks(address _user) external view returns (uint256);
function getUserLockAtIndex(address _user, uint256 _index)
external view returns (Lock memory);
| パラメータ | 説明 |
|---|---|
_user | 有効ロック集合を照会する Owner。 |
_index | 0 始まりの有効集合インデックス。範囲外では revert します。 |
前者は有効ロック数、後者はインデックスに対応する ID のロックを返します。
手数料照会
function getFee(string memory _name) public view returns (FeeStruct memory);
function getFeeOptionAtIndex(uint256 _index)
external view returns (FeeStruct memory);
function getFeeOptionLength() external view returns (uint256);
| パラメータ | 説明 |
|---|---|
_name | 正確な手数料オプション名。未知の名前は revert します。 |
_index | 0 始まりの手数料集合インデックス。無効な値は revert します。 |
FeeStruct は name、lpFee、collectFee、flatFee、flatFeeToken を含みます。オプションは即時変更されるため、ロック直前に読み取ってください。
nftPositionManagerIsAllowed
function nftPositionManagerIsAllowed(address _nftPositionManager)
external view returns (bool);
その Position Manager を lock で使用できるか返します。
公開設定 Getter
function ETERNAL_LOCK() external view returns (uint256);
function FEE_DENOMINATOR() external view returns (uint256);
function COUNTRY_LIST() external view returns (address);
function FEE_RESOLVER() external view returns (address);
function AUTO_COLLECT_ACCOUNT() external view returns (address);
function FEE_ADDR_LP() external view returns (address);
function FEE_ADDR_COLLECT() external view returns (address);
function owner() external view returns (address);
定数、外部依存、特権アドレス、2 段階コントラクト所有権を公開します。
イベント
onLock
event onLock(uint256 lock_id, address nftPositionManager, uint256 nft_id, address owner, address additionalCollector, address collectAddress, uint256 unlockDate, uint16 countryCode, uint256 collectFee, address poolAddress, INonfungiblePositionManager.Position position);
lock がロックを作成したときに発行されます。ID、アカウント、解除条件、ucf 率、Pool アドレス、完全な Position snapshot を含みます。
| パラメータ | 説明 |
|---|---|
lock_id | 新しいロック ID。 |
nftPositionManager | NFT を定義する Position Manager。 |
nft_id | ポジション NFT ID。 |
owner | 初期ロック Owner。 |
additionalCollector | 任意の Collector。 |
collectAddress | 自動回収の純収益受取先。 |
unlockDate | 解除タイムスタンプまたは ETERNAL_LOCK。 |
countryCode | 検証済みの国・地域コード。 |
collectFee | 保存された ucf 率。 |
poolAddress | ポジションに対応する Factory Pool。 |
position | Position Manager の完全な Position snapshot。 |
onWithdraw
event onWithdraw(uint256 lock_id, address owner, address receiver);
引き出したロック状態を削除する前に発行されます。
| パラメータ | 説明 |
|---|---|
lock_id | 引き出されたロック。 |
owner | ロック Owner。 |
receiver | NFT 受取先。 |
onLockOwnershipTransferStarted
event onLockOwnershipTransferStarted(uint256 lockId, address currentOwner, address pendingOwner);
現在の Owner が新 Owner を提案したときに発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 移転中のロック。 |
currentOwner | 現在の Owner。 |
pendingOwner | 提案された Owner。 |
onTransferLockOwnership
event onTransferLockOwnership(uint256 lockId, address oldOwner, address newOwner, address newCollectAddress);
pending Owner が移転を承認したときに発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 移転されたロック。 |
oldOwner | 旧 Owner。 |
newOwner | 移転を承認した新 Owner。 |
newCollectAddress | 承認時に指定した回収先。 |
onSetAdditionalCollector
event onSetAdditionalCollector(uint256 lockId, address additionalCollector);
Owner が Additional Collector を変更したときに発行されます。ゼロも指定できます。
| パラメータ | 説明 |
|---|---|
lockId | 更新されたロック。 |
additionalCollector | 新しい Collector。ゼロアドレスも指定できます。 |
onSetCollectAddress
event onSetCollectAddress(uint256 lockId, address collectAddress);
Owner が非ゼロの自動回収先を変更したときに発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 更新されたロック。 |
collectAddress | 新しい非ゼロ受取先。 |
onRelock
event onRelock(uint256 lockId, uint256 unlockDate);
ロック延長後に発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 延長されたロック。 |
unlockDate | 新しい解除タイムスタンプ。 |
onIncreaseLiquidity
event onIncreaseLiquidity(uint256 lockId);
Locker wrapper で流動性を追加した後に発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 流動性が増加したロック。 |
onDecreaseLiquidity
event onDecreaseLiquidity(uint256 lockId);
期限切れロックから Locker 経由で流動性を削減した後に発行されます。
| パラメータ | 説明 |
|---|---|
lockId | 流動性が減少したロック。 |
エラー
Locker ビジネスエラー
| Error / Revert | 関連関数 | 条件 |
|---|---|---|
OWNER CANNOT = address(0) | lock | params.owner がゼロ。 |
COLLECT_ADDR | lock, setCollectAddress | collectAddress がゼロ。acceptLockOwnership はこの確認を行いません。 |
MILLISECONDS | lock, relock | 通常時刻が 10_000_000_000 以上。 |
DATE PASSED | lock, relock | 時刻が現在より後ではありません。 |
COUNTRY | lock | countryCode が検証失敗。 |
INVALID NFT POSITION MANAGER | lock | Position Manager が未許可。 |
NOT FOUND | lock, getFee | 名前付き手数料が存在しません。 |
FLAT FEE | lock | msg.value が完全一致しません。 |
Gas token transfer failed | lock, adminRefundEth | ネイティブ転送失敗。 |
OWNER | collect、collectBatchPreview、ロック管理関数 | 呼び出し元が許可された Owner、Additional Collector、Auto Collector、pending Owner ではありません。 |
NFT ID | increaseLiquidity, decreaseLiquidity | params.tokenId が nft_id と異なります。 |
ETERNAL_LOCK | decreaseLiquidity, withdraw | 永久ロックへの操作。 |
NOT YET | decreaseLiquidity, withdraw | ロック期限前。 |
DATE | relock | 新日時が unlockDate を超えません。 |
SAME OWNER | transferLockOwnership | _newOwner が現在の Owner。 |
L | setUCF | 新 _ucf が現在率未満ではありません。 |
DEFAULT | removeFee | DEFAULT の削除。 |
Fee not exists | removeFee | オプションが存在しません。 |
バッチプレビューのカスタムエラー
error CollectBatchPreviewResult(CollectPreviewItem[] previews);
error LengthMismatch();
| Custom Error | 意味 |
|---|---|
CollectBatchPreviewResult(...) | collectBatchPreview の期待される成功 payload。previews を結果としてデコードします。 |
LengthMismatch() | lockIds、recipients、amount0Maxs、amount1Maxs の長さが一致しません。 |
外部・継承エラー
| Error / Revert | 条件 |
|---|---|
STF | safeTransferFrom 失敗。通常は残高または allowance 不足。 |
ST | safeTransfer 失敗。 |
SA | safeApprove 失敗。 |
Ownable: caller is not the owner | Owner 以外が管理関数を呼び出します。 |
ReentrancyGuard: reentrant call | nonReentrant 関数へ再入します。 |
Panic(0x11) | 算術 underflow/overflow。 |