ERC20InheritanceFactoryV2

Description:

Smart contract deployed on Ethereum with Factory features.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "contracts/BALTRegistry.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.20;\r
\r
contract BALTRegistry {\r
    struct FactoryInfo {\r
        address factory;\r
        uint16 major;\r
        uint16 minor;\r
        string chain;   // ej: "ethereum", "polygon", "rootstock"\r
        string family;  // ej: "inheritance", "trust"\r
        bool active;\r
    }\r
\r
    address public owner;\r
    mapping(address => FactoryInfo) public factories; // factory => info\r
    address[] public factoryList;\r
    mapping(address => address) public factoryOf; // vault => factory (set por factory)\r
\r
    event FactoryAdded(address indexed factory, uint16 major, uint16 minor, string chain, string family);\r
    event FactoryToggled(address indexed factory, bool active);\r
    event OwnerTransferred(address indexed newOwner);\r
    event FactoryOfSet(address indexed vault, address indexed factory);\r
\r
    modifier onlyOwner() {\r
        require(msg.sender == owner, "Not owner");\r
        _;\r
    }\r
\r
    constructor() {\r
        owner = msg.sender;\r
    }\r
\r
    function transferOwnership(address newOwner) external onlyOwner {\r
        require(newOwner != address(0), "Zero owner");\r
        owner = newOwner;\r
        emit OwnerTransferred(newOwner);\r
    }\r
\r
    function addFactory(\r
        address factory,\r
        uint16 major,\r
        uint16 minor,\r
        string calldata chain,\r
        string calldata family\r
    ) external onlyOwner {\r
        require(factory != address(0), "Invalid factory");\r
        FactoryInfo storage info = factories[factory];\r
        require(info.factory == address(0), "Exists");\r
        factories[factory] = FactoryInfo({\r
            factory: factory,\r
            major: major,\r
            minor: minor,\r
            chain: chain,\r
            family: family,\r
            active: true\r
        });\r
        factoryList.push(factory);\r
        emit FactoryAdded(factory, major, minor, chain, family);\r
    }\r
\r
    function toggleFactory(address factory, bool active) external onlyOwner {\r
        FactoryInfo storage info = factories[factory];\r
        require(info.factory != address(0), "Unknown");\r
        info.active = active;\r
        emit FactoryToggled(factory, active);\r
    }\r
\r
    function setFactoryOf(address vault, address factory) external {\r
        // Llamado por la factory en el momento de crear el vault\r
        require(factories[msg.sender].factory != address(0), "Only factory");\r
        require(factory == msg.sender, "Factory mismatch");\r
        factoryOf[vault] = factory;\r
        emit FactoryOfSet(vault, factory);\r
    }\r
\r
    function getFactoryList() external view returns (address[] memory) {\r
        return factoryList;\r
    }\r
\r
    function isFactoryActive(address factory) external view returns (bool) {\r
        return factories[factory].active;\r
    }\r
}"
    },
    "contracts/ERC20InheritanceFactoryV2.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.20;\r
