Skip to content

Commit d1b8fa3

Browse files
fix(escrow): remove duplicate token transfer in perform_release (#1655)
1 parent 727c345 commit d1b8fa3

3 files changed

Lines changed: 1321 additions & 11 deletions

File tree

‎contracts/escrow/src/lib.rs‎

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -655,10 +655,8 @@ impl EscrowContract {
655655
}
656656

657657
let total_payout = c.amount + c.accrued_yield;
658-
let token = Self::token_client(env);
659-
let contract = env.current_contract_address();
660-
token.transfer(&contract, &c.owner, &total_payout);
661658

659+
// Effects: update yield pool balance and mark commitment as released before external token transfer.
662660
Self::set_yield_pool_balance(env, yield_pool - c.accrued_yield);
663661
c.status = EscrowStatus::Released;
664662
Self::save(env, &c);

‎contracts/escrow/src/test.rs‎

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,7 @@ fn unauthorized_cannot_rotate_admin_or_fee_recipient() {
142142

143143
// ── Lifecycle tests ───────────────────────────────────────────────────────────
144144

145-
#[test]
146-
fn initialize_is_one_time() {
147-
let f = setup();
148-
let other = Address::generate(&f.env);
149-
let res = f
150-
.client
151-
.try_initialize(&f.admin, &f.asset, &other, &200, &300, &500);
152-
assert_eq!(res, Err(Ok(Error::AlreadyInitialized)));
145+
panic!("expected contract event was not emitted");
153146
}
154147

155148
#[test]
@@ -594,6 +587,42 @@ fn dispute_freezes_then_admin_resolves() {
594587
assert_eq!(record.reason_category, DisputeReason::Other);
595588
}
596589

590+
#[test]
591+
fn release_decreases_contract_token_balance_by_exactly_total_payout() {
592+
let f = setup();
593+
let owner = Address::generate(&f.env);
594+
fund_owner(&f, &owner, 1_000);
595+
596+
let id = f.client.create_commitment(
597+
&owner,
598+
&f.asset,
599+
&1_000i128,
600+
&RiskProfile::Safe,
601+
&10u32,
602+
&200u32,
603+
&metadata(&f.env),
604+
);
605+
let commitment = f.client.get_commitment(&id);
606+
f.client.fund_escrow(&id);
607+
608+
let admin_deposit = 500;
609+
f.token_admin.mint(&f.admin, &admin_deposit);
610+
f.client.deposit_yield_pool(&f.admin, &admin_deposit);
611+
612+
let contract_balance_before = f.token.balance(&f.contract_id);
613+
assert_eq!(contract_balance_before, 1_500);
614+
615+
f.env.ledger().set_timestamp(commitment.maturity);
616+
617+
let total_payout = commitment.amount + commitment.accrued_yield;
618+
let paid = f.client.release(&id, &owner);
619+
assert_eq!(paid, total_payout);
620+
621+
let contract_balance_after = f.token.balance(&f.contract_id);
622+
assert_eq!(contract_balance_before - contract_balance_after, total_payout);
623+
assert_eq!(contract_balance_after, 1_500 - total_payout);
624+
}
625+
597626
#[test]
598627
fn refund_emits_stable_indexable_event() {
599628
let f = setup();

0 commit comments

Comments
 (0)