Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions contracts/escrow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,30 +163,41 @@ impl EscrowContract {
true
}

pub fn release_to_pool(env: Env, invoice_id: BytesN<32>, repayment_amount: u128) -> bool {
pub fn release_to_pool(env: Env, invoice_id: BytesN<32>, repayment_amount: u128, caller: Address) -> bool {
// Releases escrowed funds back to the pool as repayment.
//
// # Arguments
// * `env` - The Soroban environment.
// * `invoice_id` - The invoice whose escrow is returned.
// * `repayment_amount` - The amount returned to the pool.
// * `caller` - The address calling this function (pool or invoice contract).
//
// # Returns
// * `bool` - `true` when funds are returned.
//
// # Panics
// * `NotFound` if no escrow record exists for the invoice.
// * `NotAuthorized` if the caller is not the pool or invoice contract.
//
// # Example
// ```ignore
// client.release_to_pool(&invoice_id, &repayment_amount);
// client.release_to_pool(&invoice_id, &repayment_amount, &caller);
// ```
let pool: Address = env
.storage()
.instance()
.get(&DataKey::PoolContract)
.unwrap();
pool.require_auth();
let invoice_contract: Address = env
.storage()
.instance()
.get(&DataKey::InvoiceContract)
.unwrap();

caller.require_auth();
if caller != pool && caller != invoice_contract {
panic_with_error!(&env, EscrowError::NotAuthorized);
}

let key = DataKey::Locked(invoice_id.clone());
let mut record: EscrowRecord = env
Expand Down
14 changes: 7 additions & 7 deletions contracts/escrow/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ fn test_release_to_pool_transfers_correct_amount() {

client.lock(&invoice_id, &amount);
let repayment: u128 = amount;
let result = client.release_to_pool(&invoice_id, &repayment);
let result = client.release_to_pool(&invoice_id, &repayment, &pool);
assert!(result);

let locked = client.get_locked(&invoice_id);
Expand All @@ -224,13 +224,13 @@ fn test_release_to_pool_transfers_correct_amount() {
#[test]
#[should_panic(expected = "Error(Contract, #5)")]
fn test_release_to_pool_fails_on_overpayment() {
let (env, client, _admin, _pool, _usdc) = setup();
let (env, client, _admin, pool, _usdc) = setup();
let invoice_id = generate_invoice_id(&env);
let amount: u128 = 1_000_000_000;

client.lock(&invoice_id, &amount);
let invalid_repayment: u128 = amount + 1;
client.release_to_pool(&invoice_id, &invalid_repayment);
let overpayment: u128 = amount + 1;
client.release_to_pool(&invoice_id, &overpayment, &pool);
}

#[test]
Expand All @@ -241,7 +241,7 @@ fn test_release_to_pool_partial_repayment() {

client.lock(&invoice_id, &amount);
let partial_repayment: u128 = 400_000_000;
let result = client.release_to_pool(&invoice_id, &partial_repayment);
let result = client.release_to_pool(&invoice_id, &partial_repayment, &pool);
assert!(result);

let locked = client.get_locked(&invoice_id);
Expand Down Expand Up @@ -392,13 +392,13 @@ fn test_release_to_issuer_requires_pool_authorization() {
#[test]
#[should_panic]
fn test_release_to_pool_requires_pool_authorization() {
let (env, client, _admin, _pool, _usdc) = setup();
let (env, client, _admin, pool, _usdc) = setup();
let invoice_id = generate_invoice_id(&env);
let amount: u128 = 1_000_000_000;

client.lock(&invoice_id, &amount);
env.set_auths(&[]);
client.release_to_pool(&invoice_id, &amount);
client.release_to_pool(&invoice_id, &amount, &pool);
}

#[test]
Expand Down
Loading