BotRadixBotRadixDocumentation

Exit without the website

How BotradixSalida handles exit requests, self-execution after 24 hours, withdrawals and order cancellation, with their limits.

BotradixSalida provides functions to request a DEX exit, execute your own exit, withdraw available funds and cancel orders without using the BotRadix website. Your account functions use the wallet sending the transaction as the owner; they do not let you choose another recipient. The exit contract does not hold your collateral: it communicates with the router, and payments go from CrossMargin to your wallet.

Caution

Use only the address 0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5, on Base. Type it yourself on basescan.org or compare it character by character; do not follow addresses or links received in messages, ads or social networks, even if they claim to come from BotRadix. In the Contract tab, BaseScan must show the code at that address as verified; if it does not, do not continue. This exit never needs your recovery phrase or private key: do not share them with anyone.

Important

This guide describes the mechanism, not the state of an account or the router configuration at this moment. The periods and limits are those of the router Salida was deployed for; check its read functions before acting. There is no guaranteed deadline for closing positions or receiving payment.

Step by step#

A summary of the full exit. Each step is detailed in the sections below; the names are those of BotradixSalida's verified code (English / Spanish, they do the same).

  1. Open Salida on BaseScan. On basescan.org, type the address 0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5 yourself and check that the Contract tab shows the code as verified.
  2. Read your status. In Contract → Read Contract, expand status (or estado). In the account (or cuenta) field enter your wallet address and click Query. Check that forwarder is the Salida address and note requestedAt, openPositions and openOrders.
  3. Connect your wallet. In Contract → Write Contract, click Connect to Web3. Use the wallet that owns the account, on Base (chain ID 8453), with some ETH on Base for gas.
  4. Request the exit. In Write Contract, exitDex (or salirDelDex), with no parameters: click Write and confirm in your wallet. Your account stops accepting new positions. If you had no positions or orders, the exit can complete in that same transaction.
  5. Cancel your orders, if openOrders is above 0. cancelOrders (or cancelarOrdenes); in the ids field enter the list of your order IDs in brackets, for example [123,456] (how to find them: section 2).
  6. Wait for the period. The BotRadix keeper may close your positions earlier. Otherwise, from selfExecutableAt, 24 hours after the request, you can execute the exit yourself. With a confirmed emergency (emergencyAt other than 0) there is no wait, but only positions in fixed markets close.
  7. Execute your exit. executeMyExit (or ejecutarMiSalida): the block without fields attempts to close up to 8 positions; the one with maxPositions (or maxPosiciones) accepts 1 to 16. Repeat while openPositions is above 0 and valid prices are available. Before confirming, raise the gas limit in your wallet to 8,000,000 by hand (16,000,000 if you use maxPositions 16): with the limit the wallet computes, the transaction can succeed without closing any position, because the contract skips the closes it has no gas left for. You only pay for the gas used.
  8. Withdraw everything. With openPositions at 0 and no orders, withdrawAll (or retirarTodo), with no parameters. Check the USDC and BAQ transfers to your wallet in the transaction and read status again. If withdrawals are paused, repeat after the pause.
  9. If something reverts or makes no progress, do not repeat the same call: read status and find your case in If it reverts or makes no progress. If you cannot find the cause, keep the hash and write to support@botradix.com.

Want to cancel the request instead of exiting? Use cancelExit (or cancelarSalida), with no parameters. None of this guarantees a deadline for closing or payment: it depends on prices, orders, debts, pauses and liquidity (Terms, section 22).

Before starting#

  1. Open BotradixSalida on basescan.org. Check the full address, 0x43473B3684ccB5d9d57D119f2A6bc7B9B1f5EEe5, and that the Contract tab shows the code as verified.
  2. Before connecting or sending anything, open Contract → Read Contract. Expand status (alias estado), enter your wallet address in account (or cuenta) and click Query. In the returned tuple, forwarder must be the Salida address above. If it is zero, different, or the read fails, do not continue through this Salida: check the address and router configuration. Also read ROUTER() and compare it with the official addresses.
  3. Set your wallet to Base mainnet, chain ID 8453, with ETH on Base for gas. Use the wallet that owns the positions and collateral; your account functions act on the signer.
  4. At the same Salida address, open Write Contract, click Connect to Web3, choose your wallet and check the connected account and network. Connecting does not execute an exit.
  5. For each action below, expand the block with that name, fill in its parameters, click Write and confirm the transaction in your wallet. Open its hash, wait for confirmation and query status(yourAddress) again in Read Contract. Recheck forwarder before further actions; an earlier read does not prevent later router changes.