\r
import "./ERC20InheritanceVaultV2.sol";\r
import "./BALTRegistry.sol";\r
\r
contract ERC20InheritanceFactoryV2 {\r
    address public immutable commissionWallet;\r
    address public immutable token;     // ERC-20 a utilizar en esta factory\r
    uint16  public immutable feeBps;    // ej: 80 (0.8%)\r
    uint256 public immutable minDeposit;\r
    BALTRegistry public immutable registry;\r
\r
    address[] public allVaults;\r
    mapping(address => address[]) public vaultsByTestator;\r
\r
    // Versionado de la factory\r
    uint16 public constant MAJOR = 2;\r
    uint16 public constant MINOR = 0;\r
\r
    event VaultCreated(address indexed testator, address vaultAddress);\r
\r
    constructor(\r
        address _commissionWallet,\r
        address _token,\r
        uint16 _feeBps,\r
        uint256 _minDeposit,\r
        address _registry\r
    ) {\r
        require(_commissionWallet != address(0), "Invalid commission wallet");\r
        require(_token != address(0), "Invalid token");\r
        require(_feeBps < 10_000, "fee too high");\r
        require(_registry != address(0), "Invalid registry");\r
\r
        commissionWallet = _commissionWallet;\r
        token = _token;\r
        feeBps = _feeBps;\r
        minDeposit = _minDeposit;\r
        registry = BALTRegistry(_registry);\r
    }\r
\r
    function createInheritanceVault(uint inactivityPeriod) external returns (address) {\r
        ERC20InheritanceVaultV2 vault = new ERC20InheritanceVaultV2(\r
            msg.sender,\r
            inactivityPeriod,\r
            commissionWallet,\r
            token,\r
            feeBps,\r
            minDeposit\r
        );\r
        address v = address(vault);\r
        allVaults.push(v);\r
        vaultsByTestator[msg.sender].push(v);\r
\r
        // Notificar al Registry para factoryOf[vault] = esta factory\r
        registry.setFactoryOf(v, address(this));\r
\r
        emit VaultCreated(msg.sender, v);\r
        return v;\r
    }\r
\r
    function getVaultsByTestator(address testator) external view returns (address[] memory) {\r
        return vaultsByTestator[testator];\r
    }\r
\r
    function getAllVaults() external view returns (address[] memory) {\r
        return allVaults;\r
    }\r
\r
    function version() external pure returns (uint16, uint16) {\r
        return (MAJOR, MINOR);\r
    }\r
}"
    },
    "contracts/ERC20InheritanceVaultV2.sol": {
      "content": "// SPDX-License-Identifier: MIT\r
pragma solidity ^0.8.20;\r
\r
// Mínima interfaz ERC-20\r
interface IERC20 {\r
    function transfer(address to, uint value) external returns (bool);\r
    function transferFrom(address from, address to, uint value) external returns (bool);\r
    function balanceOf(address account) external view returns (uint);\r
    function decimals() external view returns (uint8);\r
}\r
\r
contract ERC20InheritanceVaultV2 {\r
    // Roles y parámetros inmutables vinculados a la creación\r
    address public immutable testator;\r
    address public immutable commissionWallet;\r
    address public immutable token; // ERC-20 (USDC/USDT/DoC, etc.)\r
    uint16  public immutable feeBps; // comisión en basis points (80 = 0.8%)\r
    uint256 public immutable minDeposit; // mínimo en unidades del token\r
\r
    // Estado de la herencia\r
    address public heir;\r
    uint public lastCheckIn;\r
    uint public immutable inactivityPeriod;\r
    uint public createdAt;\r
\r
    enum Status { Active, Released, Cancelled }\r
    Status public inheritanceStatus;\r
\r
    // V2 versioning simple (útil para indexación/UX)\r
    uint16 public constant VERSION_MAJOR = 2;\r
    uint16 public constant VERSION_MINOR = 0;\r
\r
    // Eventos equivalentes a V1, adaptados a ERC-20\r
    event InheritanceRegistered(address indexed testator, address indexed heir, uint amount, uint inactivityPeriod);\r
    event CheckInPerformed(address indexed testator, uint timestamp);\r
    event InheritanceReleased(address indexed heir, uint amount);\r
    event InheritanceCancelled(address indexed testator, uint refundedAmount);\r
\r
    constructor(\r
        address _testator,\r
        uint _inactivityPeriod,\r
        address _commissionWallet,\r
        address _token,\r
        uint16 _feeBps,\r
        uint256 _minDeposit\r
    ) {\r
        require(_testator != address(0), "Invalid testator");                 // BΔLT-005 style\r
        require(_commissionWallet != address(0), "Invalid commission wallet");// BΔLT-005\r
        require(_token != address(0), "Invalid token");\r
        require(_feeBps < 10_000, "fee too high"); // < 100%\r
        testator = _testator;\r
        commissionWallet = _commissionWallet;\r
        token = _token;\r
        feeBps = _feeBps;\r
        minDeposit = _minDeposit;\r
\r
        inactivityPeriod = _inactivityPeriod;\r
        lastCheckIn = block.timestamp;\r
        createdAt = block.timestamp;\r
        inheritanceStatus = Status.Active;\r
    }\r
\r
    // El testador registra heredero y deposita tokens vía allowance+transferFrom\r
    function registerInheritance(address _heir, uint256 depositAmount) external {\r
        require(msg.sender == testator, "Only the testator can register");\r
        require(_heir != address(0), "Invalid heir address"); // BΔLT-006\r
        require(heir == address(0), "Inheritance already registered");\r
        require(inheritanceStatus == Status.Active, "Inheritance not active");\r
        require(depositAmount >= minDeposit, "Deposit too small"); // BΔLT-003 (versión ERC-20)\r
\r
        // Calcular fee\r
        uint256 fee = (depositAmount * feeBps) / 10_000;\r
        require(fee > 0, "Amount too low for fee");\r
        uint256 netAmount = depositAmount - fee;\r
\r
        // Transferir tokens: fee -> commission, net -> vault\r
        require(IERC20(token).transferFrom(testator, commissionWallet, fee), "Commission transfer failed");\r
        require(IERC20(token).transferFrom(testator, address(this), netAmount), "Deposit transfer failed");\r
\r
        heir = _heir;\r
        lastCheckIn = block.timestamp;\r
\r
        emit InheritanceRegistered(testator, heir, netAmount, inactivityPeriod);\r
    }\r
\r
    function performCheckIn() external {\r
        require(msg.sender == testator, "Only the testator");\r
        require(inheritanceStatus == Status.Active, "Not active");\r
        lastCheckIn = block.timestamp;\r
        emit CheckInPerformed(testator, lastCheckIn);\r
    }\r
\r
    function cancelInheritance() external {\r
        require(msg.sender == testator, "Only testator");\r
        require(inheritanceStatus == Status.Active, "Not active");\r
        uint bal = IERC20(token).balanceOf(address(this));\r
        require(bal > 0, "No balance");\r
        inheritanceStatus = Status.Cancelled;\r
        require(IERC20(token).transfer(testator, bal), "Refund failed");\r
        emit InheritanceCancelled(testator, bal);\r
    }\r
\r
    function claimInheritance() external {\r
        require(block.timestamp >= lastCheckIn + inactivityPeriod, "Testator active");\r
        require(inheritanceStatus == Status.Active, "Not active");\r
        require(msg.sender == heir, "Only heir");\r
        inheritanceStatus = Status.Released;\r
        uint bal = IERC20(token).balanceOf(address(this));\r
        require(IERC20(token).transfer(heir, bal), "Transfer failed");\r
        emit InheritanceReleased(heir, bal);\r
    }\r
\r
    function getInheritanceDetails() external view returns (\r
        address _heir,\r
        uint _lastCheckIn,\r
        uint _createdAt,\r
        Status _status,\r
        address _token,\r
        uint16 _feeBps,\r
        uint256 _minDeposit\r
    ) {\r
        return (heir, lastCheckIn, createdAt, inheritanceStatus, token, feeBps, minDeposit);\r
    }\r
}"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "evmVersion": "paris",
    "outputSelection": {
      "*": {
        "*": [
          "evm.bytecode",
          "evm.deployedBytecode",
          "devdoc",
          "userdoc",
          "metadata",
          "abi"
        ]
      }
    }
  }
}}

Tags:
Factory|addr:0xf714422cdeee04cf6dad14c22f8eb28ab70a9633|verified:true|block:23533224|tx:0x114c7387c1379164762294eea2af5b4ca0a1036268636aee9d302713135df0ed|first_check:1759936098

Submitted on: 2025-10-08 17:08:18

Comments

Log in to comment.

No comments yet.