Drone Delivery Escrow

What it does:
Holds funds in escrow for drone deliveries and automatically releases payments to delivery providers upon confirmed successful delivery.

Why it matters:
Ensures secure transactions, prevents disputes, automates conditional payments, and builds trust in autonomous delivery systems.

How it works:

  • Sender deposits payment into escrow smart contract

  • Drone delivery provider accepts the task and completes the delivery

  • Delivery confirmation (via IoT sensors, GPS, or oracles) triggers automatic payment release

  • Supports partial payments, refunds, or dispute resolution mechanisms

  • Integrates with Autonomous Vehicle Payment System, Smart City Micro-Payments, or AI Agents

  • Dashboards display escrow status, delivery confirmations, and payment history

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

import "@openzeppelin/contracts/access/Ownable.sol";

/**
 * @title DroneDeliveryEscrow
 * @author Nam
 * @notice Manages escrow payments for drone deliveries on-chain
 */
contract DroneDeliveryEscrow is Ownable {

    struct Delivery {
        address payable sender;
        address payable provider;
        uint256 amount;
        bool delivered;
        bool refunded;
    }

    mapping(uint256 => Delivery) public deliveries;
    uint256 public deliveryCount;

    mapping(address => bool) public authorizedOracles;

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

    event OracleApproved(address oracle);
    event OracleRevoked(address oracle);
    event DeliveryCreated(uint256 indexed deliveryId, address sender, address provider, uint256 amount);
    event DeliveryConfirmed(uint256 indexed deliveryId);
    event DeliveryRefunded(uint256 indexed deliveryId);

    // -------------------- ORACLE MANAGEMENT --------------------

    function approveOracle(address _oracle) external onlyOwner {
        authorizedOracles[_oracle] = true;
        emit OracleApproved(_oracle);
    }

    function revokeOracle(address _oracle) external onlyOwner {
        authorizedOracles[_oracle] = false;
        emit OracleRevoked(_oracle);
    }

    modifier onlyOracle() {
        require(authorizedOracles[msg.sender], "Not authorized oracle");
        _;
    }

    // -------------------- DELIVERY MANAGEMENT --------------------

    function createDelivery(address payable _provider) external payable {
        require(msg.value > 0, "Amount must be >0");

        deliveryCount += 1;
        deliveries[deliveryCount] = Delivery({
            sender: payable(msg.sender),
            provider: _provider,
            amount: msg.value,
            delivered: false,
            refunded: false
        });

        emit DeliveryCreated(deliveryCount, msg.sender, _provider, msg.value);
    }

    function confirmDelivery(uint256 _deliveryId) external onlyOracle {
        Delivery storage d = deliveries[_deliveryId];
        require(!d.delivered, "Already delivered");
        require(!d.refunded, "Delivery refunded");

        d.delivered = true;
        d.provider.transfer(d.amount);

        emit DeliveryConfirmed(_deliveryId);
    }

    function refundDelivery(uint256 _deliveryId) external onlyOracle {
        Delivery storage d = deliveries[_deliveryId];
        require(!d.delivered, "Already delivered");
        require(!d.refunded, "Already refunded");

        d.refunded = true;
        d.sender.transfer(d.amount);

        emit DeliveryRefunded(_deliveryId);
    }

    // -------------------- VIEW FUNCTIONS --------------------

    function getDeliveryStatus(uint256 _deliveryId) external view returns (bool delivered, bool refunded) {
        Delivery storage d = deliveries[_deliveryId];
        return (d.delivered, d.refunded);
    }
}