Vacation Property Booking Escrow
What it does:
Holds booking funds in escrow for vacation rentals and automatically releases or refunds payments based on check-in, stay completion, or cancellation rules.
Why it matters:
Protects both guests and hosts from scams, no-shows, and disputes by ensuring funds move only when pre-agreed booking conditions are met.
How it works:
-
A booking is created with property details, price, and stay dates
-
Guest deposits the booking amount into the escrow contract
-
Funds remain locked until the check-in date
-
Host confirms guest check-in on-chain
-
Funds are released to the host after successful stay
-
If cancellation or dispute occurs, funds are refunded per rules
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title VacationPropertyBookingEscrow
* @author Nam
* @notice Escrow contract for short-term vacation property bookings
*/
contract VacationPropertyBookingEscrow {
// -------------------- ROLES --------------------
address public host;
address public guest;
// -------------------- BOOKING TERMS --------------------
uint256 public bookingAmount;
uint256 public checkInDate;
uint256 public checkOutDate;
uint256 public cancellationDeadline;
// -------------------- STATE --------------------
bool public deposited;
bool public checkedIn;
bool public completed;
bool public cancelled;
// -------------------- EVENTS --------------------
event FundsDeposited(address indexed guest, uint256 amount);
event CheckInConfirmed();
event BookingCompleted();
event BookingCancelled();
event FundsReleased(address indexed host, uint256 amount);
event FundsRefunded(address indexed guest, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyHost() {
require(msg.sender == host, "Not host");
_;
}
modifier onlyGuest() {
require(msg.sender == guest, "Not guest");
_;
}
modifier bookingActive() {
require(!completed && !cancelled, "Booking inactive");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor(
address _guest,
uint256 _checkInDate,
uint256 _checkOutDate,
uint256 _cancellationDeadline
) {
require(_guest != address(0), "Invalid guest");
require(_checkOutDate > _checkInDate, "Invalid stay dates");
host = msg.sender;
guest = _guest;
checkInDate = _checkInDate;
checkOutDate = _checkOutDate;
cancellationDeadline = _cancellationDeadline;
}
// -------------------- ESCROW LOGIC --------------------
/**
* @notice Guest deposits booking funds
*/
function deposit() external payable onlyGuest bookingActive {
require(!deposited, "Already deposited");
require(msg.value > 0, "Invalid amount");
bookingAmount = msg.value;
deposited = true;
emit FundsDeposited(msg.sender, msg.value);
}
/**
* @notice Host confirms guest check-in
*/
function confirmCheckIn() external onlyHost bookingActive {
require(deposited, "No funds deposited");
require(block.timestamp >= checkInDate, "Too early to check in");
checkedIn = true;
emit CheckInConfirmed();
}
/**
* @notice Complete stay and release funds to host
*/
function completeStay() external onlyHost bookingActive {
require(checkedIn, "Guest not checked in");
require(block.timestamp >= checkOutDate, "Stay not completed");
completed = true;
payable(host).transfer(bookingAmount);
emit BookingCompleted();
emit FundsReleased(host, bookingAmount);
}
// -------------------- CANCELLATION & REFUND --------------------
/**
* @notice Guest cancels booking before deadline
*/
function cancelBooking() external onlyGuest bookingActive {
require(deposited, "No funds deposited");
require(block.timestamp <= cancellationDeadline, "Cancellation period passed");
cancelled = true;
payable(guest).transfer(bookingAmount);
emit BookingCancelled();
emit FundsRefunded(guest, bookingAmount);
}
}