Skip to content

Functions

DISCLAIMER // NFA // DYOR

This analysis is based on decompiled bytecode — the contract source code is not verified on
Etherscan. Function names, parameter types, and internal logic are inferred from selector
matching, transaction input decoding, and event log analysis. We are not smart contract
security experts. This document should not be considered a comprehensive security audit or
financial advice. Always verify critical information independently.

⊙ generated by robots | curated by humans

METADATA
Contract Address 0xD8706D2D...dC2C2c (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-03-29

Function Selectors

SELECTOR FUNCTION SIGNATURE CATEGORY
0xd7740ee1 registerPool() User
0x4e71d92d claim() User
0x23b221a0 claimAmount(uint256) User
0xa4c1e9c0 depositToUser(address) Admin
0x30a90736 batchDeposit(address[],uint256[]) Admin
0x75619ab5 setDistributor(address) Admin
0xe74b981b setFeeRecipient(address) Admin
0xc320c727 setRegistrationFee(uint256) Admin
0xdb2e21bc emergencyWithdraw() Admin
0xf2fde38b transferOwnership(address) Admin
0x14c44e09 registrationFee() View
0x1e1c6a07 poolExists(address) View
0x31fbea69 totalClaimed(address) View
0x3f90916a totalPending() View
0x46904840 feeRecipient() View
0x67b40cf7 rewardBalance(address) View
0x70a08231 balanceOf(address) View
0x7259e0f8 registeredUsers(uint256) View
0x8da5cb5b owner() View
0xbbb85188 getPoolStats() View
0xbfe10928 distributor() View
0xcb3d0564 registeredUserCount() View
0xf3234ff7 lastCreditedAt(address) View

Summary

CATEGORY COUNT
Total Functions 23
User Functions 3
Admin Functions 7
View Functions 13

User Functions

Function: registerPool()

Registers the caller as a reward pool participant. Requires payment of the current registration fee (0.001 ETH at deployment). The fee is immediately forwarded to the fee recipient address. Each address can only register once.

ATTRIBUTE VALUE
Selector 0xd7740ee1
Parameters None
Access Anyone, payable
Reentrancy Guard ☑ Yes
FLAG OBSERVATION
Registration is permanent — there is no unregister function
Fee is forwarded to the fee recipient EOA via raw ETH transfer
Fee amount can be changed by the owner at any time via setRegistrationFee()
CONDITION REQUIREMENT
Not already registered poolExists[msg.sender] == false
Sufficient payment msg.value >= registrationFee
STEP ACTION
1 Set poolExists[msg.sender] = true
2 Push msg.sender to registeredUsers array
3 Forward msg.value to feeRecipient via ETH transfer
4 Emit UserRegistered(msg.sender, msg.value)
VARIABLE CHANGE
poolExists[msg.sender] falsetrue
registeredUsers Appended with msg.sender
CONDITION REVERT MESSAGE
Already registered "RewardPoolRegistry: already registered"
Insufficient fee "RewardPoolRegistry: insufficient registration fee"
Fee transfer fails "RewardPoolRegistry: fee transfer failed"
Reentrancy "ReentrancyGuard: reentrant call"
// Reconstructed from bytecode
function registerPool() external payable nonReentrant {
    require(!poolExists[msg.sender],
        "RewardPoolRegistry: already registered");
    require(msg.value >= registrationFee,
        "RewardPoolRegistry: insufficient registration fee");

    poolExists[msg.sender] = true;
    registeredUsers.push(msg.sender);

    (bool success, ) = feeRecipient.call{value: msg.value}("");
    require(success,
        "RewardPoolRegistry: fee transfer failed");

    emit UserRegistered(msg.sender, msg.value);
}

Function: claim()

Withdraws the caller's entire reward balance. The full rewardBalance[msg.sender] is sent as ETH to the caller.

ATTRIBUTE VALUE
Selector 0x4e71d92d
Parameters None
Access Anyone with a non-zero reward balance
Reentrancy Guard ☑ Yes
FLAG OBSERVATION
Balance is zeroed before the ETH transfer (checks-effects-interactions pattern)
Protected by reentrancy guard
CONDITION REQUIREMENT
Non-zero balance rewardBalance[msg.sender] > 0
STEP ACTION
1 Read amount = rewardBalance[msg.sender]
2 Set rewardBalance[msg.sender] = 0
3 Subtract amount from totalPending
4 Transfer amount ETH to msg.sender
5 Emit RewardClaimed(msg.sender, amount, block.timestamp)
VARIABLE CHANGE
rewardBalance[msg.sender] Current balance → 0
totalPending Decreased by amount
CONDITION REVERT MESSAGE
Zero balance "RewardPoolRegistry: nothing to claim"
ETH transfer fails "RewardPoolRegistry: ETH transfer failed"
Reentrancy "ReentrancyGuard: reentrant call"
// Reconstructed from bytecode
function claim() external nonReentrant {
    uint256 amount = rewardBalance[msg.sender];
    require(amount > 0,
        "RewardPoolRegistry: nothing to claim");

    rewardBalance[msg.sender] = 0;
    totalPending -= amount;

    (bool success, ) = msg.sender.call{value: amount}("");
    require(success,
        "RewardPoolRegistry: ETH transfer failed");

    emit RewardClaimed(msg.sender, amount, block.timestamp);
}

Function: claimAmount(uint256)

Withdraws a specified amount from the caller's reward balance. Allows partial claims rather than the all-or-nothing claim() function.

ATTRIBUTE VALUE
Selector 0x23b221a0
Parameters uint256 amount — the ETH amount to withdraw
Access Anyone with sufficient reward balance
Reentrancy Guard ☑ Yes
FLAG OBSERVATION
Tracks cumulative claimed amount in totalClaimed[msg.sender] (slot 4)
Balance is reduced before ETH transfer
CONDITION REQUIREMENT
Non-zero amount amount > 0
Sufficient balance amount <= rewardBalance[msg.sender]
STEP ACTION
1 Subtract amount from rewardBalance[msg.sender]
2 Subtract amount from totalPending
3 Add amount to totalClaimed[msg.sender]
4 Transfer amount ETH to msg.sender
5 Emit RewardClaimed(msg.sender, amount, block.timestamp)
VARIABLE CHANGE
rewardBalance[msg.sender] Decreased by amount
totalPending Decreased by amount
totalClaimed[msg.sender] Increased by amount
CONDITION REVERT MESSAGE
Zero amount "RewardPoolRegistry: zero amount"
Insufficient balance "RewardPoolRegistry: insufficient balance"
ETH transfer fails "RewardPoolRegistry: ETH transfer failed"
Reentrancy "ReentrancyGuard: reentrant call"
// Reconstructed from bytecode
function claimAmount(uint256 amount) external nonReentrant {
    require(amount > 0,
        "RewardPoolRegistry: zero amount");
    require(amount <= rewardBalance[msg.sender],
        "RewardPoolRegistry: insufficient balance");

    rewardBalance[msg.sender] -= amount;
    totalPending -= amount;
    totalClaimed[msg.sender] += amount;

    (bool success, ) = msg.sender.call{value: amount}("");
    require(success,
        "RewardPoolRegistry: ETH transfer failed");

    emit RewardClaimed(msg.sender, amount, block.timestamp);
}

Admin Functions

Function: depositToUser(address)

Credits ETH rewards to a single registered user. The caller must send ETH along with the call, and the entire msg.value is credited to the specified user's reward balance.

ATTRIBUTE VALUE
Selector 0xa4c1e9c0
Parameters address user — the recipient of the reward credit
Access Distributor or Owner only, payable
FLAG OBSERVATION
Does not check if user is registered (no poolExists check)
Updates lastCreditedAt[user] to block.timestamp
CONDITION REQUIREMENT
Authorized caller msg.sender == distributor OR msg.sender == owner
Non-zero address user != address(0)
Non-zero deposit msg.value > 0
STEP ACTION
1 Add msg.value to rewardBalance[user]
2 Add msg.value to totalPending
3 Set lastCreditedAt[user] = block.timestamp
4 Emit RewardDeposited(user, msg.value, block.timestamp)
CONDITION REVERT MESSAGE
Unauthorized caller "RewardPoolRegistry: caller is not distributor or owner"
Zero address "RewardPoolRegistry: zero user address"
Zero deposit "RewardPoolRegistry: zero deposit"
// Reconstructed from bytecode
function depositToUser(address user) external payable {
    require(msg.sender == distributor || msg.sender == owner,
        "RewardPoolRegistry: caller is not distributor or owner");
    require(user != address(0),
        "RewardPoolRegistry: zero user address");
    require(msg.value > 0,
        "RewardPoolRegistry: zero deposit");

    rewardBalance[user] += msg.value;
    totalPending += msg.value;
    lastCreditedAt[user] = block.timestamp;

    emit RewardDeposited(user, msg.value, block.timestamp);
}

Function: batchDeposit(address[],uint256[])

Credits ETH rewards to multiple registered users in a single transaction. The caller must send ETH equal to the sum of all amounts. Each user must be registered (poolExists check enforced here, unlike depositToUser).

ATTRIBUTE VALUE
Selector 0x30a90736
Parameters address[] users, uint256[] amounts — parallel arrays of recipients and ETH amounts
Access Distributor or Owner only, payable
FLAG OBSERVATION
Validates msg.value == sum(amounts) — no over- or under-payment
Requires each user to be registered via poolExists check
depositToUser does not check registration, but batchDeposit does — inconsistency
CONDITION REQUIREMENT
Authorized caller msg.sender == distributor OR msg.sender == owner
Matching array lengths users.length == amounts.length
Non-empty arrays users.length > 0
Value matches sum msg.value == sum(amounts)
Per-user: non-zero address users[i] != address(0)
Per-user: non-zero amount amounts[i] > 0
Per-user: registered poolExists[users[i]] == true
STEP ACTION
1 Validate array lengths and compute sum
2 Verify msg.value == sum
3 For each user: add amounts[i] to rewardBalance[users[i]]
4 For each user: set lastCreditedAt[users[i]] = block.timestamp
5 For each user: emit RewardDeposited(users[i], amounts[i], block.timestamp)
6 Add total sum to totalPending
CONDITION REVERT MESSAGE
Unauthorized caller "RewardPoolRegistry: caller is not distributor or owner"
Length mismatch "RewardPoolRegistry: length mismatch"
Empty arrays "RewardPoolRegistry: empty arrays"
Value mismatch "RewardPoolRegistry: msg.value != sum of amounts"
Zero user address "RewardPoolRegistry: zero user address"
Zero amount for user "RewardPoolRegistry: zero amount for user"
User not registered "RewardPoolRegistry: user not registered"
// Reconstructed from bytecode
function batchDeposit(
    address[] calldata users,
    uint256[] calldata amounts
) external payable {
    require(msg.sender == distributor || msg.sender == owner,
        "RewardPoolRegistry: caller is not distributor or owner");
    require(users.length == amounts.length,
        "RewardPoolRegistry: length mismatch");
    require(users.length > 0,
        "RewardPoolRegistry: empty arrays");

    uint256 total = 0;
    for (uint256 i = 0; i < amounts.length; i++) {
        total += amounts[i];
    }
    require(msg.value == total,
        "RewardPoolRegistry: msg.value != sum of amounts");

    uint256 timestamp = block.timestamp;
    for (uint256 i = 0; i < users.length; i++) {
        require(users[i] != address(0),
            "RewardPoolRegistry: zero user address");
        require(amounts[i] > 0,
            "RewardPoolRegistry: zero amount for user");
        require(poolExists[users[i]],
            "RewardPoolRegistry: user not registered");

        rewardBalance[users[i]] += amounts[i];
        lastCreditedAt[users[i]] = timestamp;

        emit RewardDeposited(users[i], amounts[i], timestamp);
    }

    totalPending += msg.value;
}

Function: setDistributor(address)

Changes the distributor address. Only callable by the owner.

ATTRIBUTE VALUE
Selector 0x75619ab5
Parameters address newDistributor
Access Owner only
STEP ACTION
1 Store old distributor
2 Set distributor = newDistributor
3 Emit DistributorUpdated(oldDistributor, newDistributor)
CONDITION REVERT MESSAGE
Not owner "Ownable: caller is not owner"
Zero address "RewardPoolRegistry: zero distributor"
// Reconstructed from bytecode
function setDistributor(address newDistributor) external {
    require(msg.sender == owner, "Ownable: caller is not owner");
    require(newDistributor != address(0),
        "RewardPoolRegistry: zero distributor");

    address old = distributor;
    distributor = newDistributor;
    emit DistributorUpdated(old, newDistributor);
}

Function: setFeeRecipient(address)

Changes the fee recipient address. Only callable by the owner.

ATTRIBUTE VALUE
Selector 0xe74b981b
Parameters address newRecipient
Access Owner only
STEP ACTION
1 Store old fee recipient
2 Set feeRecipient = newRecipient
3 Emit FeeRecipientUpdated(oldRecipient, newRecipient)
CONDITION REVERT MESSAGE
Not owner "Ownable: caller is not owner"
Zero address "RewardPoolRegistry: zero address"
// Reconstructed from bytecode
function setFeeRecipient(address newRecipient) external {
    require(msg.sender == owner, "Ownable: caller is not owner");
    require(newRecipient != address(0),
        "RewardPoolRegistry: zero address");

    address old = feeRecipient;
    feeRecipient = newRecipient;
    emit FeeRecipientUpdated(old, newRecipient);
}

Function: setRegistrationFee(uint256)

Changes the registration fee amount. Only callable by the owner. The fee can be set to 0, effectively making registration free.

ATTRIBUTE VALUE
Selector 0xc320c727
Parameters uint256 newFee
Access Owner only
STEP ACTION
1 Store old fee
2 Set registrationFee = newFee
3 Emit RegistrationFeeUpdated(oldFee, newFee)
CONDITION REVERT MESSAGE
Not owner "Ownable: caller is not owner"
// Reconstructed from bytecode
function setRegistrationFee(uint256 newFee) external {
    require(msg.sender == owner, "Ownable: caller is not owner");

    uint256 old = registrationFee;
    registrationFee = newFee;
    emit RegistrationFeeUpdated(old, newFee);
}

Function: emergencyWithdraw()

Drains the entire ETH balance of the contract to the owner address. Resets totalPending to zero. No timelock, no Multisig, no restrictions beyond the owner check.

ATTRIBUTE VALUE
Selector 0xdb2e21bc
Parameters None
Access Owner only
FLAG OBSERVATION
Zeroes totalPending — all user balances become effectively uncollectable after this call
No timelock or delay — executes immediately
Does not zero individual user rewardBalance entries — creates a ghost balance state where users appear to have funds but the contract has none
STEP ACTION
1 Read amount = address(this).balance
2 Set totalPending = 0
3 Transfer entire balance to owner
4 Emit EmergencyWithdrawn(owner, amount)
CONDITION REVERT MESSAGE
Not owner "Ownable: caller is not owner"
Zero balance "RewardPoolRegistry: nothing to withdraw"
ETH transfer fails "RewardPoolRegistry: ETH transfer failed"
// Reconstructed from bytecode
function emergencyWithdraw() external {
    require(msg.sender == owner, "Ownable: caller is not owner");

    uint256 amount = address(this).balance;
    require(amount > 0,
        "RewardPoolRegistry: nothing to withdraw");

    totalPending = 0;

    (bool success, ) = owner.call{value: amount}("");
    require(success,
        "RewardPoolRegistry: ETH transfer failed");

    emit EmergencyWithdrawn(owner, amount);
}

Function: transferOwnership(address)

Transfers contract ownership to a new address. Standard Ownable pattern with no two-step verification.

ATTRIBUTE VALUE
Selector 0xf2fde38b
Parameters address newOwner
Access Owner only
STEP ACTION
1 Emit OwnershipTransferred(currentOwner, newOwner)
2 Set owner = newOwner
CONDITION REVERT MESSAGE
Not owner "Ownable: caller is not owner"
Zero address "Ownable: zero address"
// Reconstructed from bytecode
function transferOwnership(address newOwner) external {
    require(msg.sender == owner, "Ownable: caller is not owner");
    require(newOwner != address(0), "Ownable: zero address");

    emit OwnershipTransferred(owner, newOwner);
    owner = newOwner;
}

View Functions

Function: registrationFee()

Returns the current registration fee in wei.

ATTRIBUTE VALUE
Selector 0x14c44e09
Parameters None
Access Public view
Returns uint256 — current fee (slot 8)
function registrationFee() external view returns (uint256) {
    return registrationFee; // slot 8
}

Function: poolExists(address)

Returns whether an address is registered in the reward pool.

ATTRIBUTE VALUE
Selector 0x1e1c6a07
Parameters address user
Access Public view
Returns bool — registration status (slot 9 mapping)
function poolExists(address user) external view returns (bool) {
    return poolExists[user]; // slot 9 mapping
}

Function: totalClaimed(address)

Returns the cumulative amount claimed by a user via claimAmount(). Note: claim() does not update this counter.

ATTRIBUTE VALUE
Selector 0x31fbea69
Parameters address user
Access Public view
Returns uint256 — total claimed (slot 4 mapping)
FLAG OBSERVATION
Only tracks claims via claimAmount(), not claim() — may underreport total withdrawals
function totalClaimed(address user) external view returns (uint256) {
    return totalClaimed[user]; // slot 4 mapping
}

Function: totalPending()

Returns the total unclaimed ETH across all users.

ATTRIBUTE VALUE
Selector 0x3f90916a
Parameters None
Access Public view
Returns uint256 — total pending rewards (slot 6)
function totalPending() external view returns (uint256) {
    return totalPending; // slot 6
}

Function: feeRecipient()

Returns the address that receives registration fees.

ATTRIBUTE VALUE
Selector 0x46904840
Parameters None
Access Public view
Returns address — fee recipient (slot 7)
function feeRecipient() external view returns (address) {
    return feeRecipient; // slot 7
}

Function: rewardBalance(address)

Returns the claimable ETH reward balance for a specific user.

ATTRIBUTE VALUE
Selector 0x67b40cf7
Parameters address user
Access Public view
Returns uint256 — reward balance (slot 3 mapping)
function rewardBalance(address user) external view returns (uint256) {
    return rewardBalance[user]; // slot 3 mapping
}

Function: balanceOf(address)

Alias for rewardBalance(). Returns the same slot 3 mapping value. Uses the ERC-20 balanceOf selector, though this is not an ERC-20 contract.

ATTRIBUTE VALUE
Selector 0x70a08231
Parameters address user
Access Public view
Returns uint256 — reward balance (slot 3 mapping)
FLAG OBSERVATION
Shares the balanceOf selector with ERC-20 but returns ETH reward balance, not token balance
function balanceOf(address user) external view returns (uint256) {
    return rewardBalance[user]; // slot 3 mapping — same as rewardBalance()
}

Function: registeredUsers(uint256)

Returns the address at a given index in the registered users array.

ATTRIBUTE VALUE
Selector 0x7259e0f8
Parameters uint256 index
Access Public view
Returns address — user address at index (slot 10 array)
function registeredUsers(uint256 index) external view returns (address) {
    return registeredUsers[index]; // slot 10 dynamic array
}

Function: owner()

Returns the current contract owner.

ATTRIBUTE VALUE
Selector 0x8da5cb5b
Parameters None
Access Public view
Returns address — owner (slot 1)
function owner() external view returns (address) {
    return owner; // slot 1
}

Function: getPoolStats()

Returns three values summarizing the contract's financial state: total pending rewards, actual ETH balance, and the absolute difference between them.

ATTRIBUTE VALUE
Selector 0xbbb85188
Parameters None
Access Public view
Returns (uint256 totalPending, uint256 contractBalance, uint256 deficit)
FLAG OBSERVATION
The third return value represents the absolute difference between pending and balance — useful for detecting underfunding or surplus
function getPoolStats() external view returns (
    uint256, uint256, uint256
) {
    uint256 pending = totalPending;
    uint256 balance = address(this).balance;
    uint256 diff;
    if (pending > balance) {
        diff = pending - balance;
    } else {
        diff = balance - pending;
    }
    return (pending, balance, diff);
}

Function: distributor()

Returns the current distributor address.

ATTRIBUTE VALUE
Selector 0xbfe10928
Parameters None
Access Public view
Returns address — distributor (slot 2)
function distributor() external view returns (address) {
    return distributor; // slot 2
}

Function: registeredUserCount()

Returns the total number of registered users.

ATTRIBUTE VALUE
Selector 0xcb3d0564
Parameters None
Access Public view
Returns uint256 — length of registeredUsers array (slot 10)
function registeredUserCount() external view returns (uint256) {
    return registeredUsers.length; // slot 10
}

Function: lastCreditedAt(address)

Returns the timestamp of the last reward credit for a given user.

ATTRIBUTE VALUE
Selector 0xf3234ff7
Parameters address user
Access Public view
Returns uint256 — Unix timestamp (slot 5 mapping)
function lastCreditedAt(address user) external view returns (uint256) {
    return lastCreditedAt[user]; // slot 5 mapping
}