Saltar al contenido principal

V3 Locker

V3 Locker custodia posiciones de liquidez ERC721 emitidas por contratos INonfungiblePositionManager permitidos. El rango de precio del NFT no puede cambiar durante el bloqueo. Las cuentas autorizadas pueden cobrar comisiones y cualquier usuario puede incrementar la liquidez.

ETERNAL_LOCK es type(uint256).max. Un bloqueo permanente no se puede retirar ni reducir, pero se puede transferir, cobrar comisiones y recibir más liquidez.

Funciones de escritura

lock

function lock(LockParams calldata params)
external
payable
returns (uint256 lockId)

Transfiere el NFT de posición a custodia, cobra las comisiones acumuladas antes del bloqueo, aplica la comisión seleccionada y crea un bloqueo.

CampoTipoDescripción
params.nftPositionManagerINonfungiblePositionManagerPosition Manager permitido.
params.nft_iduint256ID del NFT propiedad del llamador y ya aprobado.
params.dustRecipientaddressDestinatario de las comisiones acumuladas antes del bloqueo.
params.owneraddressPropietario inicial; no puede ser cero.
params.additionalCollectoraddressCollector adicional opcional.
params.collectAddressaddressDestinatario del ingreso neto del cobro automático; no puede ser cero.
params.unlockDateuint256Timestamp Unix futuro en segundos, o ETERNAL_LOCK.
params.countryCodeuint16Código aceptado por COUNTRY_LIST.
params.feeNamestringOpción de comisión, normalmente DEFAULT; se ignora si r no está vacío.
params.rbytes[]Vacío para una comisión nominal; payload de FeeResolver para una dinámica.

Devuelve lockId, el ID del nuevo bloqueo.

Acceso / payable: propietario del NFT/llamador; payable; nonReentrant.

Position Manager, propietario, dirección de cobro, fecha y país o región deben ser válidos. El NFT debe estar aprobado. Las comisiones ya acumuladas se cobran primero a dustRecipient, evitando cobrarlas como nueva liquidez bloqueada. Una comisión fija nativa exige que msg.value coincida exactamente; una comisión fija ERC20 exige allowance. El ucf almacenado es la tasa de cobro elegida. Se incrementa NONCE y se emite onLock.

Si params.r no está vacío, FEE_RESOLVER.useFee(params.r, msg.sender) proporciona una comisión dinámica. El payload firmado vincula nonce, usuario, cadena y Resolver.

collect

function collect(
uint256 _lockId,
address _recipient,
uint128 _amount0Max,
uint128 _amount1Max
) external returns (
uint256 amount0,
uint256 amount1,
uint256 fee0,
uint256 fee1
)

Cobra comisiones de token0 y token1 de una posición bloqueada.

NombreTipoDescripción
_lockIduint256Bloqueo cuyas comisiones se cobran.
_recipientaddressDestinatario del neto para llamadores normales; destinatario de la comisión del protocolo para Auto Collector.
_amount0Maxuint128Cantidad máxima de token0 que se puede cobrar.
_amount1Maxuint128Cantidad máxima de token1 que se puede cobrar.
RetornoTipoDescripción
amount0uint256Cantidad neta de token0 entregada al destinatario del usuario.
amount1uint256Cantidad neta de token1 entregada al destinatario del usuario.
fee0uint256Comisión de protocolo en token0.
fee1uint256Comisión de protocolo en token1.

Acceso / payable: propietario, additionalCollector o AUTO_COLLECT_ACCOUNT; nonpayable; nonReentrant.

Para un llamador normal, las comisiones del protocolo van a FEE_ADDR_COLLECT y el neto a _recipient. Para AUTO_COLLECT_ACCOUNT, las comisiones van a _recipient y el neto al collectAddress del bloqueo. Si ucf == 0, Position Manager envía todo directamente a _recipient, incluso para Auto Collector. Trate AUTO_COLLECT_ACCOUNT como cuenta de confianza y evite destinatarios cero. Devuelve las cantidades netas amount0/amount1 y las comisiones fee0/fee1.

collectBatchPreview

function collectBatchPreview(
uint256[] calldata lockIds,
address[] calldata recipients,
uint128[] calldata amount0Maxs,
uint128[] calldata amount1Maxs
) external

Simula varias llamadas a collect y devuelve resultados exactos mediante un revert intencional.

NombreTipoDescripción
lockIdsuint256[]Bloqueos que se previsualizan.
recipientsaddress[]Destinatario de cada llamada a collect.
amount0Maxsuint128[]Máximo de token0 para cada bloqueo.
amount1Maxsuint128[]Máximo de token1 para cada bloqueo.

