This project implements a gated version of the Ethereum 2.0 deposit contract with token-based access control.
The architecture maintains the integrity of the original Ethereum 2.0 deposit contract while adding a gating mechanism through a separate contract. This design ensures:
The GatedDepositContract is virtually identical to the mainnet deposit contract, with only a single additional check added to the deposit function. This ensures it behaves exactly like the mainnet deposit contract in all aspects:
- Same deposit tree structure and hashing
- Same event signatures and data
- No additional events emitted (important: custom events broke Sepolia during the Electra fork)
- Same validation rules and constraints
The only modification is a call to depositGater.check_deposit() before processing each deposit.
All gating logic is isolated in the TokenDepositGater contract, which handles:
- ERC20 token functionality for deposit permissions
- Access control and role management
- Token burning on deposit (1 token per validator deposit)
- Special handling for top-up deposits (no token burn required)
This separation ensures that:
- The deposit contract remains as close to mainnet as possible
- All complex logic is contained in the gater contract
- GatedDepositContract: Nearly identical to the ETH2 deposit contract, with a single gater check added
- TokenDepositGater: ERC20 token that acts as a gating mechanism, burning 1 token per deposit (except for top-ups)
# Set your deployer private key
npx hardhat vars set GATED_DEPOSIT_DEPLOYER_PRIVATE_KEY
# Deploy to network
npx hardhat run scripts/deploy-full.js --network <network-name>This will:
- Deploy TokenDepositGater
- Deploy GatedDepositContract with the gater address
- Grant DEPOSIT_CONTRACT_ROLE to the GatedDepositContract
# Set environment variables
export EXISTING_DEPOSIT_CONTRACT=0x... # Address of existing GatedDepositContract
# Deploy to network
npx hardhat run scripts/deploy-gater-only.js --network <network-name>This will:
- Deploy TokenDepositGater
- Grant DEPOSIT_CONTRACT_ROLE to the existing deposit contract
Note: You'll need to update the existing GatedDepositContract to point to the new gater address.
To mint deposit tokens for a specific address:
# Set environment variables
export TOKEN_DEPOSIT_GATER_ADDRESS=0x... # TokenDepositGater contract address
export RECIPIENT_ADDRESS=0x... # Address to receive tokens
export MINT_AMOUNT=10 # Number of tokens to mint (optional, defaults to 1)
# Run minting script
npx hardhat run scripts/mint-tokens.js --network <network-name>Note: The signer must have DEFAULT_ADMIN_ROLE on the TokenDepositGater contract.
Configured networks:
hardhat- Local developmentsepolia- Sepolia testnetholesky- Holesky testnethoodi- Hoodi testnetephemery- Ephemery testnet
npm install
npm run buildnpm test