Triggering the Public Allocator
This tutorial explains how to trigger a reallocation using the Public Allocator to provide just-in-time liquidity for a borrow transaction.
Before you begin, make sure you understand the core concepts behind the Public Allocator and why it's a powerful tool for enhancing liquidity.
Review the Public Allocator Concept Page first.
The Core Action: reallocateTo
The central function of the Public Allocator is reallocateTo. It pulls liquidity from a specified list of source markets within a vault and supplies it all to a single destination market, charging an optional native-token fee per vault. The withdrawals must be sorted in ascending order by market id.
You never encode this call yourself: the Morpho SDK builds one reallocateTo() call per vault and prepends them to your borrow bundle, before the borrow itself, so the liquidity arrives and is borrowed in a single atomic transaction.
Integrate with the Morpho SDK
The general logic is:
- Check Target Market Liquidity: See if the user's borrow can be fulfilled without reallocation.
- Query Available Liquidity: If not, use the Morpho API to query the
publicAllocatorSharedLiquidityfor the target market. This returns a list of all markets in all vaults that can reallocate assets to your target. - Compute and Build: Let the SDK compute the reallocation set for those candidate vaults and prepend the
reallocateTocalls to the borrow transaction.
Step 1: Set up the client and market entity
Build the extended client and the market entity exactly as in the borrow tutorial. The snippets below reuse client, market, account, and a publicClient (the same client extended with viem's publicActions, for block reads).
Step 2: Fetch reallocation data
// Candidate vaults: query the Morpho API's `publicAllocatorSharedLiquidity`
// for the target market to find vaults that can reallocate liquidity into it.
const block = await publicClient.getBlock();
const reallocationData = await market.getReallocationData({
vaultAddresses: [
"0xVaultV1Address0000000000000000000000000000",
] as Address[],
block: { number: block.number, timestamp: block.timestamp },
});Step 3: Compute the reallocation set
// Derive the `VaultReallocation[]` needed to cover the borrow size.
// `operation` is "borrow" or "withdraw".
const reallocations = market.getReallocations({
reallocationData,
operation: "borrow",
amount: parseUnits("500", 6),
});Step 4: Borrow with reallocations
const positionData = await market.getPositionData(account.address);
const borrow = market.borrow({
amount: parseUnits("500", 6),
userAddress: account.address,
positionData,
reallocations,
});
const signatures = [];
for (const req of await borrow.getRequirements()) {
if ("sign" in req) {
signatures.push(await req.sign(client, account.address));
} else {
await client.sendTransaction(req); // approval / setAuthorization
}
}
// `tx.value` includes the sum of every PublicAllocator fee.
const tx = borrow.buildTx(signatures);
const txHash = await client.sendTransaction(tx);
console.log("Borrow with reallocation:", txHash);Reallocations work the same way for supplyCollateralBorrow, and for loan-asset withdraw. For refinance, they target the destination market and are passed as targetReallocations. See Shared liquidity (reallocations) on the Blue subpage for every variant, including passing an explicit reallocation array instead of letting the SDK compute one.
For a detailed, working example of how to implement this logic using TypeScript, Viem, and the Morpho API, refer to the public-allocator-scripts repository.