2.4. Dynamic Dead Man’s Switch
Fixed block-based or hardcoded time timeouts are fundamentally fragile in Layer 2 environments. Sequencer halts, network congestion, or off-chain FHEOS latency can easily exceed static deadlines, trapping user escrow funds indefinitely and creating centralized points of failure.
Fhenix-FairMarket v2.0 replaces rigid deadlines with a Dynamic Dead Man’s Switch that calculates resolution timeouts based on real-time network block production rates (Moving Time Average). This mechanism ensures the protocol remains resilient to infrastructure degradation, automatically triggering a VOIDED state and unlocking 100% of escrowed capital without manual intervention or trusted admin keys.
Core Design Principles
| Principle | Technical Implementation |
|---|---|
| Network-Volatility Awareness | Timeout thresholds are derived dynamically from recent block.timestamp deltas, not hardcoded block counts or fixed seconds. |
| Self-Compensating Multiplier | A × 1.5 factor is applied to the average block time, absorbing temporary latency spikes while preventing premature voiding. |
| Automatic State Transition | If block.timestamp >= endTime + dynamicTimeout without a valid AVS resolution, the contract autonomously transitions to VOIDED. |
| Trustless Capital Recovery | Bypasses FHE decryption requirements; directly opens claimRefund() paths for all participants, guaranteeing full liquidity return. |
| Funds Over Privacy | Enforces the protocol’s highest-priority principle: capital safety supersedes cryptographic settlement during critical infrastructure failures. |
️ Technical Implementation
1. Dynamic Timeout Calculation (_getResolutionTimeout)
The timeout function reads the time delta between the current block and the last recorded block, applying a volatility buffer to determine the resolution window.
// packages/contracts/core/FhenixFairMarket.sol
/**
* @notice Calculates network-adaptive timeout based on recent block production
* @return timeout Duration in seconds before Dead Man's Switch triggers
*/
function _getResolutionTimeout() internal view returns (uint256) {
// Prevent division by zero on initial blocks
uint256 lastTime = lastBlockTimestamp > 0 ? lastBlockTimestamp : block.timestamp - 12;
uint256 avgBlockTime = block.timestamp - lastTime;
// Self-compensating factor absorbs network congestion/spikes
return avgBlockTime * 1.5;
}2. Fallback Void Trigger (triggerFallbackVoid)
Permissionless and automated, this function validates the timeout breach, locks further cryptographic processing, and transitions the auction to a safe recovery state.
function triggerFallbackVoid(uint256 auctionId) external {
Auction storage auction = auctions[auctionId];
require(auction.state == AuctionState.RESOLVING, "Invalid state");
uint256 dynamicThreshold = _getResolutionTimeout();
require(block.timestamp > auction.endTime + dynamicThreshold, "Timeout not exceeded");
// Transition to safe void state
auction.state = AuctionState.VOIDED;
auction.fheEngineActive = false; // Disable further decryption attempts
emit AuctionVoided(auctionId, block.timestamp, dynamicThreshold);
// Pull-refund paths automatically unlock for all participants
}3. Test Simulation Architecture (DynamicTimeout.test.ts)
To verify resilience, Phase 2 includes a dedicated test suite simulating prolonged network degradation:
// packages/contracts/test/unit/DynamicTimeout.test.ts
it("should auto-void auction after 30-min sequencer outage simulation", async () => {
const timeout = await contract._getResolutionTimeout();
await network.provider.send("evm_increaseTime", [timeout + 1]);
await network.provider.send("evm_mine");
await contract.triggerFallbackVoid(auctionId);
expect(await contract.getAuctionState(auctionId)).to.equal("VOIDED");
expect(await contract.getEscrowBalance(bidder)).to.equal(initialDeposit);
});Architectural Impact & Comparison
| Metric | Traditional Fixed Timeout | Fhenix-FairMarket Dynamic Switch |
|---|---|---|
| Timeout Basis | Hardcoded blocks (e.g., 100 blocks) | Real-time Moving Time Average of block.timestamp |
| Sequencer Halt Response | Funds trapped until timeout expires | Timeout scales proportionally with halt duration |
| Network Congestion Spikes | Premature voiding or false triggers | × 1.5 multiplier absorbs temporary latency |
| Admin Intervention | Often requires multisig override | Fully autonomous & permissionless |
| Capital Recovery Guarantee | Dependent on post-fail manual scripts | Immediate claimRefund() unlock post-void |
️ Security Guarantees & Threat Mitigations
| Threat Vector | Attack Mechanism | Dynamic Switch Mitigation |
|---|---|---|
| Sequencer Outage / L2 Halt | Block production stops, fixed timer expires, funds lock indefinitely | Timeout auto-adjusts to 0 progression; void only triggers after actual network time resumes + multiplier |
| FHEOS / AVS Downtime | Off-chain processors fail, no resolution submitted | Contract detects missing AVS proof, applies dynamic threshold, safely voids auction |
| Network Congestion Spikes | Temporary gas wars delay block production by 2x–3x | × 1.5 self-compensating factor prevents premature state transitions |
| Malicious Keeper Delays | Keeper intentionally delays triggerFinalize() to exploit deadline | Threshold is contract-enforced via block.timestamp, not keeper-controlled |
| State Manipulation Attempts | Forged lastBlockTimestamp to alter timeout | Timestamp pulled directly from chain state; view function prevents external write access |
Audit Gate Compliance (P0)
The protocol enforces strict dynamic timeout verification gates. Progression to subsequent phases is blocked until all P0 items pass:
- [] Zero Hardcoded Block Counts:
_getResolutionTimeout()derives exclusively fromblock.timestampdeltas; no static integers used. - [] 100% Liquidity Recovery:
triggerFallbackVoid()guarantees fullescrowBalancesreturn; no partial locks or fee deductions applied. - [] FHE Engine Auto-Disable: Post-void state sets
fheEngineActive = false, preventing further decryption attempts on stranded ciphertexts. - [] Permissionless Execution: Any user, keeper, or automated script can invoke
triggerFallbackVoid()after threshold breach; noonlyOwnerrestriction. - [] Network Volatility Simulation:
DynamicTimeout.test.tssuccessfully passes 30-minute sequencer outage & congestion spike simulations.
Next Steps
- Proceed to 2.5. Fraud Proofs & Slashing to understand how EigenLayer AVS cryptoeconomically secures off-chain results.
- Review 2.6. Collateral-Pegged Escrow for solvency verification and spam mitigation mechanics.
- Explore Market Mechanics to see how dynamic timeouts integrate with sealed-bid workflows and MEV protection.