Skip to content

House Protocol Looping Feature - #15

Merged
zzzuhaibmohd merged 5 commits into
feat/house-protocol-devfrom
feat/house-protocol-dev-looping
Sep 5, 2025
Merged

House Protocol Looping Feature#15
zzzuhaibmohd merged 5 commits into
feat/house-protocol-devfrom
feat/house-protocol-dev-looping

Conversation

@zzzuhaibmohd

Copy link
Copy Markdown

buyAndBorrow Function Summary

The buyAndBorrow function is a newly added leveraged trading feature that allows users to buy issuance tokens and borrow against them in a single transaction. Users specify a leverage multiplier (1 to maxLeverage), and the function iteratively uses their collateral to purchase issuance tokens from the bonding curve, then automatically borrows against those locked tokens. This creates an efficient way to amplify both token acquisition and borrowing power simultaneously.

Key Features:

  • Leverage-based: Users can multiply their buying and borrowing power up to a configurable maximum
  • Single transaction: Combines token purchase and borrowing in one atomic operation
  • Automatic token locking: Issuance tokens are automatically locked as collateral for loans
  • Iterative execution: Processes leverage in loops, using all available collateral in each iteration
  • Integrated borrowing: Leverages existing borrow() function with all its safety checks and limits

Configuration & Security:

  • Maximum leverage controlled by maxLeverage state variable (configurable by authorized managers)
  • Emits BuyAndBorrowCompleted event for transparency
  • Includes comprehensive error handling for edge cases like insufficient collateral or zero token returns

@zzzuhaibmohd
zzzuhaibmohd force-pushed the feat/house-protocol-dev branch from c1c6e63 to 16a6463 Compare September 1, 2025 07:43

@leeftk leeftk 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.

Great job with this, though I think there may be a bug in the looping feature. Let's discuss more but overall this is on the right path.


// Calculate how much can be borrowed in this iteration
// Each iteration can borrow up to the value of the issuance tokens received
uint borrowAmountThisIteration = borrowingPower;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

there's a few points where we are setting these variables to each other and imo its kind of redundant, why not just use borrowingPower instead? i believe this exists in other places as well in this function

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed it for collateralForPurchase and borrowAmountThisIteration

}

// Track total issuance tokens received and total borrowed
uint totalIssuanceTokensReceived = 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

setting these to zero wastes gas really cause they're set to default in solidity

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed it

uint totalCollateralUsed = 0;

// Loop through leverage iterations
for (uint8 i = 0; i < leverage_; i++) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

since this operation is expensive we should optmized this loop, lets store the value of leverage here, also should this be less than or equal to? not sure but lets verify

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Since the value of leverage_ is input param and not being read from storage each time, will adding a new variable save gas?

The loops work correctly, say the leverage is set to 5, the loop starts from 0 and ends at 4.


// Get the actual amount of issuance tokens received in this iteration
uint actualIssuanceTokensReceived =
_issuanceToken.balanceOf(user) - totalIssuanceTokensReceived;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Im not sure this is right? This is assuming the the users balance of issuanceTokens would increase after each iteration however when after each loop these tokens should got locked meaning the users issuance token balance actually should be zero after each iteration, what should increase is their locked Issuance token amount.

Iteration 1:
User starts with 0 issuance tokens
buyFor() gives user 100 issuance tokens
actualIssuanceTokensReceived = 100 - 0 = 100
borrow() locks those 100 tokens
User's balance is now 0, but totalIssuanceTokensReceived = 100
Iteration 2:
User has 0 issuance tokens (they're locked)
buyFor() gives user 50 more issuance tokens
actualIssuanceTokensReceived = 50 - 100 = -50 ❌

│ └── And the user should have an outstanding loan
*/
function testPublicBuyAndBorrow_succeedsGivenValidLeverage() public {
function testFuzzPublicBuyAndBorrow_succeedsGivenValidLeverage(

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These are great but we should probably add more tests here.

@zzzuhaibmohd
zzzuhaibmohd merged commit 2f8a7fe into feat/house-protocol-dev Sep 5, 2025
3 of 5 checks passed
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.

2 participants