BotradixSalida ofrece funciones para pedir la salida del DEX, ejecutar tu propia salida, retirar fondos disponibles y cancelar órdenes sin usar la web de BotRadix. Las funciones de tu cuenta toman la wallet que envía la transacción como titular; no permiten elegir otro destinatario. El contrato de salida no guarda tu colateral: se comunica con el router y los pagos salen de CrossMargin hacia tu wallet.
Precaución
Usa solo la dirección 0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5, en Base. Escríbela tú en basescan.org o compárala carácter a carácter; no sigas direcciones ni enlaces recibidos por mensajes, anuncios o redes, aunque digan venir de BotRadix. En la pestaña Contract, BaseScan debe mostrar el código de esa dirección como verificado; si no lo muestra, no continúes. Esta salida no necesita tu frase de recuperación ni tu clave privada: no las compartas con nadie.
Importante
Esta guía describe el mecanismo, no el estado de una cuenta ni la configuración del router en este momento. Los plazos y límites son los del router para el que se desplegó Salida; consulta sus lecturas antes de actuar. No hay un plazo garantizado de cierre ni de cobro.
Paso a paso#
Resumen de la salida completa. Cada paso se explica con detalle en las secciones de abajo; los nombres son los del código verificado de BotradixSalida (inglés / español, hacen lo mismo).
- Abre la Salida en BaseScan. En basescan.org, escribe tú la dirección
0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5y comprueba en la pestaña Contract que el código aparece como verificado. - Lee tu estado. En Contract → Read Contract, abre
status(oestado). En el campoaccount(ocuenta) pon la dirección de tu wallet y pulsa Query. Comprueba queforwarderes la dirección de Salida y anotarequestedAt,openPositionsyopenOrders. - Conecta tu wallet. En Contract → Write Contract, pulsa Connect to Web3. Usa la wallet titular de la cuenta, en Base (chain ID 8453) y con algo de ETH en Base para el gas.
- Pide la salida. En Write Contract,
exitDex(osalirDelDex), sin parámetros: pulsa Write y confirma en tu wallet. Tu cuenta deja de aceptar posiciones nuevas. Si no tenías posiciones ni órdenes, la salida puede terminar en esa misma transacción. - Cancela tus órdenes, si
openOrderses mayor que 0.cancelOrders(ocancelarOrdenes); en el campoidspon la lista de IDs de tus órdenes entre corchetes, por ejemplo[123,456](cómo encontrarlos: sección 2). - Espera el plazo. El keeper de BotRadix puede cerrar tus posiciones antes. Si no, a partir de
selfExecutableAt, 24 horas después de la petición, puedes ejecutar tú la salida. Con una emergencia confirmada (emergencyAtdistinto de 0) no hay espera, pero solo cierran las posiciones de mercados fijados. - Ejecuta tu salida.
executeMyExit(oejecutarMiSalida): el bloque sin campos intenta cerrar hasta 8 posiciones; el demaxPositions(omaxPosiciones) admite de 1 a 16. Repite mientrasopenPositionssea mayor que 0 y haya precios válidos. Antes de confirmar, sube a mano el límite de gas en tu wallet a 8.000.000 (16.000.000 si usasmaxPositions16): con el límite que calcula la wallet la transacción puede terminar bien sin cerrar ninguna posición, porque el contrato salta los cierres para los que no queda gas. Solo pagas el gas que se usa. - Retira todo. Con
openPositionsen 0 y sin órdenes,withdrawAll(oretirarTodo), sin parámetros. Comprueba en la transacción las transferencias de USDC y BAQ a tu wallet y vuelve a leerstatus. Si hay una pausa de retiros, repite cuando termine. - Si algo revierte o no avanza, no repitas la misma llamada: lee
statusy busca tu caso en Si revierte o no avanza. Si no encuentras la causa, guarda el hash y escribe a support@botradix.com.
¿Quieres anular la petición en lugar de salir? Usa cancelExit (o cancelarSalida), sin parámetros. Nada de esto garantiza un plazo de cierre ni de cobro: depende de precios, órdenes, deudas, pausas y liquidez (Términos, sección 22).
Antes de empezar#
- Abre BotradixSalida en basescan.org. Comprueba la dirección completa,
0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5, y que la pestaña Contract muestra el código como verificado. - Antes de conectar o enviar nada, entra en Contract → Read Contract. Abre
status(aliasestado), introduce la dirección de tu wallet enaccount(ocuenta) y pulsa Query. En la tupla devuelta,forwarderdebe ser la dirección de Salida anterior. Si es cero, distinta o la lectura falla, no continúes por esta Salida: revisa la dirección y la configuración del router. Consulta tambiénROUTER()y contrástalo con las direcciones oficiales. - Configura tu wallet en Base mainnet, chain ID 8453, con ETH en Base para el gas. Usa la wallet titular de las posiciones y el colateral; las funciones de tu cuenta actúan sobre quien firma.
- En la misma dirección de Salida, abre Write Contract, pulsa Connect to Web3, elige tu wallet y comprueba la cuenta conectada y la red. Conectar no ejecuta la salida.
- Para cada acción de abajo, abre el bloque con ese nombre, rellena solo sus parámetros, pulsa Write y confirma la transacción en tu wallet. Abre el hash, espera su confirmación y vuelve a consultar
status(tuDirección)en Read Contract. Repite la comprobación deforwarderantes de nuevas acciones; una lectura anterior no impide cambios posteriores del router.
Las lecturas no cambian el estado ni requieren una transacción. Las fechas son marcas Unix en segundos, no cuentas atrás ni horas locales.
Campo de status(tuDirección) | Cómo interpretarlo |
|---|---|
requestedAt | Cero: no hay petición pendiente. Un valor distinto de cero: fecha de la petición. |
selfExecutableAt | Fecha ordinaria a partir de la que puedes ejecutar tu salida; requiere petición previa. En emergencia confirmada se omite la espera, aunque este campo siga mostrando la fecha ordinaria. |
openPositions, openOrders | Cuántas posiciones y órdenes quedan. No son listas de IDs. |
withdrawalsPaused, withdrawalsPausedUntil | Si el retiro está pausado y cuándo termina la pausa. |
emergencyChallengeAt, emergencyAt | El primero indica un desafío; solo emergencyAt != 0 indica emergencia confirmada. |
emergencyPending, unsettledAccounts, distributionOpenedAt | Liquidación pendiente de tu cuenta, cuentas pendientes globalmente y apertura del reparto (0: aún no abierto). |
emergencyClaimUSDC, deferredUSDC | Reclamación de emergencia y pago diferido; no equivalen a dinero libre ya cobrado. |
Las funciones de tu cuenta#
Las funciones tienen alias en español e inglés que siguen el mismo camino.
| Acción | Nombre en español | Nombre en inglés |
|---|---|---|
| Pedir la salida | salirDelDex() | exitDex() |
| Ejecutar tu salida | ejecutarMiSalida() o ejecutarMiSalida(uint256) | executeMyExit() o executeMyExit(uint256) |
| Retirar lo disponible | retirarTodo() | withdrawAll() |
| Cancelar órdenes propias | cancelarOrdenes(uint256[]) | cancelOrders(uint256[]) |
| Cancelar la petición de salida | cancelarSalida() | cancelExit() |
Los valores de retorno descritos abajo son los del contrato. Un recibo con Success no suele mostrar esos valores ni demuestra que hayas retirado todo: comprueba las lecturas de status y las transferencias a tu wallet. SalidaUsada indica la acción enviada, no que el proceso haya terminado.
1. Pedir la salida#
En Write Contract, usa exitDex() o salirDelDex(), sin parámetros. Registra la petición y bloquea nuevas aperturas de la cuenta. Si no hay posiciones ni órdenes abiertas, intenta completar la retirada en esa misma transacción, sujeto a los demás controles. Repetir una petición pendiente conserva la fecha original; no reinicia las 24 horas.
Devuelve 1 si completó la salida en esa transacción y 0 si sigue pendiente. Comprueba requestedAt, selfExecutableAt, openPositions y openOrders. Un 0 no es por sí solo un fallo: continúa con las órdenes y posiciones pendientes. Un 1 no garantiza haber cobrado pagos diferidos sin respaldo ni reclamaciones aún no pagadas.
El keeper puede cancelar órdenes y cerrar posiciones usando precios válidos observados en el instante de la petición o después. No se promete que lo haga en segundos. Durante la espera siguen existiendo riesgo de precio, funding y liquidación.
2. Cancelar órdenes pendientes#
Los IDs que pide esta función son los de los eventos DexOrderCreated del router, la dirección que devuelve ROUTER(). En BaseScan, abre esa dirección y busca en sus Events los DexOrderCreated de tu wallet: en ese evento, el primer valor indexado es el ID de la orden, el segundo la wallet titular y el tercero el pairId. Copia solo los IDs de orden, nunca el pairId. Vuelve a Write Contract de Salida, abre cancelOrders o cancelarOrdenes y pega en ids la lista, por ejemplo [123,456] sustituyendo esos números por tus IDs reales.
No necesita precios ni devuelve un valor. Comprueba que openOrders baja. Una orden tuya que ya estaba ejecutada o cancelada se ignora; una orden de otra wallet o un ID que no sea tuyo hace revertir la transacción completa.
Cancelar órdenes no cierra por sí solo todas las posiciones. La función de ejecución propia no enumera ni cancela automáticamente todas tus órdenes de entrada: revisa openOrders y cancela las que queden para poder completar la salida y liberar sus reservas.
3. Ejecutar tu salida a partir de las 24 horas#
Si sigue pendiente, consulta status(tuDirección) y usa executeMyExit o ejecutarMiSalida en Write Contract una vez alcanzado selfExecutableAt, 24 horas después de la petición. En una emergencia confirmada (emergencyAt != 0) no se exige esa espera, pero sigue haciendo falta pedir la salida con exitDex(); abrir un desafío no basta.
BaseScan muestra dos versiones con el mismo nombre: el bloque sin campos intenta cerrar hasta 8 posiciones; el que tiene maxPositions (o maxPosiciones) permite introducir una tanda de 1 a 16. El gas disponible puede reducir lo procesado. Puede ser necesario repetir llamadas.
Para un mercado no congelado, las dos patas del precio deben estar en sesión abierta, haberse observado en el instante de la petición o después, tener como máximo 10 minutos de antigüedad, no estar fechadas en el futuro y cumplir sus límites de confianza. Un mercado congelado utiliza su precio fijado. En emergencia solo se cierran posiciones de mercados congelados. Las posiciones sin precio utilizable se omiten y permanecen abiertas.
Devuelve (cerradas, pendientes, terminada): posiciones cerradas en esta llamada, posiciones que siguen abiertas y 1 si completó la salida (0 si no). Revisa status(tuDirección) después de cada tanda. Repite mientras queden posiciones y se cumplan las condiciones de precio; si no hay progreso, consulta las causas de abajo. Si quedan órdenes, deudas, una pausa efectiva o una liquidación de emergencia pendiente, cerrar la última posición puede no completar el retiro. En emergencia, termina con withdrawAll(), aunque ya no queden posiciones. Llegar a las 24 horas habilita una llamada, no dispara una transacción ni garantiza disponer de precios o fondos.
4. Retirar lo disponible#
Cuando openPositions sea 0, cancela antes las órdenes que queden y usa withdrawAll() o retirarTodo() en Write Contract, sin parámetros. No necesita precios ni una petición de salida previa. Con posiciones abiertas revierte con DexPositionsOpen. Intenta liquidar y cobrar lo que corresponda en emergencia, reclamar los pagos diferidos que ya tengan respaldo y retirar el USDC libre y BAQ disponibles a la wallet titular.
No devuelve un valor: comprueba las transferencias de USDC y BAQ a tu wallet en esa transacción y el nuevo estado. Una transacción correcta puede reflejar una retirada parcial o de importe cero; no demuestra por sí sola que no quede nada pendiente. Durante una pausa, el router emite DexExitAwaitingWithdrawal y detiene el retiro sin que necesariamente revierta la transacción. Repite cuando termine la pausa.
Las reservas de órdenes no se retiran; la deuda cruzada o una liquidación pendiente también pueden impedir completar el proceso. Un pago diferido sin respaldo no se convierte en saldo retirable por llamar a esta función. En emergencia, el reparto requiere que no quede ninguna posición abierta en todo el DEX y que todas las cuentas estén liquidadas. Si distributionOpenedAt sigue en 0 o queda una reclamación, vuelve a llamar cuando se cumplan esas condiciones; puede haber un reparto parcial y un resto diferido.
Cancelar la petición#
Si quieres anular una petición pendiente, usa cancelExit() o cancelarSalida(), sin parámetros, en Write Contract. No devuelve un valor: comprueba que requestedAt vuelve a 0. Quita el bloqueo de aperturas de esa petición; no elimina una emergencia ni otros bloqueos del protocolo. No restaura posiciones ya cerradas ni órdenes canceladas, y no revierte transacciones confirmadas. Si después pides otra salida, comienza una nueva espera ordinaria.
Si revierte o no avanza#
Si BaseScan o la wallet avisan de que la llamada revertiría, revisa la causa antes de firmar. Una transacción confirmada como fallida no conserva cambios de esa llamada, pero consume gas. No repitas sin cambiar la condición que la impide. Salida reenvía la llamada al router: si el código del router no aparece verificado en BaseScan, el motivo del error puede mostrarse como un código hexadecimal en lugar de un nombre. Las lecturas de status y market te dicen en qué situación estás.
| Situación | Qué hacer |
|---|---|
Fallaría executeMyExit() o cancelExit() y requestedAt es 0 | No hay petición pendiente. Si quieres salir y quedan posiciones, pide antes la salida con exitDex(). Si la salida ya terminó, no necesitas cancelarla. |
Fallaría executeMyExit() antes de selfExecutableAt | Espera a esa fecha, salvo emergencia confirmada (emergencyAt != 0). |
withdrawAll() revierte con DexPositionsOpen | Quedan posiciones: pide la salida si hace falta, ciérralas con executeMyExit() cuando proceda y vuelve a leer el estado. |
| Fallaría cualquier función de tu cuenta sin otra causa visible | Revisa que forwarder sea esta dirección de Salida, la cuenta conectada y, en cancelOrders, que todos los IDs sean de órdenes de tu wallet. Añadir gas no lo arregla. |
DexExitAwaitingWithdrawal o withdrawalsPaused == true | Es una espera de retiro, no necesariamente un revert. Consulta withdrawalsPausedUntil y reintenta el retiro después de la pausa. |
withdrawAll() se confirma pero no llega todo | Puede quedar una pausa, órdenes con fondos reservados, deuda cruzada, una liquidación pendiente o un pago diferido sin respaldo. Revisa openOrders, deferredUSDC, emergencyPending y la pausa; si las lecturas no lo explican, comunica el hash a soporte. |
Cero posiciones cerradas, o terminada == 0 | Puede faltar precio válido, haber poco gas para otra posición, órdenes, deuda o liquidación pendiente. Consulta los contadores y el mercado; en emergencia puede faltar fijarlo. Una llamada exitosa no fuerza esas condiciones. |
| Falta de gas | Comprueba ETH en Base y la estimación. Para ejecución propia, prueba una tanda menor, por ejemplo maxPositions = 1; para listas de órdenes, usa lotes más pequeños. |
| Fallaría una función «de todos» | El desafío o la emergencia no están en el estado requerido o su plazo no se ha cumplido. Vuelve a leer status (emergencyChallengeAt, emergencyAt) y market(pairId) (challengeOpenedAt, settleAfter, frozenKind) antes de repetir. |
Fallaría confirmEmergency con una lista de mercados | Vuelve a obtener la lista completa y ascendente de marketsWithPositions(); no inventes IDs ni uses una lista recortada. |
Fallaría settleMarket aunque se cumpla settleAfter | Puede faltar una observación con la que fijar el precio: el plazo cumplido no crea un precio. Revisa market(pairId) y comunica el problema. |
Si no puedes identificar la causa, conserva el hash y el error visible y consulta support@botradix.com. No hay garantía de que esperar o repetir la misma llamada permita completarla.
Pausas, falta de precios y emergencia#
Con las reglas del router para el que se desplegó Salida, cada pausa de retiros caduca a las 72 horas, exige 24 horas sin pausa antes de la siguiente y no rige en emergencia confirmada. Aun después de caducar, pueden quedar otros impedimentos al cobro.
Las funciones «de todos» también están en Write Contract de Salida. Cualquiera puede pagar el gas para llamarlas cuando se cumplan sus condiciones. Los resultados y pagos corresponden a cada titular; enviarlas no da derecho a cobrar fondos ajenos. No se activan automáticamente al vencer las 24 horas de tu petición.
| Función en inglés / alias en español | Condiciones y resultado |
|---|---|
openEmergencyChallenge() / abrirDesafioEmergencia() | Abre el desafío público de 72 horas si hay posiciones en el DEX y aún no hay emergencia. Lee emergencyChallengeAt. |
confirmEmergency(markets) / confirmarEmergencia(mercados) | Tras las 72 horas, obtén en Read Contract la lista bytes32[] completa y ascendente de marketsWithPositions() / mercadosConPosiciones() y pégala en markets (o mercados) de Write Contract. Devuelve true si activa la emergencia. Una observación de USDC o de un mercado con posiciones desde la apertura, incluso con sesión cerrada, anula el desafío y devuelve false. Comprueba emergencyAt. |
fixEmergencyMarkets(markets) / fijarMercadosEmergencia(mercados) | En emergencia, fija los mercados con posiciones que falten; devuelve cuántos fijó. Usa los IDs de mercados de la lectura anterior y repite si el gas dejó trabajo pendiente. Precio y funding se fijan al instante de la emergencia, aunque la fijación se complete después. |
challengeMarket(pairId) / desafiarMercado(pairId) | Abre el desafío de 3 días de un mercado con posiciones y aún no congelado. pairId es el número del par, no el marketId de tipo bytes32. Lee market(pairId) / mercado(pairId), incluidos challengeOpenedAt y settleAfter. |
settleMarket(pairId) / liquidarMercado(pairId) | Desde settleAfter, sin observaciones desde el desafío, congela el mercado al último precio observado y fija su funding. Devuelve true al congelarlo; una observación posterior anula el desafío y devuelve false. Comprueba frozenKind y frozenPriceX18 en market. |
closeFrozen(positions, orders) / cerrarCongeladas(posiciones, ordenes) | Recibe dos listas de IDs, cierra posiciones de mercados congelados y cancela sus órdenes; en emergencia puede cancelar cualquier orden. Devuelve (posiciones cerradas, órdenes canceladas). Puede requerir tandas; los resultados quedan en las cuentas de sus titulares. |
settleAccounts(accounts) / liquidarCuentas(cuentas) | En emergencia, liquida las cuentas indicadas sin posiciones ni órdenes; devuelve cuántas liquidó. Ganancia neta: reclamación. Pérdida neta: efectivo y después respaldo comprometido en BAQ. Las cuentas aún no liquidables se omiten. |
payEmergencyClaims(accounts) / cobrarReparto(cuentas) | Sin posiciones en todo el DEX y con todas las cuentas liquidadas, abre el reparto y abona la parte correspondiente a cada cuenta en CrossMargin. Devuelve el importe total pagado, no el número de cuentas; 0 puede significar que el reparto aún no puede abrirse. Cada titular termina con withdrawAll() para retirarlo a su wallet. |
La emergencia confirmada es definitiva para este DEX y detiene el trading; el administrador puede declararla sin el desafío público. El reparto aplica a todos el mismo porcentaje fijado: el menor entre el 100 % y la liquidez disponible (vault, seguro y emergencia, excluidas las reservas para pagos diferidos anteriores) dividida por las reclamaciones, sujeto a redondeo. Lo no cubierto queda diferido, sin plazo garantizado de pago. Los desafíos, las tandas y el reparto necesitan transacciones; ningún reloj los ejecuta por sí solo.
Dependencias de esta salida#
BotradixSalida no tiene administrador ni mecanismo de actualización propio, pero depende del router y de CrossMargin. El router debe reconocerlo como forwarder. Mientras la configuración esté abierta, la administración puede sustituirlo o desconectarlo mediante setDexExitForwarder(address(0)) y puede cambiar la lógica que procesa la salida sin aviso previo obligatorio. Una vuelta a una versión anterior del router puede dejar Salida sin uso aunque su dirección siga existiendo. Tras el sellado previsto por este código, la Salida ya no se puede desconectar y los módulos del router solo se pueden cambiar mediante la puerta de aviso previo, con un mínimo comprometido de 72 horas o más. Esto describe las reglas del sellado, no afirma que esté activo. Los cambios administrativos son transacciones públicas en Base.
Salir sin la web elimina la dependencia de esa interfaz, pero no la de la red Base, los precios, el código desplegado, las condiciones de la cuenta o la liquidez. Consulta Seguridad y contratos, Riesgos y los Términos §22: salida independiente, pausas y emergencia, junto con las secciones 23–24 sobre administración y pagos diferidos.