Liquidity Request (Pending Withdrawal)
What is a Liquidity Request
When withdrawing Alien tokens from TVM to EVM, the MultiVault contract must send the recipient real tokens from its balance. If the balance is insufficient — the withdrawal cannot complete instantly. In this case, a Liquidity Request (LR) is created — a pending withdrawal with NotRequired status that awaits liquidity.
Why is the LR Mechanism Needed?
- Protection against fund lockup — without LR, the transaction would simply revert and the user wouldn't be able to receive their tokens. LR records the right to withdraw and allows completing it later
- Economic incentive for LPs — the user sets a bounty (reward), which attracts liquidity providers to quickly close the LR
- Flexibility for the recipient — if liquidity doesn't appear, the user can cancel the LR and return tokens to TVM
How it Works
- User initiates an Alien token withdrawal from TVM → EVM
- When calling
saveWithdrawAlien(), MultiVault detects that the balance is less than the withdrawal amount - A Pending Withdrawal with
NotRequiredstatus is created — governance approval is not required - The recipient sets a bounty — a reward for filling the LR
- A liquidity provider (LP) deposits tokens via
deposit(), closes the LR and takes the bounty - The recipient receives their tokens (minus bounty)
Important
Liquidity Request exists only on the EVM network side and only for Alien tokens. Native tokens are minted on withdrawal, so liquidity shortage is impossible for them.
Liquidity Request Creation Flow
Technically, LR is the same Pending Withdrawal that is created when limits are exceeded, but with NotRequired status instead of Required.
Example Scenario
User withdraws 50,000 USDT from TVM → EVM
1. Contract checks MultiVault balance: 10,000 USDT
2. 50,000 > 10,000 — insufficient liquidity
3. LR created with approveStatus = NotRequired
4. LP fills the LR via Fill and takes the bounty
5. User receives their 50,000 USDT (minus bounty)Data Structure
What is Stored in Each LR
| Field | What it means |
|---|---|
token | Which token is being withdrawn |
amount | How much (already after fee deduction) |
bounty | Reward for LP for fill (set by user) |
timestamp | When the request was created in TVM |
approveStatus | Current status (NotRequired for LR) |
chainId | Which network to withdraw to |
callback | Data for callback after withdrawal |
Available Actions
LR is created with NotRequired status — governance approval is not required, actions can be taken immediately:
| Action | Who can | Description |
|---|---|---|
| Fill | Anyone (usually LP) | LP deposits tokens, recipient receives amount minus bounty |
| Force Withdraw | Anyone | Direct withdrawal when liquidity appears on MultiVault |
| Cancel | LR owner | Cancel and return tokens to TVM |
| Bounty | LR owner | Set/change reward for LP |
TIP
If a Pending Withdrawal was created due to limits being exceeded (Required status), the available actions differ — see Limits.
LR Identification
Each LR is identified by the pair recipient (recipient address) + id (sequential number).
Events for Tracking
| Event | When Emitted | Parameters |
|---|---|---|
PendingWithdrawalCreated | When LR is created | recipient, id, token, amount, payloadId |
PendingWithdrawalFill | When filled via deposit | recipient, id |
PendingWithdrawalForce | When force withdraw | recipient, id |
PendingWithdrawalCancel | When cancelled | recipient, id, amount |
PendingWithdrawalUpdateBounty | When bounty changes | recipient, id, bounty |
TIP
Approve/Reject and auto-withdrawal events are described in the Limits section.
Fill Mechanism (LP)
A liquidity provider (LP) can "fill" someone else's LR by depositing their own tokens. The recipient gets their funds, and the LP takes the bounty.
LP deposits 1000 USDT via deposit()
│
▼
User with LR receives 990 USDT (set bounty = 10)
│
▼
LP receives in TVM: 1000 + 10 - fee = ~1008 USDTProcess:
- LP calls
deposit()with tokens and a list of LRs to close - For each LR:
- Check that token matches
- Check that sufficient funds
- Recipient receives
amount - bounty - LP accumulates bounty
- LP receives in TVM:
depositAmount + totalBounty - fee
Bounty — Reward for LP
The user sets bounty themselves — this is an incentive for LP to fill their specific LR:
- Higher bounty makes LR more attractive to LPs
- Bounty cannot be greater than the withdrawal amount
- Can change bounty at any time (while LR is active)
How to set bounty:
setPendingWithdrawalBounty(id, bounty)Cancel — LR Cancellation
The recipient can cancel a Liquidity Request and return tokens to TVM.
cancelPendingWithdrawal(id, amount, tvmRecipient, ...)Restrictions:
- Only for Alien tokens (from EVM)
- Only LR owner
- Status must be
NotRequiredorApproved
Force Withdraw — Direct Withdrawal
If LR has status NotRequired or Approved and liquidity has appeared on MultiVault, any address can push through the withdrawal directly. The recipient receives the full amount — bounty is not deducted.
forceWithdraw(pendingWithdrawalIds[])Error Codes
| Error | Cause |
|---|---|
"Pending: amount is zero" | LR already filled or cancelled |
"Pending: native token" | Bounty cannot be set for Native tokens |
"Pending: bounty too large" | Bounty greater than withdrawal amount |
"Pending: wrong amount" | Incorrect amount for cancel |
"Pending: wrong token" | LR token doesn't match deposit token |
"Pending: deposit insufficient" | Insufficient funds for fill |