Skip to content
LogoLogo

Escrow

The buyer funds the escrow. The arbiter either releases the funds to the seller or refunds the buyer.

escrow.lithe
(* The buyer funds the escrow. The arbiter releases it to the seller, or refunds
   the buyer. *)
 
import "std/evm";
 
error NotBuyer;
error NotArbiter;
error AlreadyFunded;
error NotFunded;
 
event Released of record {
  amount : wei;
}
 
event Refunded of record {
  amount : wei;
}
 
storage is record {
  buyer : address;
  seller : address;
  arbiter : address;
  amount : wei;
  funded : bool;
}
 
external payable function fund(const seller : address; const arbiter : address)
  raises AlreadyFunded
is {
  assert(not storage.funded, AlreadyFunded);
  storage.buyer := Evm.sender();
  storage.seller := seller;
  storage.arbiter := arbiter;
  storage.amount := Evm.value();
  storage.funded := true;
}
 
view function settleCheck() raises NotArbiter | NotFunded is {
  assert(Evm.sender() = storage.arbiter, NotArbiter);
  assert(storage.funded, NotFunded);
}
 
external nonreentrant function release()
  raises NotArbiter | NotFunded
is {
  settleCheck();
  const amount : wei := storage.amount;
  storage.funded := false;
  storage.amount := 0wei;
  emit Released { amount = amount; };
  defer Evm.transfer(storage.seller, amount);
}
 
external nonreentrant function refund()
  raises NotArbiter | NotFunded
is {
  settleCheck();
  const amount : wei := storage.amount;
  storage.funded := false;
  storage.amount := 0wei;
  emit Refunded { amount = amount; };
  defer Evm.transfer(storage.buyer, amount);
}