Reads do not change state or require a transaction. Dates are Unix timestamps in seconds, not countdowns or local times.

Field in status(yourAddress)How to interpret it
requestedAtZero: no pending request. A nonzero value: the request timestamp.
selfExecutableAtThe ordinary time from which you can execute your exit; a prior request is required. A confirmed emergency skips the wait even if this field still shows the ordinary time.
openPositions, openOrdersCounts of remaining positions and orders. These are not ID lists.
withdrawalsPaused, withdrawalsPausedUntilWhether withdrawals are paused and when the pause ends.
emergencyChallengeAt, emergencyAtThe first indicates a challenge; only emergencyAt != 0 indicates a confirmed emergency.
emergencyPending, unsettledAccounts, distributionOpenedAtYour account's pending settlement, the global count of unsettled accounts, and the distribution opening time (0: not open yet).
emergencyClaimUSDC, deferredUSDCEmergency claim and deferred payment; these are not free funds already received.

Your account functions#

The functions have Spanish and English aliases that follow the same path.

ActionSpanish nameEnglish name
Request an exitsalirDelDex()exitDex()
Execute your exitejecutarMiSalida() or ejecutarMiSalida(uint256)executeMyExit() or executeMyExit(uint256)
Withdraw what is availableretirarTodo()withdrawAll()
Cancel your orderscancelarOrdenes(uint256[])cancelOrders(uint256[])
Cancel the exit requestcancelarSalida()cancelExit()

The return values described below are contract results. A receipt marked Success does not usually display those values or prove that everything was withdrawn: check the status reads and the transfers to your wallet. SalidaUsada identifies the action sent, not completion of the process.

1. Request an exit#

In Write Contract, use exitDex() or salirDelDex(), with no parameters. It records the request and locks new positions for the account. If there are no open positions or orders, it attempts to complete withdrawal in that transaction, subject to the other checks. Repeating a pending request keeps its original timestamp; it does not restart the 24-hour wait.

It returns 1 if the exit completed in that transaction and 0 if it remains pending. Check requestedAt, selfExecutableAt, openPositions and openOrders. A 0 is not itself a failure: continue with pending orders and positions. A 1 does not guarantee payment of unbacked deferred amounts or unpaid claims.

The keeper can cancel orders and close positions using valid prices observed at or after the request. Execution within seconds is not promised. Price, funding and liquidation risk remain during the wait.

2. Cancel pending orders#

The IDs this function takes are those of the router's DexOrderCreated events, the router being the address returned by ROUTER(). On BaseScan, open that address and look in its Events for the DexOrderCreated events of your wallet: in that event, the first indexed value is the order ID, the second the owner wallet and the third the pairId. Copy only the order IDs, never the pairId. Return to Salida's Write Contract, expand cancelOrders or cancelarOrdenes and enter the list in ids, for example [123,456], replacing those numbers with your actual IDs.

It needs no prices and returns no value. Check that openOrders goes down. An order of yours that was already executed or cancelled is ignored; an order of another wallet, or an ID that is not yours, reverts the whole transaction.

Cancelling orders does not by itself close all positions. The self-execution function does not enumerate and automatically cancel all your entry orders: check openOrders and cancel any remaining ones so the exit can complete and their reserves can be released.

3. Execute your exit after 24 hours#

If the request remains pending, read status(yourAddress) and use executeMyExit or ejecutarMiSalida in Write Contract once selfExecutableAt is reached, 24 hours after the request. A confirmed emergency (emergencyAt != 0) removes that wait, but you must still request the exit with exitDex() first; opening a challenge is not enough.

BaseScan shows two versions with the same name: the block without input fields attempts to close up to 8 positions; the one with maxPositions (or maxPosiciones) lets you enter a batch size of 1 to 16. Available gas can reduce the amount processed. Multiple calls may be needed.

For an unfrozen market, both price legs must have an open session, have been observed at or after the request, be at most 10 minutes old, not be dated in the future and meet their confidence limits. A frozen market uses its fixed price. During an emergency, only positions in frozen markets can close. Positions without a usable price are skipped and remain open.

