// SPDX-License-Identifier: MIT pragma solidity 0.8.30; // Disposable no-value fixtures for Robinhood Chain Testnet only contract TeylTestUSD { string public constant name = "Teyl Test USD - No Value"; string public constant symbol = "tUSD"; uint8 public constant decimals = 2; address public immutable operator; uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); constructor() { require(block.chainid == 46630, "TESTNET_ONLY"); operator = msg.sender; } function mint(uint256 value) external { require(msg.sender == operator, "OPERATOR_ONLY"); require(totalSupply + value <= 100_000_000, "FIXTURE_CAP"); balanceOf[operator] += value; totalSupply += value; emit Transfer(address(0), operator, value); } function approve(address spender, uint256 value) external returns (bool) { allowance[msg.sender][spender] = value; emit Approval(msg.sender, spender, value); return true; } function transfer(address to, uint256 value) external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom(address from, address to, uint256 value) external returns (bool) { require(allowance[from][msg.sender] >= value, "ALLOWANCE"); allowance[from][msg.sender] -= value; _transfer(from, to, value); return true; } function _transfer(address from, address to, uint256 value) private { require(to != address(0) && balanceOf[from] >= value, "BALANCE"); balanceOf[from] -= value; balanceOf[to] += value; emit Transfer(from, to, value); } } contract TeylRiskHarness { TeylTestUSD public immutable asset; address public immutable operator; uint256 public immutable expiresAt; uint256 public capital; uint256 public reserved; uint256 public totalPaid; struct Policy { uint256 limit; uint256 deadline; bool closed; } mapping(bytes32 => Policy) public policies; mapping(bytes32 => bool) public usedEvents; event Deposited(uint256 amount, uint256 capital); event Committed(bytes32 indexed policyId, uint256 limit, uint256 deadline); event Settled(bytes32 indexed policyId, bytes32 indexed eventId, bytes32 evidenceHash, uint256 deficit, uint256 bufferUsed, uint256 payment, uint256 uncovered); event Released(bytes32 indexed policyId, uint256 amount); event Withdrawn(uint256 amount, uint256 capital); modifier onlyOperator() { require(msg.sender == operator, "OPERATOR_ONLY"); _; } modifier active() { require(block.timestamp < expiresAt, "HARNESS_EXPIRED"); _; } constructor(address asset_, uint256 expiresAt_) { require(block.chainid == 46630, "TESTNET_ONLY"); asset = TeylTestUSD(asset_); operator = msg.sender; require(asset.operator() == msg.sender && asset.decimals() == 2, "FIXTURE_ASSET_ONLY"); require(expiresAt_ > block.timestamp && expiresAt_ <= block.timestamp + 72 hours, "EXPIRY"); expiresAt = expiresAt_; } function freeCapital() public view returns (uint256) { return capital - reserved; } function deposit(uint256 amount) external onlyOperator active { require(amount > 0, "ZERO_AMOUNT"); capital += amount; require(asset.transferFrom(msg.sender, address(this), amount), "TRANSFER"); emit Deposited(amount, capital); } function commit(bytes32 policyId, uint256 limit, uint256 deadline) external onlyOperator active { require(policyId != bytes32(0) && policies[policyId].deadline == 0, "POLICY_EXISTS"); require(limit > 0 && limit <= freeCapital(), "CAPACITY"); require(deadline > block.timestamp && deadline <= expiresAt, "DEADLINE"); policies[policyId] = Policy(limit, deadline, false); reserved += limit; emit Committed(policyId, limit, deadline); } // Inputs and eligibility are manually supplied test evidence, not an oracle or real liquidation function settle(bytes32 policyId, bytes32 eventId, bytes32 evidenceHash, uint256 debt, uint256 proceeds, uint256 costs, uint256 protocolBuffer, bool eligible) external onlyOperator active { Policy storage policy = policies[policyId]; require(policy.deadline != 0 && !policy.closed, "POLICY_CLOSED"); require(block.timestamp < policy.deadline, "LATE_EVIDENCE"); require(eventId != bytes32(0) && !usedEvents[eventId], "EVENT_REPLAY"); require(evidenceHash != bytes32(0), "MISSING_EVIDENCE"); uint256 due = debt + costs; uint256 deficit = due > proceeds ? due - proceeds : 0; uint256 bufferUsed = deficit < protocolBuffer ? deficit : protocolBuffer; uint256 residual = deficit - bufferUsed; uint256 payment = eligible ? (residual < policy.limit ? residual : policy.limit) : 0; policy.closed = true; usedEvents[eventId] = true; reserved -= policy.limit; capital -= payment; totalPaid += payment; if (payment > 0) require(asset.transfer(operator, payment), "TRANSFER"); emit Settled(policyId, eventId, evidenceHash, deficit, bufferUsed, payment, residual - payment); } function release(bytes32 policyId) external onlyOperator { Policy storage policy = policies[policyId]; require(policy.deadline != 0 && !policy.closed, "POLICY_CLOSED"); require(block.timestamp >= policy.deadline, "NOT_EXPIRED"); policy.closed = true; reserved -= policy.limit; emit Released(policyId, policy.limit); } function withdraw(uint256 amount) external onlyOperator { require(amount > 0 && amount <= freeCapital(), "RESERVED_CAPITAL"); capital -= amount; require(asset.transfer(operator, amount), "TRANSFER"); emit Withdrawn(amount, capital); } }