V2 Locker
V2 Locker custodia tokens LP ERC20 creados por la Factory BDEX V2 configurada. ETERNAL_LOCK es type(uint256).max. Un bloqueo permanente no se puede retirar ni acortar, pero se puede incrementar, dividir o transferir.
Funciones de escritura
lockLPToken
function lockLPToken(
address _lpToken,
uint256 _amount,
uint256 _unlock_date,
address payable _referral,
bool _fee_in_eth,
address payable _withdrawer,
uint16 _countryCode
) external payable
Transfiere LP desde el llamador, deduce las comisiones actuales y crea un bloqueo.
| Nombre | Tipo | Descripción |
|---|---|---|
_lpToken | address | Token de par BDEX V2. |
_amount | uint256 | Cantidad de LP transferida antes de comisiones. |
_unlock_date | uint256 | Timestamp Unix en segundos, o ETERNAL_LOCK. |
_referral | address payable | Referidor elegible, o la dirección cero. |
_fee_in_eth | bool | true paga la comisión fija con el token nativo; false usa el token secundario. |
_withdrawer | address payable | Propietario inicial del bloqueo. |
_countryCode | uint16 | Código aceptado por COUNTRY_LIST. |
Acceso / payable: cualquier llamador; payable; nonReentrant.
_amount debe ser distinto de cero. Salvo ETERNAL_LOCK, la fecha debe estar en el futuro y ser menor que 10_000_000_000. El país o región y el par de la Factory deben ser válidos. El llamador debe proporcionar allowance de LP y, al pagar con el token secundario, allowance de ese token. Quien pague la comisión nativa sin estar permitido debe enviar exactamente la comisión calculada. El contrato acepta _withdrawer cero, por lo que el cliente debe rechazarlo. amount e initialAmount guardan la cantidad neta después de la comisión LP. Después se incrementa NONCE y se emite onNewLock.
relock
function relock(uint256 _lockID, uint256 _unlock_date) external
Extiende un bloqueo o lo convierte en permanente.
| Nombre | Tipo | Descripción |
|---|---|---|
_lockID | uint256 | Bloqueo que se extenderá. |
_unlock_date | uint256 | Nuevo timestamp en segundos, o ETERNAL_LOCK. |
Acceso / payable: solo el propietario del bloqueo; nonpayable; nonReentrant.
El nuevo valor debe superar el unlockDate actual y pasar la validación del formato en segundos. El contrato no exige por separado que supere block.timestamp; el cliente debe exigir _unlock_date > max(current unlockDate, current block time). Se deduce la comisión LP actual de toda la cantidad restante y se emite onRelock. La función no tiene un parámetro de recepción mínima.
withdraw
function withdraw(uint256 _lockID, uint256 _amount) external
Retira una parte o la totalidad de un bloqueo temporal vencido.
| Nombre | Tipo | Descripción |
|---|---|---|
_lockID | uint256 | Bloqueo de origen. |
_amount | uint256 | Cantidad que se retirará; type(uint256).max significa todo el LP restante. |
Acceso / payable: solo el propietario; nonpayable; nonReentrant.
La cantidad debe ser distinta de cero, el bloqueo no puede ser permanente y debe cumplirse unlockDate < block.timestamp. Un retiro total elimina el ID de los índices activos del propietario, pero conserva el registro histórico LOCKS con cantidad cero. Emite onWithdraw.
incrementLock
function incrementLock(uint256 _lockID, uint256 _amount) external
Añade LP a un bloqueo existente.
| Nombre | Tipo | Descripción |
|---|---|---|
_lockID | uint256 | Bloqueo que recibe el incremento. |
_amount | uint256 | Cantidad de LP aportada antes de comisiones. |
Acceso / payable: cualquier llamador; nonpayable; nonReentrant.
La función omite deliberadamente la comprobación de propietario: el LP aportado pertenece al propietario existente. La cantidad debe ser distinta de cero y estar aprobada. El cliente debe verificar LOCKS(_lockID).lpToken != address(0). La cantidad neta después de la comisión LP se suma a amount, pero no a initialAmount, y se emite onIncrementLock.
splitLock
function splitLock(uint256 _lockID, uint256 _amount) external payable
Mueve parte de un bloqueo a uno nuevo con el mismo propietario y condiciones.
| Nombre | Tipo | Descripción |
|---|---|---|
_lockID | uint256 | Bloqueo de origen. |
_amount | uint256 | Cantidad asignada al bloqueo hijo. |
Acceso / payable: solo el propietario; payable; nonReentrant.
La cantidad debe ser distinta de cero y no superar el saldo de origen. Incluso para una cuenta permitida, msg.value debe ser igual a gFees.ethFee. El bloqueo hijo hereda lpToken, lockDate, unlockDate, propietario y código de país o región; su amount y initialAmount equivalen a _amount. Emite onSplitLock y onNewLock.
transferLockOwnership
function transferLockOwnership(
uint256 _lockID,
address payable _newOwner
) external
Transfiere inmediatamente el bloqueo y sus índices activos.
| Nombre | Tipo | Descripción |
|---|---|---|
_lockID | uint256 | Bloqueo que se transferirá. |
_newOwner | address payable | Nuevo propietario. |
Acceso / payable: solo el propietario; nonpayable.
El nuevo propietario debe diferir del llamador. Es una transferencia de un paso, sin llamada de aceptación. El contrato acepta la dirección cero, por lo que el cliente debe rechazarla. Emite onTransferLockOwnership.
Funciones de lectura
LOCKS
function LOCKS(uint256 _lockID) external view returns (
address lpToken,
uint256 lockDate,
uint256 amount,
uint256 initialAmount,
uint256 unlockDate,
uint256 lockID,
address owner,
uint16 countryCode
)
Getter del mapping público de bloqueos. amount es el saldo LP restante e initialAmount es la cantidad neta al crearlo. Los IDs desconocidos devuelven valores cero.
TOKEN_LOCKS
function TOKEN_LOCKS(address lpToken, uint256 index)
external view returns (uint256 lockID)
Devuelve el ID histórico de bloqueo para un token LP en index.
Enumeración de tokens
function getNumLocksForToken(address _lpToken)
external view returns (uint256);
function getNumLockedTokens() external view returns (uint256);
function getLockedTokenAtIndex(uint256 _index)
external view returns (address);
_lpToken identifica el token cuyo número histórico se consulta. _index es un índice global desde cero y revierte fuera de rango. El conjunto global de tokens nunca se depura y TOKEN_LOCKS contiene IDs históricos.
Enumeración de usuarios
function getUserNumLockedTokens(address _user)
external view returns (uint256);
function getUserLockedTokenAtIndex(address _user, uint256 _index)
external view returns (address);
function getUserNumLocksForToken(address _user, address _lpToken)
external view returns (uint256);
function getUserLockForTokenAtIndex(
address _user,
address _lpToken,
uint256 _index
) external view returns (TokenLock memory);
Estas funciones devuelven el tamaño del conjunto activo de tokens, un token por índice, el número de bloqueos activos de un token y un bloqueo completo. Los bloqueos retirados por completo se eliminan. Los índices comienzan en cero y revierten fuera de rango.
Consultas de la lista blanca de comisiones
function getWhitelistedUsersLength() external view returns (uint256);
function getWhitelistedUserAtIndex(uint256 _index)
external view returns (address);
function getUserWhitelistStatus(address _user)
external view returns (bool);
Devuelven la longitud de la lista, una dirección por índice y el estado de pertenencia. Un índice inválido revierte.
Getters de configuración pública
function NONCE() external view returns (uint256);
function ETERNAL_LOCK() external view returns (uint256);
function uniswapFactory() external view returns (address);
function COUNTRY_LIST() external view returns (address);
function owner() external view returns (address);
function gFees() external view returns (
uint256 ethFee,
address secondaryFeeToken,
uint256 secondaryTokenFee,
uint256 secondaryTokenDiscount,
uint256 liquidityFee,
uint256 referralPercent,
address referralToken,
uint256 referralHold,
uint256 referralDiscount
);
NONCE es el siguiente ID, no el número de bloqueos activos. Los porcentajes usan un denominador de 1000 (10 = 1%). Las comisiones pueden cambiar de inmediato; vuelva a leerlas y simule justo antes de enviar una transacción de escritura.
Eventos
onNewLock
event onNewLock(uint256 lockID, address lpToken, address owner, uint256 amount, uint256 lockDate, uint256 unlockDate, uint16 countryCode);
Emitido por lockLPToken y cuando splitLock crea un bloqueo hijo.
| Parámetro | Descripción |
|---|---|
lockID | ID del nuevo bloqueo. |
lpToken | Token del par bloqueado. |
owner | Propietario del bloqueo. |
amount | Cantidad neta almacenada. |
lockDate | Marca de tiempo de creación. |
unlockDate | Marca de tiempo de desbloqueo o ETERNAL_LOCK. |
countryCode | Código de país o región validado. |
onRelock
event onRelock(uint256 lockID, address lpToken, address owner, uint256 amountRemainingInLock, uint256 liquidityFee, uint256 unlockDate);
Emitido después de extender el bloqueo y deducir la comisión.
| Parámetro | Descripción |
|---|---|
lockID | Bloqueo extendido. |
lpToken | Token del par. |
owner | Propietario del bloqueo. |
amountRemainingInLock | Cantidad neta restante. |
liquidityFee | Comisión LP deducida. |
unlockDate | Nueva fecha de desbloqueo. |
onWithdraw
event onWithdraw(uint256 lockID, address lpToken, address owner, uint256 amountRemainingInLock, uint256 amountRemoved);
Emitido tras un retiro parcial o total.
| Parámetro | Descripción |
|---|---|
lockID | Bloqueo retirado. |
lpToken | Token del par. |
owner | Propietario y destinatario. |
amountRemainingInLock | Cantidad LP restante. |
amountRemoved | Cantidad LP transferida. |
onIncrementLock
event onIncrementLock(uint256 lockID, address lpToken, address owner, address payer, uint256 amountRemainingInLock, uint256 amountAdded, uint256 liquidityFee);
Emitido al aportar LP al bloqueo.
| Parámetro | Descripción |
|---|---|
lockID | Bloqueo incrementado. |
lpToken | Token del par. |
owner | Propietario beneficiario. |
payer | Proveedor del LP. |
amountRemainingInLock | Nueva cantidad total restante. |
amountAdded | Cantidad LP neta añadida. |
liquidityFee | Comisión LP deducida. |
onSplitLock
event onSplitLock(uint256 lockID, address lpToken, address owner, uint256 amountRemainingInLock, uint256 amountRemoved);
Emitido para el bloqueo de origen cuando se crea uno hijo.
| Parámetro | Descripción |
|---|---|
lockID | Bloqueo de origen. |
lpToken | Token del par. |
owner | Propietario de ambos bloqueos. |
amountRemainingInLock | Cantidad del bloqueo de origen después de la división. |
amountRemoved | Cantidad del bloqueo hijo. |
onTransferLockOwnership
event onTransferLockOwnership(uint256 lockID, address lpToken, address oldOwner, address newOwner);
Emitido al completar la transferencia de propiedad de un paso.
| Parámetro | Descripción |
|---|---|
lockID | Bloqueo transferido. |
lpToken | Token del par. |
oldOwner | Propietario anterior. |
newOwner | Nuevo propietario. |
Errores
Estos son los principales reverts de los flujos V2. Compare las cadenas exactamente; el contrato usa la grafía ZERO WITHDRAWL.
| Error / Revert | Funciones | Activación |
|---|---|---|
TIMESTAMP INVALID | lockLPToken, relock | Timestamp normal igual o mayor que 10_000_000_000, normalmente en milisegundos. |
DATE PASSED | lockLPToken | La fecha normal no es posterior al bloque actual. |
INSUFFICIENT | lockLPToken | _amount == 0. |
COUNTRY | lockLPToken | _countryCode no supera COUNTRY_LIST. |
NOT UNIV2 | lockLPToken | _lpToken no proviene de la Factory BDEX V2 configurada. |
INADEQUATE BALANCE | lockLPToken | El referidor no cumple referralHold. |
FEE NOT MET | lockLPToken, splitLock | msg.value no coincide exactamente con la comisión nativa. |
NOT OWNER | relock, withdraw, splitLock, transferLockOwnership | El llamador no es el propietario del bloqueo. |
UNLOCK BEFORE | relock | La nueva fecha no supera estrictamente el unlockDate actual. |
ZERO WITHDRAWL | withdraw | _amount == 0 o la cantidad resuelta es cero. |
ETERNAL_LOCK | withdraw | Intento de retirar un bloqueo permanente. |
NOT YET | withdraw | El bloqueo temporal aún no venció. |
ZERO AMOUNT | incrementLock, splitLock | Incremento o división cero. |
OWNER | transferLockOwnership | _newOwner es el llamador. |
TransferHelper: APPROVE_FAILED | Aprobación de tokens | approve falla o devuelve false. |
TransferHelper: TRANSFER_FAILED | Transferencia de tokens | transfer falla o devuelve false. |
TransferHelper: TRANSFER_FROM_FAILED | lockLPToken, incrementLock | Saldo o allowance insuficiente, o fallo de transferFrom. |
Panic(0x11) | withdraw, splitLock y otras operaciones de cantidad | La solicitud supera el saldo restante o una comisión provoca underflow/overflow. |
Las funciones administrativas y la protección contra reentradas también pueden devolver errores heredados:
| Error / Revert | Activación |
|---|---|
Ownable: caller is not the owner | Una cuenta que no es owner llama a una función administrativa. |
ReentrancyGuard: reentrant call | Reentrada en una función nonReentrant. |
Los reverts de Factory, token LP, token de referidos o token de comisiones se propagan sin cambios. El frontend debe conservar los datos originales.