Smart Lease Renewal Contract

What it does:
Automatically renews or terminates a rental lease based on predefined conditions such as tenant payment history, notice periods, and landlord approval.

Why it matters:
Removes friction and ambiguity from lease renewals, ensuring both tenant and landlord follow transparent, enforceable rules.

How it works:

  • Lease terms and renewal conditions are set at deployment.

  • Tenant signals intent to renew and pays renewal fee (if any).

  • Contract checks eligibility (on-time payments, notice window).

  • Lease is auto-extended or cleanly expired on-chain.

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title SmartLeaseRenewal
 * @author Nam
 * @notice Automates lease renewal based on predefined conditions
 */
contract SmartLeaseRenewal {

    // -------------------- ROLES --------------------

    address public landlord;
    address public tenant;

    // -------------------- LEASE TERMS --------------------

    uint256 public leaseStart;
    uint256 public leaseEnd;
    uint256 public renewalDuration;   // seconds
    uint256 public renewalFee;        // ETH
    uint256 public noticePeriod;      // seconds before lease end

    // -------------------- STATE --------------------

    bool public active;
    bool public renewalRequested;
    bool public terminated;

    // -------------------- EVENTS --------------------

    event RenewalRequested(address indexed tenant);
    event LeaseRenewed(uint256 newLeaseEnd);
    event LeaseTerminated();

    // -------------------- MODIFIERS --------------------

    modifier onlyTenant() {
        require(msg.sender == tenant, "Not tenant");
        _;
    }

    modifier onlyLandlord() {
        require(msg.sender == landlord, "Not landlord");
        _;
    }

    modifier leaseActive() {
        require(active && !terminated, "Lease inactive");
        _;
    }

    // -------------------- CONSTRUCTOR --------------------

    constructor(
        address _tenant,
        uint256 _leaseDuration,
        uint256 _renewalDuration,
        uint256 _renewalFee,
        uint256 _noticePeriod
    ) {
        require(_tenant != address(0), "Invalid tenant");

        landlord = msg.sender;
        tenant = _tenant;

        leaseStart = block.timestamp;
        leaseEnd = leaseStart + _leaseDuration;
        renewalDuration = _renewalDuration;
        renewalFee = _renewalFee;
        noticePeriod = _noticePeriod;

        active = true;
    }

    // -------------------- RENEWAL LOGIC --------------------

    /**
     * @notice Tenant requests lease renewal
     */
    function requestRenewal() external payable onlyTenant leaseActive {
        require(!renewalRequested, "Already requested");
        require(block.timestamp >= leaseEnd - noticePeriod, "Too early");
        require(msg.value == renewalFee, "Incorrect renewal fee");

        renewalRequested = true;
        emit RenewalRequested(msg.sender);
    }

    /**
     * @notice Landlord approves renewal
     */
    function approveRenewal() external onlyLandlord leaseActive {
        require(renewalRequested, "No renewal request");

        leaseEnd += renewalDuration;
        renewalRequested = false;

        if (renewalFee > 0) {
            payable(landlord).transfer(renewalFee);
        }

        emit LeaseRenewed(leaseEnd);
    }

    // -------------------- TERMINATION --------------------

    /**
     * @notice Lease ends without renewal
     */
    function terminateLease() external leaseActive {
        require(block.timestamp >= leaseEnd, "Lease not ended");
        require(!renewalRequested, "Renewal pending");

        active = false;
        terminated = true;

        emit LeaseTerminated();
    }
}