Acceso / payable: cada elemento usa la misma autorización que collect; nonpayable; nonReentrant.

Los arrays deben tener la misma longitud o revierte con LengthMismatch(). Llámela solo mediante eth_call. Una vista previa correcta revierte con:

error CollectBatchPreviewResult(CollectPreviewItem[] previews);

Cada elemento contiene ID, destinatario, direcciones de tokens, cantidades netas y comisiones. El revert revierte atómicamente el estado de Position Manager, tokens y Locker. Cualquier otro revert indica un fallo real. No transmita esta función como transacción.

increaseLiquidity

function increaseLiquidity(
uint256 _lockId,
INonfungiblePositionManager.IncreaseLiquidityParams calldata params
) external payable returns (
uint128 liquidity,
uint256 amount0,
uint256 amount1
)

Añade liquidez token0/token1.

NombreTipoDescripción
_lockIduint256Bloqueo que recibe liquidez.
params.tokenIduint256Debe coincidir con el ID del NFT bloqueado.
params.amount0Desireduint256Máximo de token0 transferido desde el llamador.
params.amount1Desireduint256Máximo de token1 transferido desde el llamador.
params.amount0Minuint256Cantidad mínima de token0 utilizada.
params.amount1Minuint256Cantidad mínima de token1 utilizada.
params.deadlineuint256Fecha límite de Position Manager.
RetornoTipoDescripción
liquidityuint128Liquidez añadida.
amount0uint256Cantidad de token0 utilizada.
amount1uint256Cantidad de token1 utilizada.

Acceso / payable: cualquier llamador; payable; nonReentrant.

El llamador debe aprobar ambos tokens. Los tokens no utilizados se reembolsan al llamador y se emite onIncreaseLiquidity. La implementación no reenvía msg.value; envíe cero tokens nativos. La interacción directa con Position Manager puede costar menos gas si es compatible.

decreaseLiquidity

function decreaseLiquidity(
uint256 _lockId,
INonfungiblePositionManager.DecreaseLiquidityParams calldata params
) external payable returns (uint256 amount0, uint256 amount1)

Elimina liquidez tras vencer un bloqueo temporal y envía los tokens al propietario.

NombreTipoDescripción
_lockIduint256Bloqueo cuya liquidez se reduce.
params.tokenIduint256Debe coincidir con el ID del NFT bloqueado.
params.liquidityuint128Liquidez que se elimina.
params.amount0Minuint256Cantidad mínima de token0 acreditada.
params.amount1Minuint256Cantidad mínima de token1 acreditada.
params.deadlineuint256Fecha límite de Position Manager.
RetornoTipoDescripción
amount0uint256Cantidad de token0 acreditada por decreaseLiquidity.
amount1uint256Cantidad de token1 acreditada por decreaseLiquidity.

Acceso / payable: solo el propietario; payable; nonReentrant.

El bloqueo debe estar vencido y no ser permanente. Primero se cobran todas las comisiones acumuladas mediante la ruta del Locker; luego se cobra al llamador todo lo adeudado por el NFT. No se reenvía msg.value; envíe cero. Emite onDecreaseLiquidity.

relock

function relock(uint256 _lockId, uint256 _unlockDate) external

Extiende el bloqueo o lo hace permanente.

NombreTipoDescripción
_lockIduint256Bloqueo que se extiende.
_unlockDateuint256Nuevo timestamp en segundos, o ETERNAL_LOCK.

Acceso / payable: solo el propietario; nonpayable; nonReentrant.

La fecha debe superar el unlockDate actual y block.timestamp; salvo el bloqueo permanente, debe ser menor que 10_000_000_000. El plazo nunca se puede acortar. Emite onRelock.

withdraw

function withdraw(uint256 _lockId, address _receiver) external

Transfiere el NFT completo desde un bloqueo temporal vencido.

NombreTipoDescripción
_lockIduint256Bloqueo que se retira.
_receiveraddressDestinatario del NFT.

Acceso / payable: solo el propietario; nonpayable; nonReentrant.

El bloqueo debe estar vencido y no ser permanente. Si ucf > 0, primero se cobran todas las comisiones usando _receiver como destinatario normal. Después se transfiere el NFT, se eliminan los índices y LOCKS, y se emite onWithdraw. Use un receptor compatible con transferencias safe ERC721.

setAdditionalCollector

function setAdditionalCollector(uint256 _lockId, address _additionalCollector) external

