Automated Trade Finance

What it does:
Automates trade finance processes such as letters of credit, invoices, and payments between importers, exporters, and banks using smart contracts.

Why it matters:
Reduces intermediaries, speeds up trade settlements, lowers risk of fraud, and ensures transparency and enforceable contracts in global trade.

How it works:

  • Exporters and importers register trade agreements and invoices on-chain

  • Smart contracts lock funds in escrow until predefined conditions are met (e.g., shipment confirmation, inspection, customs clearance)

  • Payment is automatically released when all conditions are verified

  • Trade events and document approvals are recorded immutably

  • Dispute resolution or partial payments can be handled via multi-signature rules

  • Integrates with logistics, supply chain tracking, and compliance audits

  • Dashboards allow stakeholders to monitor the status of trade finance transactions

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

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

/**
 * @title AutomatedTradeFinance
 * @author Nam
 * @notice Automates trade finance payments and letters of credit on-chain
 */
contract AutomatedTradeFinance is Ownable {

    struct Trade {
        address payable importer;
        address payable exporter;
        uint256 amount;
        bool shipmentConfirmed;
        bool inspectionPassed;
        bool paymentReleased;
    }

    mapping(uint256 => Trade) public trades;
    uint256 public tradeCount;

    mapping(address => bool) public inspectors;

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

    event TradeCreated(uint256 indexed tradeId, address importer, address exporter, uint256 amount);
    event ShipmentConfirmed(uint256 indexed tradeId);
    event InspectionPassed(uint256 indexed tradeId);
    event PaymentReleased(uint256 indexed tradeId, uint256 amount);
    event InspectorApproved(address inspector);

    // -------------------- INSPECTOR MANAGEMENT --------------------

    function approveInspector(address _inspector) external onlyOwner {
        inspectors[_inspector] = true;
        emit InspectorApproved(_inspector);
    }

    function revokeInspector(address _inspector) external onlyOwner {
        inspectors[_inspector] = false;
    }

    // -------------------- TRADE MANAGEMENT --------------------

    function createTrade(address payable _exporter) external payable {
        require(msg.value > 0, "Payment required");
        tradeCount += 1;

        trades[tradeCount] = Trade({
            importer: payable(msg.sender),
            exporter: _exporter,
            amount: msg.value,
            shipmentConfirmed: false,
            inspectionPassed: false,
            paymentReleased: false
        });

        emit TradeCreated(tradeCount, msg.sender, _exporter, msg.value);
    }

    // -------------------- TRADE CONDITIONS --------------------

    function confirmShipment(uint256 _tradeId) external {
        Trade storage t = trades[_tradeId];
        require(msg.sender == t.exporter, "Only exporter can confirm shipment");
        require(!t.shipmentConfirmed, "Shipment already confirmed");

        t.shipmentConfirmed = true;
        emit ShipmentConfirmed(_tradeId);
    }

    function passInspection(uint256 _tradeId) external {
        require(inspectors[msg.sender], "Not authorized inspector");

        Trade storage t = trades[_tradeId];
        require(t.shipmentConfirmed, "Shipment not confirmed");
        require(!t.inspectionPassed, "Inspection already passed");

        t.inspectionPassed = true;
        emit InspectionPassed(_tradeId);
    }

    // -------------------- PAYMENT RELEASE --------------------

    function releasePayment(uint256 _tradeId) external {
        Trade storage t = trades[_tradeId];
        require(t.shipmentConfirmed, "Shipment not confirmed");
        require(t.inspectionPassed, "Inspection not passed");
        require(!t.paymentReleased, "Payment already released");

        t.paymentReleased = true;
        t.exporter.transfer(t.amount);
        emit PaymentReleased(_tradeId, t.amount);
    }
}