A secure and simple Ethereum vault contract that allows users to deposit and withdraw ETH with overflow/underflow protection.
VaultManager is a Solidity smart contract designed to manage user deposits and withdrawals of ETH in a secure way. It uses a custom Math library to prevent arithmetic overflows and underflows, and enforces proper access control and validation.
Built with Solidity 0.8.30, it leverages modern best practices while maintaining clarity and safety.
- Deposit ETH – Users can deposit any amount greater than 0.
- Withdraw ETH – Users can withdraw up to their deposited balance.
- Safe Math Operations – Custom
Mathlibrary prevents overflow and underflow. - Balance Tracking – Each user’s balance is tracked on-chain.
- Event Logging – Deposits and withdrawals are emitted as events.
- Contract Balance Check – Ensures the contract has enough funds before withdrawal.
A simple safe math library for addition and subtraction.
| Function | Description |
|---|---|
add(uint256 a, uint256 b) |
Returns a + b with overflow check |
sub(uint256 a, uint256 b) |
Returns a - b with underflow check |
Note: Solidity 0.8+ has built-in overflow checks, but this library provides explicit, readable safety.
Base contract containing shared state, modifiers, and utilities.
balances[address]– Tracks each user’s deposited ETH balance.
Deposited(address indexed user, uint256 amount)– Emitted on deposit.Withdrawn(address indexed user, uint256 amount)– Emitted on withdrawal.
validDepositAmount(uint256 amount)– Ensures deposit amount > 0.sufficientBalance(uint256 amount)– Ensures user has enough balance.
getContractBalance()– Returns the current ETH balance of the contract.
Implements core deposit and withdrawal functionality.
| Function | Visibility | Payable | Modifiers | Description |
|---|---|---|---|---|
deposit() |
external |
Yes | validDepositAmount |
Accepts ETH and updates user balance |
withdraw(uint256 amount) |
external |
❌ No | sufficientBalance |
Transfers ETH to user if balance and contract funds allow |
Uses low-level
.callfor ETH transfer to avoid issues with contracts that don’t implementreceive().
- Reentrancy Protection: Not strictly needed here since state is updated before transfer, but consider adding
ReentrancyGuardin extended versions. - Arithmetic Safety:
Mathlibrary ensures no overflows/underflows. - Balance Validation: Checks both user and contract balance before withdrawal.
- Use of
.call: Safer than.transfer(); includes success check.
Future improvement: Add a reentrancy guard if extending functionality.
// Send 1 ETH to deposit
await vaultManager.deposit({ value: ethers.parseEther("1.0") });// Withdraw 0.5 ETH
await vaultManager.withdraw(ethers.parseEther("0.5"));Deploy using Hardhat, Foundry, or other Ethereum development tools.
Ensure your deployment environment includes:
- Solidity compiler
^0.8.30 - Sufficient ETH in the contract to support withdrawals
SPDX-License-Identifier: MIT
contracts/
└── VaultManager.sol
test/
└── vaultManager.test.js # (You can create this)
scripts/
└── deploy.js
- Add reentrancy guard via OpenZeppelin.
- Support multiple tokens (ERC-20) in addition to ETH.
- Add admin functions for emergency withdrawal or fee collection.
- Implement withdrawAll() convenience function.
- Add Slippage/timelock for advanced vaults.
Built with Hardhat and inspired by secure vault patterns in the Ethereum ecosystem.
Always test on local or testnet before deploying to mainnet.