What it does:
A smart contract that digitizes rental agreements, automatically handling rent payments, security deposits, late fees, and lease conditions without intermediaries.
Why it matters:
Traditional rental agreements rely on trust, paperwork, and manual enforcement. This contract ensures rent is paid on time, deposits are handled fairly, and all rules are enforced transparently on-chain.
How it works:
Landlord and tenant agree on rent terms.
Tenant deposits a security deposit and periodic rent.
Rent is paid automatically per rental period.
Late payments trigger penalties.
Deposit is released or partially withheld at lease end.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title SmartRentalAgreement
* @author Nam
* @notice On-chain rental agreement with automated rent and deposit handling
*/
contract SmartRentalAgreement {
// -------------------- STATE VARIABLES --------------------
address public landlord;
address public tenant;
uint256 public rentAmount; // Rent per period
uint256 public rentInterval; // Rental interval (e.g. 30 days)
uint256 public securityDeposit;
uint256 public lateFee; // Flat late fee
uint256 public leaseEnd;
uint256 public lastRentPaid;
bool public active;
// -------------------- EVENTS --------------------
event LeaseStarted();
event RentPaid(uint256 amount);
event LateFeePaid(uint256 amount);
event LeaseEnded(uint256 depositReturned);
// -------------------- MODIFIERS --------------------
modifier onlyTenant() {
require(msg.sender == tenant, "Not tenant");
_;
}
modifier onlyLandlord() {
require(msg.sender == landlord, "Not landlord");
_;
}
modifier leaseActive() {
require(active, "Lease inactive");
_;
}
// -------------------- CONSTRUCTOR --------------------
constructor(
address _tenant,
uint256 _rentAmount,
uint256 _rentInterval,
uint256 _securityDeposit,
uint256 _lateFee,
uint256 _leaseDuration
) {
require(_tenant != address(0), "Invalid tenant");
require(_rentAmount > 0, "Invalid rent");
require(_rentInterval > 0, "Invalid interval");
landlord = msg.sender;
tenant = _tenant;
rentAmount = _rentAmount;
rentInterval = _rentInterval;
securityDeposit = _securityDeposit;
lateFee = _lateFee;
leaseEnd = block.timestamp + _leaseDuration;
}
// -------------------- LEASE START --------------------
/**
* @notice Tenant starts lease by paying deposit
*/
function startLease() external payable onlyTenant {
require(!active, "Already active");
require(
msg.value == securityDeposit,
"Incorrect deposit"
);
active = true;
lastRentPaid = block.timestamp;
emit LeaseStarted();
}
// -------------------- RENT PAYMENT --------------------
/**
* @notice Pay periodic rent
*/
function payRent() external payable onlyTenant leaseActive {
require(
block.timestamp dueDate) {
totalDue += lateFee;
emit LateFeePaid(lateFee);
}
require(msg.value == totalDue, "Incorrect payment");
lastRentPaid = block.timestamp;
payable(landlord).transfer(msg.value);
emit RentPaid(msg.value);
}
// -------------------- LEASE END --------------------
/**
* @notice End lease and release deposit
*/
function endLease(uint256 damageCost)
external
onlyLandlord
leaseActive
{
require(block.timestamp >= leaseEnd, "Lease ongoing");
require(damageCost 0) {
payable(tenant).transfer(refund);
}
if (damageCost > 0) {
payable(landlord).transfer(damageCost);
}
emit LeaseEnded(refund);
}
// -------------------- VIEW FUNCTIONS --------------------
function nextRentDue() external view returns (uint256) {
return lastRentPaid + rentInterval;
}
}
Build and Grow By Nam Le Thanh