Immutable Limits
Protocol constants — minimum and maximum inactivity periods, and the recovery retry limit.
All of the values on this page are immutable — they are set at deployment time via the constructor and cannot be changed afterward. There is no governance mechanism, no admin function, and no upgrade path that can modify them once the contract is deployed.
The constructor validates all values and reverts deployment if any are out of bounds — for example, a zero minInactivityPeriod_, a maxInactivityPeriod_ set below minInactivityPeriod_, or a zero maxRecoveryAttempts_.
Deployed Values
The table below shows the values for the live Sepolia deployment (0x9Eb95e4b47aECCB131f20AE7af33A29832499067) and the planned mainnet values.
| Constant | Sepolia (live) | Mainnet (planned) | What it controls |
|---|---|---|---|
MIN_INACTIVITY_PERIOD | 5 min | 180 days | Shortest inactivity period a user can set |
MAX_INACTIVITY_PERIOD | 3,650 days | 3,650 days (10 years) | Longest inactivity period — prevents permanent lock-up |
MAX_RECOVERY_ATTEMPTS | 3 | 3 | Consecutive failures before a vault is abandoned |
Why These Values?
MIN_INACTIVITY_PERIOD: 180 days
The 180-day floor exists to prevent accidental recovery. A trip or an unusually busy period could easily produce a gap of a few months in someone's blockchain activity. Below 180 days, the risk of unintended recovery becomes meaningful for real-world users.
On Sepolia, the minimum is set to 5 minutes (300 seconds) specifically to allow developers and testers to observe the full recovery cycle within a single session.
MAX_INACTIVITY_PERIOD: 3,650 days (~10 years)
The 10-year ceiling prevents a pathological case where a user sets an astronomically long period (say, 100 years) and their vault balance becomes permanently irrecoverable. If someone has been inactive for 10 years, recovery is almost certainly appropriate.
MAX_RECOVERY_ATTEMPTS: 3
Three attempts give a broken backup address a fair chance to be fixed — perhaps it was a multisig temporarily misconfigured, or a contract with a bug that's since been patched. After three consecutive failures, the protocol stops retrying rather than letting a permanently broken address consume gas indefinitely: without a cap, whichever address ends up submitting triggerRecovery() for that wallet would keep burning real ETH on a transfer that can never succeed.
Reading These Values On-Chain
All immutable constants are publicly accessible as public immutable Solidity variables, readable via automatically generated getter functions:
// Read all immutable limits
const minInactivityPeriod = await vault.read.MIN_INACTIVITY_PERIOD() // 300 (Sepolia) / 15552000 (mainnet)
const maxInactivityPeriod = await vault.read.MAX_INACTIVITY_PERIOD() // 315360000
const maxRecoveryAttempts = await vault.read.MAX_RECOVERY_ATTEMPTS() // 3Frontends and integrators should read these values from the contract rather than hardcoding them, since different deployments (Sepolia vs mainnet vs future chains) use different values.