Escrow & Settlement Contract
The escrow contract handles the critical lock-release cycle for off-ramp settlements.
Interface
rust
#[contract]
pub struct Escrow;
#[contractimpl]
impl Escrow {
/// Lock funds in escrow for off-ramp settlement
pub fn lock(
env: Env,
user: Address,
amount: i128,
request_id: BytesN<32>, // Unique off-ramp request ID
) {
user.require_auth();
// Transfer USDC from user/vault to escrow
token::transfer(&env, &user, &env.current_contract_address(), amount);
// Store escrow record
Self::store_escrow(&env, request_id, EscrowRecord {
user: user.clone(),
amount,
status: EscrowStatus::Locked,
locked_at: env.ledger().timestamp(),
});
env.events().publish(
(symbol_short!("offramp"), symbol_short!("locked")),
(user, amount, request_id),
);
}
/// Release funds to LP after successful fiat settlement
/// Called by authorized backend settlement service
pub fn release_after_settlement(
env: Env,
authority: Address,
request_id: BytesN<32>,
lp_address: Address,
) {
authority.require_auth();
Self::verify_settlement_authority(&env, &authority);
let record = Self::get_escrow(&env, request_id);
assert!(record.status == EscrowStatus::Locked, "not locked");
// Release USDC to liquidity provider
token::transfer(&env, &env.current_contract_address(), &lp_address, record.amount);
Self::update_status(&env, request_id, EscrowStatus::Settled);
env.events().publish(
(symbol_short!("offramp"), symbol_short!("settled")),
(record.user, record.amount, request_id),
);
}
/// Refund funds to user if settlement fails
pub fn refund_if_failed(
env: Env,
authority: Address,
request_id: BytesN<32>,
) {
authority.require_auth();
Self::verify_settlement_authority(&env, &authority);
let record = Self::get_escrow(&env, request_id);
assert!(record.status == EscrowStatus::Locked, "not locked");
// Return USDC to user
token::transfer(&env, &env.current_contract_address(), &record.user, record.amount);
Self::update_status(&env, request_id, EscrowStatus::Refunded);
env.events().publish(
(symbol_short!("offramp"), symbol_short!("refunded")),
(record.user, record.amount, request_id),
);
}
}State Machine
┌──────────┐
│ Locked │ ← User initiates off-ramp
└────┬──────┘
│
├──── Fiat transfer succeeds ───▶ ┌──────────┐
│ │ Settled │
│ └──────────┘
│
└──── Fiat transfer fails ──────▶ ┌──────────┐
or timeout (30 min) │ Refunded │
└──────────┘