Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new flashloan entrypoint #30

Merged
merged 7 commits into from
Jan 22, 2025
Merged

new flashloan entrypoint #30

merged 7 commits into from
Jan 22, 2025

Conversation

heytdep
Copy link
Contributor

@heytdep heytdep commented Jan 10, 2025

continuation of #10

@heytdep
Copy link
Contributor Author

heytdep commented Jan 10, 2025

this is a new pr with a whole new entry point that wraps the execute_submit functionality and adds the flash loan too. tracking issue is still #7

@heytdep
Copy link
Contributor Author

heytdep commented Jan 10, 2025

Note that this is just an MVP, if we choose that this is the right approach then I'll further tidy the code.

Copy link
Contributor

@mootz12 mootz12 left a comment

Choose a reason for hiding this comment

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

Looks good so far @heytdep!

We should add an integration test in test-suites/tests that actually invokes a flash loan contract. We could add a test moderc3156 contract in mocks that just returns some additional tokens to the invoker, to validate we can successfully process a flash loan.

Let me know if any help is required on test requirements, happy to assist.

Thanks for the contribution!

Comment on lines 84 to 86
// similarly to usual borrows, we want the flash loan to be debited before
// checking the health factor. TODO: We should decide whether the execution ordering
// matters here (I'm pretty sure it doesn't but haven't looked much into it).
Copy link
Contributor

Choose a reason for hiding this comment

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

This would only be an issue if the function ever was re-entrant.

maybe make a comment that re-entrancy is unsafe here since the user state is not written before the flash loan contract was invoked, to warn any future developer.

Comment on lines 128 to 132
if use_allowance {
handle_transfer_with_allowance(e, &actions, from, from);
} else {
handle_transfers(e, &actions, from, from);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

we should only use allowances here.

When executing transfers with flash loans, the odds the transfer requests will be accurate across blocks is unlikely, making simulation difficult.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good point, switched on the use allowance flag.

@mootz12 mootz12 linked an issue Jan 15, 2025 that may be closed by this pull request
Copy link
Contributor

@mootz12 mootz12 left a comment

Choose a reason for hiding this comment

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

Minor doc updates and issue found with user position ordering. Once these are resolved, I think this will be good to go!

Comment on lines 132 to 141
/// Submit a set of requests to the pool where 'from' takes on the position, 'sender' sends any
/// required tokens to the pool and 'to' receives any tokens sent from the pool
///
/// Returns the new positions for 'from'
///
/// ### Arguments
/// * `from` - The address of the user whose positions are being modified
/// * `spender` - The address of the user who is sending tokens to the pool
/// * `to` - The address of the user who is receiving tokens from the pool
/// * `requests` - A vec of requests to be processed
Copy link
Contributor

Choose a reason for hiding this comment

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

we should update docs for flash_loan args

from: &Address,
flash_loan: FlashLoan,
requests: Vec<Request>,
use_allowance: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

we could drop this argument, given it is fixed as true

use test_suites::{create_fixture_with_data, moderc3156::create_flashloan_receiver, test_fixture::{TokenIndex, SCALAR_7}};

#[test]
fn test_liquidations() {
Copy link
Contributor

Choose a reason for hiding this comment

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

test name

Comment on lines 14 to 15
// reset frodo's health.
// TODO: there probably is a user in the fixture that doesn't require this due to low hf? haven't really looked into it.
Copy link
Contributor

Choose a reason for hiding this comment

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

you can just create a new user, see wasm_happy_path for example, we create user samwise to start from scratch.

frodo mainly exists to seed the test pool with capital.

Comment on lines 33 to 44
// this request rebalances the flash loan borrow.
// we need to account for the overcollateralization too, so it cannot be the same
// exact amount borrowed.
let requests: Vec<Request> = vec![
&fixture.env,
Request {
request_type: RequestType::SupplyCollateral as u32,
address: fixture.tokens[TokenIndex::XLM].address.clone(),
amount: 2_000 * SCALAR_7,
},

];
Copy link
Contributor

Choose a reason for hiding this comment

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

we should includes a separate test that processes a repayment as well, to validate the issue found in execute_submit_with_flash_loan

Comment on lines +27 to +29
// perform operations here
// ...

Copy link
Contributor

Choose a reason for hiding this comment

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

should this test contract just return amount to caller?

That way, we can test more common cases of flash loans like:

  1. Flash loan 1000 USDC to contract that does arb are returns 1000 USDC
  2. Repay 1000 USDC

And that the tokens are being properly transferred to the flash loan contract by the pool

Comment on lines 79 to 104
// note: check_health is omitted since we always will want to check the health
// if a flash loan is involved.
let (actions, mut new_from_state, _) =
build_actions_from_request(e, &mut pool, from, requests);

// similarly to usual borrows, we want the flash loan to be debited before
// checking the health factor.

// Warning: at this point user state is not written yet before invoking the
// flash loan contract, so was this function ever reentrant this code would become
// unsafe.
{
let mut reserve = pool.load_reserve(e, &flash_loan.asset, true);
let d_tokens_minted = reserve.to_d_token_up(flash_loan.amount);
new_from_state.add_liabilities(e, &mut reserve, d_tokens_minted);
reserve.require_utilization_below_max(e);

e.events().publish(
(
Symbol::new(e, "flash_borrow"),
&flash_loan.asset,
&flash_loan.contract,
),
(&flash_loan.amount, d_tokens_minted),
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The flash loan liabilities will need to be added before build_actions_from_request, right?

Reason being, it will be quite common for a repay request to be included of the flash loaned asset in the requests array.

repay has logic that reduces the repayment amount based on the actual liabilities on the block this is being processed on. So, the flash_loan liability needs to exist on the Positions object before repay is processed, that way the liability will accurately be reduced.

@@ -0,0 +1,17 @@
use soroban_sdk::{testutils::Address as _, Address, Env};

mod emitter_contract {
Copy link
Contributor

Choose a reason for hiding this comment

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

mod name

use soroban_sdk::{testutils::Address as _, Address, Env};

mod emitter_contract {
soroban_sdk::contractimport!(file = "../target/wasm32-unknown-unknown/optimized/moderc3156_example.wasm");
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to add this to the Makefile so that the moderc3156_example.wasm is built during make build, such that things like the github test pipeline can access it.

Copy link
Contributor

@Ryang-21 Ryang-21 left a comment

Choose a reason for hiding this comment

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

Looks good

@mootz12 mootz12 merged commit e9615be into blend-capital:main Jan 22, 2025
3 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.

Add flash loans
3 participants