Blend flash-loan callback (ModERC-3156 interface).
Called by the source pool with exec_op(from, token, amount, fee=0).
Public by ABI necessity; all legitimate paths reach it only via
migrate → source_pool.flash_loan. Guarded by consume_staged_params
which enforces: NoStagedParams, source_pool auth, SamePoolNotAllowed,
AssetMismatch, AmountMismatch (see consume_staged_params doc above).
Cross-pool supply/borrow (slice 3), swap (slice 4), and walking skeleton (slice 5) follow after the guard layer.
fn exec_op(
env: soroban_sdk::Env,
from: soroban_sdk::Address,
token: soroban_sdk::Address,
amount: i128,
_fee: i128,
)
Stage params on receiver and call source_pool.flash_loan atomically.
Call stack (no re-entry): migrator.migrate → receiver.stage_params (done) → source_pool.flash_loan → receiver.exec_op
fn migrate(
env: soroban_sdk::Env,
receiver: soroban_sdk::Address,
route: MigrationRoute,
amounts: MigrationAmounts,
)
Stage migration params for the calling position owner.
Public entry point called by the RefinanceMigrator contract BEFORE flash_loan.
Separated from the flash_loan invocation to avoid Soroban re-entry:
migrate on the receiver would be: receiver.migrate → pool.flash_loan → receiver.exec_op
(receiver appears twice → re-entry error from the Soroban host).RefinanceMigrator contract calls receiver.stage_params (frame A,
completes), then calls pool.flash_loan (frame B → receiver.exec_op frame C).
Frames A and C are sequential, not concurrent → no re-entry.Requires auth from route.from (position owner signing the migration).
Anyone may call this, but the stored params are useless without source_pool calling exec_op.
fn stage_params(
env: soroban_sdk::Env,
route: MigrationRoute,
amounts: MigrationAmounts,
)