Overview
The FenineSystem contract is the heart of Fenines Network’s FPoS (Finality Proof of Stake) consensus. It manages validator registration, staking, delegation, and reward distribution through a unique proximity-based system.Contract Address:
0x0000000000000000000000000000000000001000 (System Contract)Architecture
Validator Lifecycle
Validator Lifecycle
- NOT_EXIST: Address has never registered
- CREATED: Registered with metadata, not yet staked
- STAKED: Staked ≥10,000 FEN, waiting for epoch activation
- VALIDATED: Active validator, earning rewards
- UNSTAKED: Initiated unstake, in lock period
Proximity Reward System
Proximity Reward System
Fenines implements an 8-level proximity (referral) system where:
- When a delegator claims rewards, a portion goes to their uplines (previous stakers to the same validator)
- Default distribution: 30% of rewards distributed across 8 levels
- Per-level allocation:
[7%, 5%, 4%, 3.5%, 3%, 2.5%, 2.5%, 2.5%] - Remainder split 50/50 between claimer and validator
- Anti-Sybil: Minimum stake requirements increase per level
Epoch System
Epoch System
- Epoch Length: 200 blocks (~10 minutes at 3s block time)
- System Transactions: Executed automatically at block % 200 == 0
updateValidatorCandidates()- Activate STAKED → VALIDATEDdistributeBlockReward()- Distribute accumulated rewards
- Validator Set Updates: Only at epoch boundaries
Constants
Validator Functions
registerValidator
Register as a validator (expression of intent).address payable
required
Address to receive rewards (can differ from msg.sender)
string
required
Validator name/identifier (1-128 characters)
string
Contact phone number (optional)
string
Additional metadata (optional)
uint256
required
Commission in basis points (500-1000 = 5-10%)
stakeValidator
Stake as validator (minimum 10,000 FEN).- Status must be
CREATEDorUNSTAKED msg.value >= 10,000 FEN- Contract not paused
- Adds to
selfStakeandtotalStake - Status →
STAKED - Added to
validatorCandidatesarray - Will be activated at next epoch
addValidatorStake
Add more stake to existing validator (top-up).- Status must be
STAKEDorVALIDATED msg.value > 0
- Increases
selfStakeandtotalStake - Does NOT reset stake age or status
unstakeValidator
Initiate validator unstake process.- Status must be
STAKEDorVALIDATED - Not already unstaking
- Status →
UNSTAKED - Sets
unstakeBlock = current block - Removed from
activeValidatorSet - Removed from
validatorCandidates - Lock period: 50,000 blocks (~7 days)
withdrawValidatorStake
Withdraw staked FEN after lock period.unstakeBlock > 0(unstake initiated)block.number >= unstakeBlock + 50000(lock period passed)selfStake > 0
- Transfers
selfStaketo validator - Resets
selfStake = 0 - Status →
CREATED - Can re-stake later
claimValidatorReward
Claim accumulated validator rewards.- Status must be
VALIDATED claimableReward > 0
- Transfers rewards to
rewardAddress - Applies tax via TaxManager
- Resets
claimableReward = 0
updateValidatorMetadata
Update validator information.updateCommissionRate
Update commission rate (only before activation).Delegator Functions
stakeToValidator
Stake FEN to a validator as a delegator.address
required
Validator address to stake to
- Validator status must be
VALIDATED msg.value >= 1,000 FEN- Not currently unstaking
- Whitelisted via NFTPassport contract
- First-time: Added to validator’s
stakersarray (proximity position) - Increases
stakeAmountand validator’stotalStake - Starts earning rewards
Proximity Position: Your position in the stakers array determines proximity rewards. Earlier stakers are deeper in the chain and receive rewards from later stakers.
addDelegatorStake
Add more stake to existing delegation.unstakeDelegator
Initiate delegator unstake process.stakeAmount > 0- Not already unstaking
- Removed from
stakersarray (proximity chain) - Status →
UNSTAKING - Sets
unstakeBlock = current block - Lock period: 25,000 blocks (~3.5 days)
- Pending rewards preserved
withdrawDelegatorStake
Withdraw delegated stake after lock period.claimDelegatorReward
Claim rewards with proximity distribution.View Functions
getActiveValidators
Get list of active validators.getValidatorInfo
Get detailed validator information.getDelegatorInfo
Get delegator stake information.getEstimatedDelegatorReward
Calculate estimated rewards (preview before claiming).getProximityConfig
Get current proximity distribution configuration.getCurrentEpoch
Get current epoch number.getNextEpochReward
Get pending reward pool for next epoch.Admin Functions
setProximityConfig
Update proximity reward distribution.- Only admin can call
newTotalBps <= 8700(87% max)- Array must sum to
newTotalBps
pause / unpause
Emergency pause/unpause contract (inherited from EmergencyControl).changeAdmin
Transfer admin role (inherited from EmergencyControl, with 7-day timelock).Events
Validator Events
Validator Events
Delegator Events
Delegator Events
Proximity Events
Proximity Events
System Events
System Events
Integration Examples
- Become a Validator
- Delegate to Validator
- Claim Rewards
Security Considerations
Reentrancy Protection
Reentrancy Protection
All state-changing functions that transfer ETH use the
nonReentrant modifier to prevent reentrancy attacks.Access Control
Access Control
- User functions: Anyone can call
- System functions: Only
block.coinbase(consensus layer) - Admin functions: Only contract admin with timelock
Anti-Sybil
Anti-Sybil
- Minimum stake requirements per proximity level prevent sybil attacks
- Stake age requirement (100 blocks minimum)
- Unstaking addresses cannot receive proximity rewards
Emergency Controls
Emergency Controls
- Pause functionality (inherited from EmergencyControl)
- 7-day timelock for admin changes
- Emergency withdrawal capability with hooks
Next Steps
NFT Passport Contract
Whitelist and referral system
Tax Manager Contract
Reward tax and burn mechanism
Integration Examples
Complete integration examples
Quick Reference
Common queries and selectors