Configura la cuenta opcional que puede llamar a collect.

NombreTipoDescripción
_lockIduint256Bloqueo que se configura.
_additionalCollectoraddressDirección del Collector, o la dirección cero para borrarla.

Acceso / payable: solo el propietario; nonpayable; nonReentrant. Actualiza el bloqueo y emite onSetAdditionalCollector.

setCollectAddress

function setCollectAddress(uint256 _lockId, address _collectAddress) external

Configura el destinatario de los ingresos netos del cobro automático.

NombreTipoDescripción
_lockIduint256Bloqueo que se configura.
_collectAddressaddressDestinatario no nulo del cobro automático.

Acceso / payable: solo el propietario; nonpayable; nonReentrant. Emite onSetCollectAddress.

transferLockOwnership

function transferLockOwnership(uint256 _lockId, address _newOwner) external

Inicia una transferencia de propiedad en dos pasos.

NombreTipoDescripción
_lockIduint256Bloqueo que se transfiere.
_newOwneraddressPropietario propuesto.

Acceso / payable: solo el propietario; nonpayable; nonReentrant.

El nuevo propietario debe diferir del llamador. Se acepta la dirección cero, aunque un pending owner cero no puede aceptar. Una propuesta nueva sobrescribe la anterior. Emite onLockOwnershipTransferStarted.

acceptLockOwnership

function acceptLockOwnership(uint256 _lockId, address _collectAddress) external

Acepta la transferencia pendiente y elige la nueva dirección de cobro automático.

NombreTipoDescripción
_lockIduint256Bloqueo que se acepta.
_collectAddressaddressNueva dirección de cobro almacenada.

Acceso / payable: solo pending owner; nonpayable; nonReentrant.

Se mueven los índices, se borran pendingOwner y additionalCollector, y se guarda _collectAddress. Esta función acepta una dirección de cobro cero, por lo que el cliente debe rechazarla. Emite onTransferLockOwnership.

Funciones de lectura

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
);

Ambos devuelven los mismos campos: getLock devuelve un struct y el getter del mapping una tupla ABI. IDs retirados o desconocidos devuelven un bloqueo con ceros.

ParámetroDescripción
_lockId / lockIdID del bloqueo que se consulta.

getLocksLength / NONCE

function getLocksLength() external view returns (uint256);
function NONCE() external view returns (uint256);

Ambos devuelven el siguiente ID, incluidos los bloqueos históricos retirados. No representan el número activo.

Enumeración de usuarios

function getNumUserLocks(address _user) external view returns (uint256);
function getUserLockAtIndex(address _user, uint256 _index)
external view returns (Lock memory);
ParámetroDescripción
_userPropietario cuyo conjunto de bloqueos activos se consulta.
_indexÍndice activo desde cero; fuera de rango revierte.

La primera devuelve el número activo. La segunda resuelve el ID del índice y devuelve su bloqueo.

Consultas de comisiones

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);
ParámetroDescripción
_nameNombre exacto de la opción; un nombre desconocido revierte.
_indexÍndice desde cero del conjunto de comisiones; un índice inválido revierte.

FeeStruct incluye name, lpFee, collectFee, flatFee y flatFeeToken. Las opciones pueden cambiar inmediatamente; léalas justo antes de bloquear.

nftPositionManagerIsAllowed

function nftPositionManagerIsAllowed(address _nftPositionManager)
external view returns (bool);

Indica si lock puede usar ese Position Manager.

Getters de configuración pública

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);

Exponen constantes, dependencias, direcciones privilegiadas y la propiedad del contrato en dos pasos.

Eventos

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);

Se emite cuando lock crea un bloqueo. Incluye IDs, cuentas, condiciones de desbloqueo, tasa ucf, dirección del pool y snapshot completo de Position.

ParámetroDescripción
lock_idID del nuevo bloqueo.
nftPositionManagerPosition Manager que define el NFT.
nft_idID del NFT de posición.
ownerPropietario inicial del bloqueo.
additionalCollectorCollector opcional.
collectAddressDestinatario del ingreso neto del cobro automático.
unlockDateTimestamp de desbloqueo o ETERNAL_LOCK.
countryCodeCódigo de país o región validado.
collectFeeTasa ucf almacenada.
poolAddressPool de Factory correspondiente a la posición.
positionSnapshot completo de Position de Position Manager.

onWithdraw

event onWithdraw(uint256 lock_id, address owner, address receiver);

Se emite antes de eliminar el estado del bloqueo retirado.

