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] |
false → true |
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" |
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" |
View Functions
Function: registrationFee()
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: 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: totalPending()
Function: feeRecipient()
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: 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: 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: owner()
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: distributor()
Function: registeredUserCount()
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) |