It returns (closed, remaining, finished): positions closed in this call, positions still open, and 1 if the exit completed (0 otherwise). Check status(yourAddress) after each batch. Repeat while positions remain and price conditions are met; if there is no progress, check the causes below. If orders, debts, an effective pause or pending emergency settlement remain, closing the last position may not complete withdrawal. During an emergency, finish with withdrawAll(), even if no positions remain. Reaching 24 hours enables a call; it does not trigger a transaction or guarantee available prices or funds.

4. Withdraw what is available#

Once openPositions is 0, cancel any remaining orders first and use withdrawAll() or retirarTodo() in Write Contract, with no parameters. It needs no prices or prior exit request. With open positions it reverts with DexPositionsOpen. It attempts to settle and collect applicable emergency payments, claim deferred payments that now have backing, and withdraw available free USDC and BAQ to the owner wallet.

It returns no value: check the USDC and BAQ transfers to your wallet in that transaction and the new state. A successful transaction can reflect a partial withdrawal or a zero amount; it does not by itself prove that nothing remains pending. During a pause the router emits DexExitAwaitingWithdrawal and stops withdrawal without necessarily reverting the transaction. Repeat once the pause ends.

Order reserves are not withdrawn; cross debt or pending settlement can also prevent completion. Calling this function does not turn an unbacked deferred payment into withdrawable balance. During an emergency, distribution requires no open position anywhere in the DEX and every account to be settled. If distributionOpenedAt is still 0 or a claim remains, call again once those conditions are met; payment may be partial, with a deferred remainder.

Cancel the request#

To cancel a pending request, use cancelExit() or cancelarSalida(), with no parameters, in Write Contract. It returns no value: check that requestedAt is back to 0. It removes that request's lock on new positions; it does not remove an emergency or other protocol restrictions. It does not restore closed positions or cancelled orders, or reverse confirmed transactions. A later exit request starts a new ordinary wait.

If it reverts or makes no progress#

If BaseScan or the wallet warns that the call would revert, check the cause before signing. A transaction confirmed as failed keeps no changes from that call but consumes gas. Do not repeat it without addressing the condition that prevents it. Salida forwards the call to the router: if the router's code does not appear as verified on BaseScan, the error reason may show as a hexadecimal code instead of a name. The status and market reads tell you which situation you are in.

SituationWhat to do
executeMyExit() or cancelExit() would fail and requestedAt is 0There is no pending request. If you want to exit and positions remain, request the exit with exitDex() first. If the exit already completed, you do not need to cancel it.
executeMyExit() would fail before selfExecutableAtWait until that time, unless an emergency is confirmed (emergencyAt != 0).
withdrawAll() reverts with DexPositionsOpenPositions remain: request an exit if needed, close them with executeMyExit() when eligible and read the state again.
Any of your account functions would fail with no other visible causeCheck that forwarder is this Salida address, the connected account and, for cancelOrders, that every ID belongs to an order of your wallet. Adding gas does not fix it.
DexExitAwaitingWithdrawal or withdrawalsPaused == trueWithdrawal is waiting, not necessarily reverting. Read withdrawalsPausedUntil and retry withdrawal after the pause.
withdrawAll() succeeds but not everything arrivesA pause, orders with reserved funds, cross debt, a pending settlement or an unbacked deferred payment may remain. Check openOrders, deferredUSDC, emergencyPending and the pause; if the reads do not explain it, report the hash to support.
No positions closed, or finished == 0There may be no valid price, too little gas for another position, orders, debt or pending settlement. Read the counters and market state; during an emergency the market may still need fixing. A successful call does not force those conditions to be met.
Insufficient gasCheck ETH on Base and the estimate. For self-execution, try a smaller batch, such as maxPositions = 1; split order lists into smaller batches.
A community function would failThe challenge or emergency is not in the required state, or its period has not elapsed. Read status (emergencyChallengeAt, emergencyAt) and market(pairId) (challengeOpenedAt, settleAfter, frozenKind) again before retrying.
confirmEmergency would fail with a market listRead the complete, ascending list from marketsWithPositions() again; do not invent IDs or use a shortened list.
settleMarket would fail although settleAfter has passedThere may be no observation to fix the price with: reaching the deadline does not create a price. Check market(pairId) and report the problem.

