Skip to content

Feat/async hub#236

Open
lastperson wants to merge 40 commits into
mainfrom
feat/async-hub
Open

Feat/async hub#236
lastperson wants to merge 40 commits into
mainfrom
feat/async-hub

Conversation

@lastperson

Copy link
Copy Markdown
Collaborator

Closes: #193

@lastperson lastperson self-assigned this Jun 15, 2026
Base automatically changed from task/remove-everclear to main June 19, 2026 11:10
@lastperson lastperson marked this pull request as ready for review June 19, 2026 11:57
@lastperson lastperson requested a review from mpetrunic June 19, 2026 11:57
@mpetrunic mpetrunic requested a review from Copilot June 19, 2026 12:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates LiquidityHub to support ERC-7540-style asynchronous redemptions, enabling users to request withdrawals when liquidity is insufficient and allowing an authorized operator (ops multisig) to later fulfill those pending redemptions once liquidity is available.

Changes:

  • Add async redeem request tracking (requestRedeem, operator approvals, and fulfilRedeem) and include pending requests in vault accounting.
  • Bound maxRedeem / maxWithdraw by the liquidity pool’s current asset balance (so insufficient-liquidity withdrawals revert with ERC4626 max errors).
  • Add an extensive test suite covering the new async redeem flows and update the coverage baseline.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
contracts/LiquidityHub.sol Implements ERC-7540 async redeem requests, operator permissions, fulfill role, and liquidity-bounded max redeem/withdraw logic.
contracts/interfaces/ILiquidityHub.sol Extends the public interface with async redeem and operator APIs.
test/LiquidityHub.ts Adds tests for async redeem flows and updates insufficient-liquidity expectations.
coverage-baseline.json Updates baseline coverage thresholds after adding tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +264 to +269
function claimableRedeemRequest(uint256 /* requestId */, address controller) public view returns (uint256) {
uint256 pending = _getStorage().redeemRequests[controller];
if (pending == 0) return 0;
uint256 available = LIQUIDITY_POOL.balance(IERC20(asset()));
return Math.min(pending, previewWithdraw(available));
}
Comment on lines +284 to +288
function maxRedeem(address owner) public view override returns (uint256) {
uint256 total = balanceOf(owner) + _getStorage().redeemRequests[owner];
uint256 available = LIQUIDITY_POOL.balance(IERC20(asset()));
return Math.min(total, previewWithdraw(available));
}
Comment on lines +61 to 64
uint256 totalRedeemRequest;
mapping(address controller => uint256 shares) redeemRequests;
mapping(address controller => mapping(address operator => bool)) operators;
}
Comment thread test/LiquidityHub.ts Outdated
expect(await liquidityHub.totalRedeemRequest()).to.equal(4n * LP);
});

it("claimableRedeemRequest returns min(pending, previewWithdraw(pool))", async function () {
Use floor when calculating maxRedeem and claimableRedeemRequest
@lastperson

Copy link
Copy Markdown
Collaborator Author

@mpetrunic comments addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert LiquidityHub to eip7540

2 participants