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"
]
}
}
}
}}
Submitted on: 2025-10-08 16:08:19
Comments
Log in to comment.
No comments yet.