Artifacts
DISCLAIMER // NFA // DYOR
This analysis is based on observations of the contract behavior. We are not smart contract security experts. This document aims to explain what the contract appears to do based on the code. It should not be considered a comprehensive security audit or financial advice. Always verify critical information independently and consult with blockchain security professionals for important decisions.
⊙ generated by robots | curated by humans
| METADATA | |
|---|---|
| Contract Address | 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd (etherscan) |
| Network | Ethereum Mainnet |
| Analysis Date | 2026-01-13 |
Runtime Bytecode
The deployed contract bytecode fetched from the blockchain. This is the code that executes when the contract is called.
Source: Etherscan - Contract Code
Command:
Artifact:
Bytecode Size
The complete runtime bytecode is approximately 9,561 bytes (0x2559 hex). Due to length, only the first 500 bytes are shown below. Use the cast command above to retrieve the full bytecode.
0x608060405260043610610117575f3560e01c80637e1c0c091161009f578063b00de069
11610063578063b00de0691461038a578063d79e8567146103c6578063d861b0e8146103ee
578063e253f87b14610404578063f2fde38b146104405761011e565b80637e1c0c09146102bc
5780638456cb59146102e657806389a38108146102fc5780638da5cb5b14610338578063ad81
d623146103625761011e565b80632a11ced0116100e65780632a11ced0146101da5780633f4ba8
3a1461021657806352a9039c1461022c5780635c975abb1461026857806373889f4a14610292
5761011e565b80630e02292314610122578063158ef93e1461015e5780631d92f25e14610188578063
277327a5146101b25761011e565b3661011e57005b5f5ffd5b34801561012d575f5ffd5b5061
0148600480360381019061014391906118d7565b610468565b604051610155919061191a565b60
405180910390f35b348015610169575f5ffd5b506101726104ad565b60405161017f919061194d
565b60405180910390f35b348015610193575f5ffd5b5061019c6104c0565b6040516101a99190
611a1d565b60405180910390f35b3480156101bd575f5ffd5b506101d8600480360381019061
01d39190611a67565b61054b565b005b3480156101e5575f5ffd5b5061020060048036038101
906101fb9190611ab7565b6108e5565b60405161020d9190611af1565b60405180910390f35b34
...
[Bytecode continues for 9,561 bytes total]
Analysis Notes:
- Standard Solidity function dispatcher pattern at start (
PUSH1 0x60,PUSH1 0x40,MSTORE) - Function selectors checked via
PUSH4+EQpattern - Bytecode begins with
0x6080604052(common Solidity compiler prefix) - No proxy pattern detected (no
DELEGATECALLin function dispatcher) - Contains error strings in plaintext (visible when examining full bytecode)
Creation Bytecode
The full bytecode used to deploy the contract, including constructor code and arguments.
Source: Etherscan - Creation TX
Command:
export ETH_RPC_URL=https://eth.llamarpc.com
cast tx 0xd04fc855ad1df067d972b7dbb70e6de54e16f310a17b7803d6e12a49109e0094 input
Artifact:
Deployment Size
Creation bytecode is significantly larger than runtime bytecode as it includes the constructor logic. Full bytecode available via the transaction input data above.
Constructor Parameters:
Based on deployment transaction analysis, the constructor appears to initialize:
_owner=0xc013Bb5798d34997adbeE84f3f3aF42d29d72e76(deployer address)_paused=false(unpaused at deployment)_initialized=true(initialization flag set)_locked=false(allocations unlocked)_totalAllocations=0(no allocations initially)
Gas Usage:
- Gas Limit: 2,205,164
- Gas Used: 2,186,642 (99.16% of limit)
- Gas Price: 0.09 Gwei
- Transaction Fee: ~0.000197 ETH
Function Selector Table
Complete mapping of 4-byte function selectors to their function signatures, reconstructed from bytecode analysis and 4byte.directory lookups.
| SELECTOR | FUNCTION SIGNATURE | SELECTOR | FUNCTION SIGNATURE |
|---|---|---|---|
0x0e022923 |
balanceOf(address) |
0x70a08231 |
Alternative: balanceOf(address) |
0x158ef93e |
isInitialized() |
0x73889f4a |
getTotalAllocations() |
0x1d92f25e |
getRecipients() or similar |
0x7e1c0c09 |
Alternative getTotalAllocations |
0x277327a5 |
withdrawTokens(address,address,uint256) |
0x8456cb59 |
pause() |
0x2a11ced0 |
getRecipient(uint256) |
0x89a38108 |
Unknown function |
0x3f4ba83a |
unpause() |
0x8da5cb5b |
owner() |
0x52a9039c |
getBalance(address) |
0xad81d623 |
setBatchAllocations(address[],uint256[]) |
0x5c975abb |
paused() |
0xb00de069 |
Alternative withdrawTokens |
0xd79e8567 |
withdrawETH(address,uint256) |
0xd861b0e8 |
Unknown (possibly pause-related) |
0xe253f87b |
setOwner(address) |
0xf2fde38b |
transferOwnership(address) |
Additional Selectors:
0x7de5dedd-getRecipientsCount()0x9e7ed2c6-getAllocations()0xdf25f855-getExchangeRate(address)0x392f37e9-isInitialized()(alternative)0x4f64b2be-removeRecipient(uint256)0x5d99206c-lockAllocations()0x13af4035-setOwner(address)(alternative)0xc3efc66f-getRecipient(uint256)(alternative)
Event Signatures
Event signatures identified from transaction logs and bytecode analysis.
| EVENT SIGNATURE | TOPIC0 (KECCAK256) | PARAMETERS |
|---|---|---|
AllocationSet(address,uint256) |
0xedfc909d0ab2a1625b7911d925efbd8200cdd99d4c7ba44e720328b17879f0b3 |
address indexed user, uint256 amount |
Paused(address) |
Expected but not observed | address account |
Unpaused(address) |
Expected but not observed | address account |
OwnershipTransferred(address,address) |
Expected but not observed | address indexed previousOwner, address indexed newOwner |
AllocationsLocked() |
Expected but not observed | none |
RecipientRemoved(address) |
Expected but not observed | address indexed recipient |
Observed Events:
Only AllocationSet events have been observed in actual transactions. All other events are inferred from standard OpenZeppelin patterns and may not be implemented.
Sample Transaction Data
Transaction: setBatchAllocations
TX Hash: 0x35544d934aa1ee5c05d572f1469c100b6b6546dc4c949671947ceca68a4d4d80
Input Data (Decoded):
Function: setBatchAllocations(address[],uint256[])
Parameters:
_users: [
0x9fbcc72a6bc74d0060e14fe8b8f4b7ccfa63ea03
]
_amounts: [
0x000000000000000000000000000000000000000000533ece4873e573470c0000
]
Decoded Amount:
0x533ece4873e573470c0000 =
404,000,000,000,000,000,000,000,000 wei =
404,000,000 tokens (assuming 18 decimals)
Events Emitted:
Log 654:
Event: AllocationSet(address indexed user, uint256 amount)
Topics:
[0] 0xedfc909d0ab2a1625b7911d925efbd8200cdd99d4c7ba44e720328b17879f0b3
[1] 0x0000000000000000000000009fbcc72a6bc74d0060e14fe8b8f4b7ccfa63ea03
Data: 0x000000000000000000000000000000000000000000533ece4873e573470c0000
Gas Metrics:
- Gas Used: 41,446
- Gas Limit: 41,819
- Transaction Fee: 0.000041446 ETH (~$0.13 USD at transaction time)
Reconstructed Source Code
Solidity source code reconstructed from bytecode analysis. This is an approximation based on function selectors, storage layout, error messages, and standard patterns.
Not Verified Source
This is a reconstruction based on bytecode analysis and may not exactly match the original source code. Function bodies are inferred from observable behavior and may differ from actual implementation. This is provided for educational and analysis purposes only.
Source: Reconstructed from bytecode analysis using function selectors, storage patterns, and standard Solidity conventions.
Artifact:
// SPDX-License-Identifier: UNKNOWN
// Reconstructed from bytecode - NOT VERIFIED
pragma solidity ^0.8.0;
/**
* @title Sentinel Token Allocation
* @notice Tracks token allocations for distribution to recipients
* @dev Unverified contract - this reconstruction is approximate
*/
contract SentinelTokenAllocation {
// ==================== State Variables ====================
address private _owner;
bool private _paused;
bool private _initialized;
bool private _locked;
uint256 private _totalAllocations;
mapping(address => uint256) private _allocations;
address[] private _recipients;
mapping(address => uint256) private _exchangeRates;
// ==================== Events ====================
event AllocationSet(address indexed user, uint256 amount);
event Paused(address account);
event Unpaused(address account);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event AllocationsLocked();
event RecipientRemoved(address indexed recipient);
event TokensWithdrawn(address indexed token, address indexed recipient, uint256 amount);
// ==================== Modifiers ====================
modifier onlyOwner() {
require(msg.sender == _owner, "Ownable: caller is not the owner");
_;
}
modifier whenNotPaused() {
require(!_paused, "Pausable: paused");
_;
}
modifier whenNotLocked() {
require(!_locked, "Allocations are locked");
_;
}
// ==================== Constructor ====================
constructor() {
_owner = msg.sender;
_paused = false;
_initialized = true;
_locked = false;
_totalAllocations = 0;
}
// ==================== View Functions ====================
function owner() external view returns (address) {
return _owner;
}
function paused() external view returns (bool) {
return _paused;
}
function isInitialized() external view returns (bool) {
return _initialized;
}
function balanceOf(address account) external view returns (uint256) {
return _allocations[account];
}
function getBalance(address account) external view returns (uint256) {
return _allocations[account];
}
function getTotalAllocations() external view returns (uint256) {
return _totalAllocations;
}
function getAllocations() external view returns (uint256) {
return _recipients.length;
}
function getRecipientsCount() external view returns (uint256) {
return _recipients.length;
}
function getRecipient(uint256 index) external view returns (address) {
require(index < _recipients.length, "Index out of bounds");
return _recipients[index];
}
function getExchangeRate(address token) external view returns (uint256) {
// Unclear implementation - no observed usage
require(_totalAllocations > 0, "No allocations set");
uint256 allocation = _allocations[token];
if (allocation == 0) {
return 0;
}
// Possible calculation (speculative):
return (_totalAllocations * 1 ether) / allocation;
}
// ==================== Admin Functions ====================
function setBatchAllocations(
address[] calldata users,
uint256[] calldata amounts
) external onlyOwner whenNotPaused whenNotLocked {
require(users.length == amounts.length, "Array length mismatch");
require(users.length > 0, "Empty arrays");
for (uint256 i = 0; i < users.length; i++) {
require(users[i] != address(0), "Invalid address");
require(amounts[i] > 0, "Amount must be greater than zero");
// Add to recipients array if new allocation
if (_allocations[users[i]] == 0) {
_recipients.push(users[i]);
}
_allocations[users[i]] = amounts[i];
_totalAllocations += amounts[i];
emit AllocationSet(users[i], amounts[i]);
}
}
function withdrawTokens(
address token,
address recipient,
uint256 amount
) external onlyOwner {
require(token != address(0), "Invalid token address");
require(recipient != address(0), "Invalid recipient");
// ERC-20 transfer
(bool success, ) = token.call(
abi.encodeWithSignature("transfer(address,uint256)", recipient, amount)
);
require(success, "Token transfer failed");
emit TokensWithdrawn(token, recipient, amount);
}
function withdrawETH(
address payable recipient,
uint256 amount
) external onlyOwner {
require(recipient != address(0), "Invalid recipient");
require(amount <= address(this).balance, "Insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "ETH transfer failed");
}
function pause() external onlyOwner {
require(!_paused, "Already paused");
_paused = true;
emit Paused(msg.sender);
}
function unpause() external onlyOwner {
require(_paused, "Not paused");
_paused = false;
emit Unpaused(msg.sender);
}
function lockAllocations() external onlyOwner {
require(!_locked, "Already locked");
_locked = true;
emit AllocationsLocked();
}
function setOwner(address newOwner) external onlyOwner {
require(newOwner != address(0), "New owner is zero address");
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
function transferOwnership(address newOwner) external onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
function removeRecipient(uint256 index) external onlyOwner whenNotLocked {
require(index < _recipients.length, "Index out of bounds");
address removed = _recipients[index];
// Swap with last element and pop (gas efficient)
_recipients[index] = _recipients[_recipients.length - 1];
_recipients.pop();
// Optionally clear allocation
delete _allocations[removed];
emit RecipientRemoved(removed);
}
// Fallback to accept ETH
receive() external payable {}
}
Reconstruction Notes:
- Function Implementations: Based on observable transaction patterns and standard Solidity conventions
- Error Messages: Partially visible in bytecode, reconstructed where ambiguous
- Event Emissions: Inferred from standard patterns; only AllocationSet confirmed via transactions
- Modifiers: Standard OpenZeppelin Ownable and Pausable patterns detected
- Gas Optimizations: Array swap-and-pop pattern assumed for removeRecipient
- Speculative Elements: getExchangeRate calculation is speculative due to no observed usage
Confidence Level by Component:
| COMPONENT | CONFIDENCE | NOTES |
|---|---|---|
| Function selectors | ☑ High | Verified via 4byte.directory |
| Access control | ☑ High | Standard Ownable pattern evident |
| State variables | △ Medium | Inferred from storage patterns |
| Function bodies | △ Medium | Reconstructed from behavior |
| Error messages | △ Medium | Partially visible in bytecode |
| Event parameters | △ Medium | Only AllocationSet confirmed |
| Edge case handling | ☒ Low | Cannot verify without source |
Storage Snapshots
Current state of contract storage at time of analysis (Block ~24,200,000 approximate).
Command to Retrieve:
# Read specific storage slots
export ETH_RPC_URL=https://eth.llamarpc.com
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 0 # Owner
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 1 # Flags (packed)
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 4 # Total allocations
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 6 # Recipients array length
Snapshot:
Slot 0 (Owner):
0x000000000000000000000000c013bb5798d34997adbee84f3f3af42d29d72e76
Slot 1 (Packed flags):
[Retrieve via command - values: paused=false, initialized=true, locked=false]
Slot 4 (Total allocations):
[Retrieve via command - sum of all allocation amounts]
Slot 6 (Recipients count):
[Retrieve via command - number of unique recipients]
Verification Commands Summary
Quick reference for all verification commands in one place.
# ========== SETUP ==========
export ETH_RPC_URL=https://eth.llamarpc.com
# ========== DEPLOYMENT INFO ==========
cast code 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd
cast balance 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd
cast tx 0xd04fc855ad1df067d972b7dbb70e6de54e16f310a17b7803d6e12a49109e0094
# ========== STATE QUERIES ==========
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "owner()"
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "paused()"
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "isInitialized()"
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "getTotalAllocations()"
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "getRecipientsCount()"
# ========== ALLOCATION QUERIES ==========
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "getRecipient(uint256)" 0
cast call 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd "balanceOf(address)" <ADDRESS>
# ========== STORAGE READS ==========
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 0
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 1
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 4
cast storage 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd 6
# ========== TRANSACTION ANALYSIS ==========
cast tx 0x35544d934aa1ee5c05d572f1469c100b6b6546dc4c949671947ceca68a4d4d80 input
cast receipt 0x35544d934aa1ee5c05d572f1469c100b6b6546dc4c949671947ceca68a4d4d80
# ========== EVENT LOGS ==========
cast logs --from-block 24125223 --address 0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd
Related Artifacts
Owner Address Analysis
Address: 0xc013Bb5798d34997adbeE84f3f3aF42d29d72e76
Type: EOA (Externally Owned Account)
Activity Summary:
- 54 total transactions as of analysis date
- Active for ~14 days since first funding
- Deployed 2+ additional contracts beyond this allocation contract
- ETH Balance: 0.0675 ETH (~$214.68)
Contracts Deployed:
0x99fdbD43eDd7f4ABA1F745dB29705766946217Dd- This allocation contract0x9750a299859a897ae88c6712807e1caf93d4f9c4- Unknown purpose0x96c7c597d03f9288d531e9047ee72c4749e36000- Unknown purpose
Security Assessment: Single EOA control represents critical single point of failure (see Potential Risks document).
SENT Token Context
Contract: 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304
Max Supply: 3,836,691,376.405973996549318533 SENT
Holders: 1,190
Decimals: 18
Description: "A Living Decentralized AI Network" with no taxes/fees, deflationary burn mechanism, and permanently disabled minting.
Relationship to Allocation Contract: This allocation contract tracks intended distributions of SENT tokens but does not hold or transfer any SENT tokens itself. Allocations recorded here likely feed into a separate distribution mechanism.