Storage Layout
DISCLAIMER // NFA // DYOR
This analysis is based on decompiled bytecode and 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, but 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 | 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 (etherscan) |
| Network | Ethereum Mainnet |
| Analysis Date | 2025-12-26 |
Variables
| SLOT | VARIABLE NAME | TYPE | CURRENT VALUE | PURPOSE |
|---|---|---|---|---|
| 0 | _owner | address | 0x9c146431E3b7300FAaABC625Eeee3c7ec882A0DC |
Contract owner |
| 1 | _balances | mapping(address => uint256) | - | Token balances |
| 2 | _allowances | mapping(address => mapping(address => uint256)) | - | Spending allowances |
| 3 | _totalSupply | uint256 | 3,911,241,716 * 10^18 | Current circulating supply |
| 4 | _name | string | "Sentinel" | Token name |
| 5 | _symbol | string | "SENT" | Token symbol |
| 6 | TOTAL_SUPPLY | uint256 | 3,911,241,716 * 10^18 | Original total supply |
| 7 | presaleWallet | address | 0xEa35cde1d1ac4e36Ca519dB0b38Fe28A2C477eFE |
Presale allocation recipient |
| 8 | presaleAllocation | uint256 | 3,492,180,104 * 10^18 | Amount allocated to presale |
| 9 | _isInitialized | bool | true | Minting initialization flag |
Storage Diagram
graph TB
subgraph Core["Ownable - Slot 0"]
S0["Slot 0: _owner<br/>0x9c146431E3b7300FA..."]
end
subgraph ERC20["ERC-20 State - Slots 1-5"]
S1["Slot 1: _balances<br/>(mapping)"]
S2["Slot 2: _allowances<br/>(nested mapping)"]
S3["Slot 3: _totalSupply<br/>3,911,241,716 SENT"]
S4["Slot 4: _name<br/>'Sentinel'"]
S5["Slot 5: _symbol<br/>'SENT'"]
end
subgraph Custom["Custom State - Slots 6-9"]
S6["Slot 6: TOTAL_SUPPLY<br/>3,911,241,716 SENT"]
S7["Slot 7: presaleWallet<br/>0xEa35cde1d1ac4e36..."]
S8["Slot 8: presaleAllocation<br/>3,492,180,104 SENT"]
S9["Slot 9: _isInitialized<br/>true"]
end
Core --> ERC20 --> Custom
style S0 fill:#ffe1e1
style S3 fill:#fff4e1
style S6 fill:#fff4e1
style S7 fill:#e1ffe1
style S8 fill:#e1ffe1
style S9 fill:#e1f5ff
Raw Storage Values
The following raw storage values were queried directly from the blockchain:
Slot 0: 0x0000000000000000000000009c146431e3b7300faaabc625eeee3c7ec882a0dc
↳ _owner: 0x9c146431E3b7300FAaABC625Eeee3c7ec882A0DC
Slot 3: 0x00000000000000000000000000000000000000000ca34da647b8581567500000
↳ _totalSupply: 3,911,241,716,000,000,000,000,000,000 (3.91B tokens)
Slot 4: 0x53656e74696e656c000000000000000000000000000000000000000000000010
↳ _name: "Sentinel" (8 characters, stored inline)
Slot 5: 0x53454e5400000000000000000000000000000000000000000000000000000008
↳ _symbol: "SENT" (4 characters, stored inline)
Slot 6: 0x00000000000000000000000000000000000000000ca34da647b8581567500000
↳ TOTAL_SUPPLY: 3,911,241,716,000,000,000,000,000,000
Slot 7: 0x000000000000000000000000ea35cde1d1ac4e36ca519db0b38fe28a2c477efe
↳ presaleWallet: 0xEa35cde1d1ac4e36Ca519dB0b38Fe28A2C477eFE
Slot 8: 0x00000000000000000000000000000000000000000b48a9e6c5fbc184ad200000
↳ presaleAllocation: 3,492,180,104,000,000,000,000,000,000 (3.49B tokens)
Mapping Storage
_balances (Slot 1)
The _balances mapping stores token balances. For a given address, the balance is stored at:
Query Example:
# GET BALANCE STORAGE SLOT FOR AN ADDRESS
# Calculate storage slot for presale wallet balance
cast index address 0xEa35cde1d1ac4e36Ca519dB0b38Fe28A2C477eFE 1
_allowances (Slot 2)
The _allowances nested mapping stores spending approvals. For owner → spender, the allowance is stored at:
Variable Analysis
Critical State Variables
| VARIABLE | MUTABILITY | RISK LEVEL | NOTES |
|---|---|---|---|
| _owner | Mutable | △ Medium | Can be changed via transferOwnership |
| _totalSupply | Mutable | Low | Only decreases via burn |
| TOTAL_SUPPLY | Immutable-like | Low | Set once at initialization |
| presaleWallet | Immutable-like | Low | Set once at initialization |
| presaleAllocation | Immutable-like | Low | Set once at initialization |
| _isInitialized | Immutable-like | Low | Set to true once, never false |
Storage Slot Access Patterns
| SLOT | READABLE | WRITABLE BY |
|---|---|---|
| 0 (_owner) | Anyone | Owner only |
| 1 (_balances) | Anyone | Internal functions (transfer, mint, burn) |
| 2 (_allowances) | Anyone | Internal functions (approve) |
| 3 (_totalSupply) | Anyone | Internal functions (mint, burn) |
| 4 (_name) | Anyone | Never (set in constructor) |
| 5 (_symbol) | Anyone | Never (set in constructor) |
| 6 (TOTAL_SUPPLY) | Anyone | Owner once (initializeMinting) |
| 7 (presaleWallet) | Anyone | Owner once (initializeMinting) |
| 8 (presaleAllocation) | Anyone | Owner once (initializeMinting) |
| 9 (_isInitialized) | Anyone | Owner once (initializeMinting) |
Verification Commands
The following commands can be used to verify storage values:
Tip
Commands below use cast from the Foundry Toolkit. To run the commands below, you must set the RPC URL environment variable:
Read Storage Slots
# READ OWNER (SLOT 0)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 0
# READ TOTAL SUPPLY (SLOT 3)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 3
# READ NAME (SLOT 4)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 4
# READ SYMBOL (SLOT 5)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 5
# READ TOTAL_SUPPLY CONSTANT (SLOT 6)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 6
# READ PRESALE WALLET (SLOT 7)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 7
# READ PRESALE ALLOCATION (SLOT 8)
cast storage 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 8
Read Via Function Calls
# READ OWNER VIA FUNCTION
cast call 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 "owner()(address)"
# READ TOTAL SUPPLY VIA FUNCTION
cast call 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 "totalSupply()(uint256)"
# READ BALANCE OF AN ADDRESS
cast call 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 "balanceOf(address)(uint256)" <ADDRESS>
# CHECK IF INITIALIZED
cast call 0xe88BAab9192a3Cb2C0a50182AB911506e5aDc304 "isInitialized()(bool)"