If you cannot identify the cause, keep the hash and visible error and contact support@botradix.com. Waiting or repeating the same call is not guaranteed to complete it.

Pauses, missing prices and emergency#

Under the rules of the router Salida was deployed for, each withdrawal pause expires after 72 hours, requires 24 hours without a pause before the next one and does not apply during a confirmed emergency. Other payment constraints can remain after expiry.

The community functions are also in Salida's Write Contract. Anyone can pay gas to call them when their conditions are met. Results and payments belong to each account owner; submitting the transaction gives no right to anyone else's funds. They do not activate automatically when your request reaches 24 hours.

English function / Spanish aliasConditions and result
openEmergencyChallenge() / abrirDesafioEmergencia()Opens the public 72-hour challenge if positions exist in the DEX and there is no emergency yet. Read emergencyChallengeAt.
confirmEmergency(markets) / confirmarEmergencia(mercados)After 72 hours, get the complete, ascending bytes32[] list from marketsWithPositions() / mercadosConPosiciones() in Read Contract and paste it into markets (or mercados) in Write Contract. Returns true if it activates the emergency. An observation of USDC or a market with positions since the challenge opened, even with a closed session, clears the challenge and returns false. Check emergencyAt.
fixEmergencyMarkets(markets) / fijarMercadosEmergencia(mercados)During an emergency, fixes the remaining markets with positions; returns how many it fixed. Use the market IDs from the read above and repeat if gas left work pending. Price and funding are fixed at the emergency instant even if fixing finishes later.
challengeMarket(pairId) / desafiarMercado(pairId)Opens the 3-day challenge for a market with positions that is not frozen. pairId is the pair's number, not a bytes32 market ID. Read market(pairId) / mercado(pairId), including challengeOpenedAt and settleAfter.
settleMarket(pairId) / liquidarMercado(pairId)From settleAfter, with no observations since the challenge, freezes the market at its last observed price and fixes its funding. Returns true when it freezes the market; a later observation clears the challenge and returns false. Check frozenKind and frozenPriceX18 in market.
closeFrozen(positions, orders) / cerrarCongeladas(posiciones, ordenes)Takes two ID lists, closes positions in frozen markets and cancels their orders; during an emergency it can cancel any order. Returns (positions closed, orders cancelled). Batches may be needed; results stay in the owners' accounts.
settleAccounts(accounts) / liquidarCuentas(cuentas)During an emergency, settles the listed accounts with no positions or orders; returns how many it settled. Net gain: a claim. Net loss: cash, then committed BAQ backing. Accounts not yet eligible are skipped.
payEmergencyClaims(accounts) / cobrarReparto(cuentas)With no positions anywhere in the DEX and all accounts settled, opens distribution and credits each owner's share to their CrossMargin account. Returns the total amount paid, not the number of accounts; 0 can mean distribution cannot open yet. Each owner finishes with withdrawAll() to withdraw to their wallet.

A confirmed emergency is final for this DEX and stops trading; the administrator can declare it without the public challenge. Distribution applies the same fixed percentage to everyone: the smaller of 100% and available liquidity (vault, insurance and emergency reserves, excluding reserves for earlier deferred payments) divided by claims, subject to rounding. Any shortfall remains deferred, without a guaranteed payment deadline. Challenges, batches and distribution require transactions; no clock executes them automatically.

What this exit depends on#

BotradixSalida has no administrator or upgrade mechanism of its own, but depends on the router and CrossMargin. The router must recognize it as the forwarder. While configuration is open, administration can replace or disconnect it using setDexExitForwarder(address(0)) and can change the logic processing exits without mandatory advance notice. A return to an earlier router version can leave Salida unusable even if its address still exists. After the sealing provided for by this code, Salida can no longer be disconnected and router modules can only change through the advance-notice gate, with a committed minimum of at least 72 hours. This describes the sealing rules; it does not claim sealing is active. Administrative changes are public transactions on Base.

Leaving without the website removes dependence on that interface, but not on the Base network, prices, deployed code, account conditions or liquidity. See Security and contracts, Risks and Terms §22: independent exit, pauses and emergency, together with sections 23–24 on administration and deferred payments.

Last updated: 2026-10-12