Public Allocator: Just-in-Time Liquidity
Morpho's design of isolated markets provides unparalleled risk containment. However, it can also lead to fragmented liquidity, where capital is spread across multiple markets instead of being concentrated in a single pool. For a borrower, this could mean a market they want to use doesn't have enough liquidity for their desired loan size.
The Public Allocator is the elegant solution to this problem. It is a smart contract that functions as a liquidity router, providing just-in-time liquidity by reallocating assets between markets on demand.
What is the Public Allocator?
The Public Allocator is a publicly callable contract that can move a vault's idle or under-utilized assets into a market where a borrower needs them, right at the moment they need them.
From a borrower's perspective, this transforms a series of isolated, smaller pools into a single, deep source of liquidity, combining the safety of isolated risk with the convenience of a pooled lending model.
How It Works for a Borrower
Imagine a user wants to borrow 1,000 WETH from the wstETH/WETH market, but that specific market only has 200 WETH available.
1. Liquidity Request
The user (or your application on their behalf) initiates the borrow. The system detects the 800 WETH shortfall.
2. Public Allocator Triggered
Instead of failing, a call is made to the Public Allocator. It instantly finds the 800 WETH from other markets where the same lending vault has capital (e.g., from an idle pool or an under-utilized rETH/WETH market).
3. Liquidity Reallocated
The Public Allocator executes a reallocate function, moving the 800 WETH into the target wstETH/WETH market.
4. Borrow Executed
The wstETH/WETH market now has 1,000 WETH available. The user's borrow transaction succeeds seamlessly.
When integrated with a Bundler, this entire process-reallocation and borrowing-happens atomically within a single transaction. The user experience is simple: they see deep liquidity and execute one transaction.
Curator Controls: Flow Caps
This on-demand reallocation is not a free-for-all. Vault curators retain full control over how their liquidity can be moved by setting Flow Caps on the Public Allocator for each market.
maxIn: The maximum amount of assets that can be moved into a market by the Public Allocator.maxOut: The maximum amount that can be moved out of a market.
These guardrails ensure that while liquidity is flexible, it always operates within the risk parameters defined by the vault's curator.
Benefits for Your Integration
- Offer Deeper Liquidity: Allow your users to execute large borrows without worrying about the liquidity of a single market.
- Improve User Experience: Abstract away the complexity of fragmented liquidity. Users interact with one market and get the liquidity of many.
- Maintain Security: Benefit from a pool-like experience while retaining the underlying risk isolation of Morpho's core architecture.
Now that you understand what the Public Allocator does, here is how to integrate it into your borrowing flow.

Core Integration: reallocateTo
The primary function for interacting with the Public Allocator is reallocateTo. This function pulls assets from multiple source markets within a vault and supplies them to a single destination market in one atomic transaction.
Function Signature
function reallocateTo(
address vault,
Withdrawal[] calldata withdrawals,
MarketParams calldata supplyMarketParams
) external payable;Parameters
vault: The address of the MetaMorpho vault containing the liquidity.withdrawals: An array ofWithdrawalstructs, each specifying a source market and an amount to withdraw.supplyMarketParams: AMarketParamsstruct defining the single destination market where all withdrawn assets will be deposited.
Important Requirements
To successfully call reallocateTo, you must adhere to the following rules:
- Sorted Withdrawals: The
withdrawalsarray must be sorted in ascending order by market ID. - Pay the Fee: The transaction must be sent with the correct
feein gas token (E.g Ethereum: in ETH ) asmsg.value. You can query this fee by calling thefee(vaultAddress)view function on the Public Allocator contract. Note: This fee is set and collected by the vault curator, not by Morpho. The curator can set it to 0. - Respect Flow Caps: The withdrawal and supply amounts must not exceed the
maxOutandmaxInflow caps configured by the vault curator for each market. - Valid Markets: All source and destination markets must be enabled in the vault's configuration.
- No Self-Supply: The destination market (
supplyMarketParams) cannot be included in thewithdrawalsarray.
Example: Solidity Integration
Here is a simplified example of how you might construct and call reallocateTo within a smart contract.
// Assuming IPublicAllocator and IMetaMorpho interfaces are available
IPublicAllocator publicAllocator = IPublicAllocator(PA_ADDRESS);
IMetaMorpho vault = IMetaMorpho(VAULT_ADDRESS);
// 1. Check prerequisites
require(vault.isAllocator(address(publicAllocator)), "PA: Not an allocator");
uint256 requiredFee = publicAllocator.fee(address(vault));
// 2. Prepare withdrawal parameters (must be sorted by market ID)
Withdrawal[] memory withdrawals = new Withdrawal[](2);
// Withdrawal from Market A (e.g., Idle Market)
withdrawals[0] = Withdrawal({
marketParams: marketAParams, // MarketParams for Market A
amount: 70 * 1e18
});
// Withdrawal from Market B (e.g., wstETH Market)
// The ID of Market B must be greater than the ID of Market A
withdrawals[1] = Withdrawal({
marketParams: marketBParams, // MarketParams for Market B
amount: 800 * 1e18
});
// 3. Define the destination market
MarketParams memory supplyMarketParams = rETHMarketParams; // MarketParams for rETH Market
// 4. Execute the reallocation
publicAllocator.reallocateTo{value: requiredFee}(
address(vault),
withdrawals,
supplyMarketParams
);Recommended Integration Flow
For a robust dApp integration, the onchain reallocateTo call should be the final step in a flow that uses offchain data to ensure success.
1. Check Target Market Liquidity
First, check if the user's borrow can be fulfilled by the target market's existing liquidity. If so, no reallocation is needed.
2. Query for Reallocatable Liquidity
If more liquidity is required, use the Morpho API to query the publicAllocatorSharedLiquidity for the target market. This will return a list of all source markets across all vaults that can provide liquidity.
3. Simulate and Build Transaction
Using the data from the API, construct the withdrawals array. It is highly recommended to use the Morpho SDKs to simulate the transaction before asking the user to sign. This verifies that flow caps are respected and the call will succeed.
4. Bundle and Execute
For the best user experience, bundle the reallocateTo call with the user's borrow call into a single transaction using a Morpho Bundler. This ensures atomicity: if the reallocation fails, the entire operation (including the borrow) reverts, preventing failed transactions for the user.
Reference Implementation A complete, working script demonstrating this flow with the Morpho API and SDKs is available on GitHub. This is the best starting point for your integration.
Key Resources
| Resource | Link | Description |
|---|---|---|
| Step-by-Step Tutorial | /developers/borrow/tutorials/public-allocator/ | A practical guide on how to trigger a reallocation, including an Etherscan walkthrough. |
| Contract Addresses | /get-started/resources/addresses/ | Official addresses for the Public Allocator contract on all supported chains. |
| Solidity Specs & Errors | /get-started/resources/contracts/public-allocator/ | Detailed contract specifications, function descriptions, and a table of common error messages. |
| API & Data Endpoints | /developers/api/ | How to query GraphQL for flow caps, fees, and available reallocatable liquidity. |