ParámetroDescripción
lock_idBloqueo retirado.
ownerPropietario del bloqueo.
receiverDestinatario del NFT.

onLockOwnershipTransferStarted

event onLockOwnershipTransferStarted(uint256 lockId, address currentOwner, address pendingOwner);

Se emite cuando el propietario actual propone uno nuevo.

ParámetroDescripción
lockIdBloqueo en transferencia.
currentOwnerPropietario actual.
pendingOwnerPropietario propuesto.

onTransferLockOwnership

event onTransferLockOwnership(uint256 lockId, address oldOwner, address newOwner, address newCollectAddress);

Se emite cuando el pending owner acepta la transferencia.

ParámetroDescripción
lockIdBloqueo transferido.
oldOwnerPropietario anterior.
newOwnerNuevo propietario que acepta la transferencia.
newCollectAddressDirección de cobro proporcionada al aceptar.

onSetAdditionalCollector

event onSetAdditionalCollector(uint256 lockId, address additionalCollector);

Se emite cuando el propietario cambia el Additional Collector, que puede ser cero.

ParámetroDescripción
lockIdBloqueo actualizado.
additionalCollectorNuevo Collector, que puede ser la dirección cero.

onSetCollectAddress

event onSetCollectAddress(uint256 lockId, address collectAddress);

Se emite cuando el propietario cambia el destinatario no nulo del cobro automático.

ParámetroDescripción
lockIdBloqueo actualizado.
collectAddressNuevo destinatario no nulo.

onRelock

event onRelock(uint256 lockId, uint256 unlockDate);

Se emite después de extender un bloqueo.

ParámetroDescripción
lockIdBloqueo extendido.
unlockDateNuevo timestamp de desbloqueo.

onIncreaseLiquidity

event onIncreaseLiquidity(uint256 lockId);

Se emite después de añadir liquidez mediante el wrapper del Locker.

ParámetroDescripción
lockIdBloqueo cuya liquidez aumentó.

onDecreaseLiquidity

event onDecreaseLiquidity(uint256 lockId);

Se emite después de reducir la liquidez de un bloqueo vencido mediante el Locker.

ParámetroDescripción
lockIdBloqueo cuya liquidez disminuyó.

Errores

Errores de negocio del Locker

Error / RevertFuncionesActivación
OWNER CANNOT = address(0)lockparams.owner es cero.
COLLECT_ADDRlock, setCollectAddresscollectAddress es cero. acceptLockOwnership no realiza esta comprobación.
MILLISECONDSlock, relockTimestamp normal al menos 10_000_000_000.
DATE PASSEDlock, relockLa fecha no es posterior al bloque actual.
COUNTRYlockcountryCode no supera COUNTRY_LIST.
INVALID NFT POSITION MANAGERlockPosition Manager no permitido.
NOT FOUNDlock, getFeeLa opción nominal no existe.
FLAT FEElockmsg.value no coincide exactamente.
Gas token transfer failedlock, adminRefundEthFalla la transferencia nativa.
OWNERcollect, collectBatchPreview, funciones de gestiónEl llamador no es un Owner, Additional Collector, Auto Collector o pending Owner autorizado.
NFT IDincreaseLiquidity, decreaseLiquidityparams.tokenId difiere del nft_id.
ETERNAL_LOCKdecreaseLiquidity, withdrawOperación sobre un bloqueo permanente.
NOT YETdecreaseLiquidity, withdrawEl bloqueo aún no venció.
DATErelockLa nueva fecha no supera el unlockDate.
SAME OWNERtransferLockOwnership_newOwner es el Owner actual.
LsetUCF_ucf nuevo no es menor que la tasa actual.
DEFAULTremoveFeeIntento de eliminar DEFAULT.
Fee not existsremoveFeeLa opción no existe.

Errores personalizados de vista previa

error CollectBatchPreviewResult(CollectPreviewItem[] previews);
error LengthMismatch();
Custom ErrorSignificado
CollectBatchPreviewResult(...)Payload de éxito esperado de collectBatchPreview. Decodifique previews como resultado.
LengthMismatch()Las longitudes de lockIds, recipients, amount0Maxs y amount1Maxs son distintas.

Errores externos y heredados

Error / RevertActivación
STFFalla safeTransferFrom, normalmente por saldo o allowance.
STFalla safeTransfer.
SAFalla safeApprove.
Ownable: caller is not the ownerUna cuenta que no es owner llama a administración.
ReentrancyGuard: reentrant callReentrada en una función nonReentrant.
Panic(0x11)Underflow u overflow aritmético.