ExitNow - OVM Builder Blitz 1st 🥇
ExitNow is an instant exit layer for Obol Validator Managers (OVMs). It advances liquidity to stakers while enforcing accountability via an on-chain state machine, deadlines, and a bond. ExitNow is built on top of the Ovm
⚠️ IMPORTANT WARNING
This contract has only undergone basic functional testing. DO NOT USE ON MAINNET. It is recommended to use only on testnets and conduct thorough security audits before considering mainnet deployment.
When the network is congested, validator exits can take many days and your principal gets stuck. ExitNow provides immediate liquidity; it doesn’t make protocol exits faster—it simply bridges the liquidity gap caused by the wait.
ExitNow provides immediate liquidity for Ethereum validators by:
- Instant Liquidity: ExitNow advances 99% while withholding a 3.5% bond; net to staker ≈ 95.5%
- Bonded Security: A 3.5% bond ensures accountability against slashing or inactivity penalties
- EIP-7002 Integration: Uses OVM's withdrawal mechanisms which internally leverage EIP-7002
Ovm address:0xFf15ad0DD7574992eEDa2Bd92cDc3AB34Bb382f1
ExitNow address:0x6110bc76138cA3C9A77b14728e95Df28D54D8D98
All testing was conducted using Foundry.
The diagram above illustrates the complete ExitNow process flow in the normal case where the staker is the OVM Owner and everything operates correctly:
- Staker calls
exit_setup(): The staker (who owns the OVM) initiates the exit process by calling the ExitNow contract with validator public keys - Validation checks: ExitNow validates OVM contract, principal stake (≥32 ETH), and contract balance sufficiency
- Request ownership: ExitNow calls
requestOwnershipHandover()on the OVM to initiate ownership transfer - Complete ownership: Staker calls
completeOwnershipHandover()to transfer OVM ownership to ExitNow
- Staker calls
exit_execute(): The staker triggers the execution phase with matching validator public keys - Validation: ExitNow verifies public key hash, ownership, and sufficient contract balance
- Request withdrawals: ExitNow calls
requestWithdrawal()on the OVM with system contract fees - Transfer funds to staker: ExitNow advances 99% of principal value, withholding 3.5% as bond (net to staker ≈ 95.5%)
- Set deadline: 60-day withdrawal deadline is established for completion
- Validator exits: When validators have exited, the contract owner uses
withdrawOvm()to trigger fund distribution from the OVM - Fund distribution: The OVM calls
distributeFunds()to transfer principal stake back to ExitNow - Automatic settlement: ExitNow's
receive()function automatically processes the funds:- If full expected amount received: Returns 3.5% bond to staker and transitions to
Settledphase - If insufficient funds or past deadline: Confiscates bond as penalty
- If full expected amount received: Returns 3.5% bond to staker and transitions to
exit_setup(): Initiates exit process with validator public keys and validates OVM contractexit_execute(): Executes withdrawal with public key verification and advances 99% to staker (withholding 3.5% bond)withdrawOvm(): Triggers fund distribution from OVM after validator exits (owner only)cancel_ownership_handover(): Cancels exit when ExitNow owns OVM and returns ownership to stakercancel_exit(): Cancels exit when staker still owns OVM and resets statereceive(): Handles fund reception and automatic bond settlement based on success/failure
The contract enforces strict state transitions:
- None: Initial state, no exit process initiated
- Setup: Exit initiated, ownership handover requested
- Executed: Withdrawal triggered, funds advanced to staker
- Settled: Process completed, bond returned or confiscated
ExitNow is built on top of the Ovm, leveraging the following OVM operations:
requestOwnershipHandover(): Initiates ownership transfer processtransferOwnership(): Transfers ownership back to staker during cancellationrequestWithdrawal(): Triggers validator withdrawals with system contract fees (uses EIP-7002 internally)setPrincipalRecipient(): Sets ExitNow as fund recipientdistributeFunds(): Distributes available funds back to ExitNowamountOfPrincipalStake(): Gets current principal stake amountprincipalThreshold(): Gets withdrawal threshold per validator
- Foundry development framework
- OVM contract deployed via Obol Network's factory
- OVM contract with minimum 32 ETH stake
- Validator public keys for withdrawal
- Access to Obol Network's distributed validator infrastructure
git clone <repository-url>
cd ExitNow
forge installforge buildforge testforge script script/Deploy.s.sol --rpc-url <your_rpc_url> --private-key <your_private_key>The current design targets individual liquidity providers but is architected for future expansion into:
- Non-custodial marketplace for validator exits
- Programmable validator exit platform
- Advanced DeFi integrations
src/
├── ExitNow.sol # Main contract
├── ovm/
│ ├── ObolValidatorManager.sol
│ └── ObolValidatorManagerFactory.sol
└── interfaces/
└── IENSReverseRegistrar.sol
test/
├── ExitNow.t.sol # Main test suite
└── mocks/ # Mock contracts for testing
# Run all tests
forge test
# Run with verbosity
forge test -vv
# Run specific test
forge test --match-test testExitSetup
# Generate gas report
forge test --gas-reportforge fmtThis contract is a proof of concept and has known security risks—for example, validator slashing, validator inactivity, and spoofed validator pubkey lists.
For more comprehensive validator verification, consider incorporating the beacon state root and SSZ proofs.
Loom:https://www.loom.com/share/54a08fc4bf1b4322b81c3096f44b7eb1?sid=b82826d1-8422-434f-8a83-1ca91a89fa34
This project is licensed under the MIT License - see the LICENSE file for details.
