// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
/// @title BasketToken — fully-backed, in-kind mint/redeem index token
/// @notice An ERC-20 backed 1:1 by fixed raw quantities of constituent ERC-20s
/// held by this contract. Mint deposits constituents in-kind; redeem
/// burns and returns constituents in-kind. No oracles, no rebalancing,
/// no upgradability, no admin control over funds.
/// @dev Works purely on raw ERC-20 amounts. Constituents implementing the
/// ERC-8056 Scaled UI Amount extension are supported by construction:
/// the UI multiplier is never read here (display concern only).
///
/// Trust guarantee: `redeem` is callable in every contract state. No
/// pause, cap, or guardian power can ever block it. The only way a
/// redeem can fail is if a constituent token itself reverts the
/// transfer (e.g. an issuer-level freeze) — a risk this contract
/// inherits and cannot remove.
contract BasketToken is ERC20, ReentrancyGuard {
using SafeERC20 for IERC20;
// ---------------------------------------------------------------- errors
error LengthMismatch();
error InvalidConstituentCount();
error DuplicateToken();
error ZeroAddress();
error NotAContract(address token);
error ZeroUnits();
error FeeTooHigh();
error ZeroSupplyCap();
error CapExceedsMax();
error ZeroAmount();
error MintingPaused();
error SupplyCapExceeded();
error InsufficientDeposit(address token);
error NotGuardian();
// ---------------------------------------------------------------- events
event Minted(address indexed sender, address indexed to, uint256 basketAmount, uint256 fee);
event Redeemed(address indexed sender, address indexed to, uint256 basketAmount);
event MintPausedSet(bool paused);
event SupplyCapSet(uint256 newCap);
event FeeRecipientSet(address indexed newRecipient);
// --------------------------------------------------------------- storage
uint256 private constant ONE = 1e18;
uint256 public constant MAX_FEE_BPS = 50;
uint256 public constant MIN_CONSTITUENTS = 2;
uint256 public constant MAX_CONSTITUENTS = 20;
/// @notice Guardian: may pause minting, adjust the supply cap (up to
/// `maxSupplyCap`) and move the fee recipient. Nothing else.
address public immutable guardian;
/// @notice Mint fee in basis points, fixed at deployment. Fee is taken in
/// basket tokens, so the backing invariant stays exact.
uint16 public immutable mintFeeBps;
/// @notice Immutable ceiling for `supplyCap`; the guardian can never raise
/// the cap above this.
uint256 public immutable maxSupplyCap;
address public feeRecipient;
uint256 public supplyCap;
bool public mintPaused;
address[] private _tokens;
uint256[] private _units; // raw constituent wei per 1e18 basket wei
// ----------------------------------------------------------- constructor
constructor(
string memory name_,
string memory symbol_,
address[] memory tokens_,
uint256[] memory unitsPerBasket_,
uint16 mintFeeBps_,
address feeRecipient_,
address guardian_,
uint256 maxSupplyCap_,
uint256 initialSupplyCap_
) ERC20(name_, symbol_) {
uint256 n = tokens_.length;
if (n != unitsPerBasket_.length) revert LengthMismatch();
if (n < MIN_CONSTITUENTS || n > MAX_CONSTITUENTS) revert InvalidConstituentCount();
if (mintFeeBps_ > MAX_FEE_BPS) revert FeeTooHigh();
if (feeRecipient_ == address(0) || guardian_ == address(0)) revert ZeroAddress();
if (maxSupplyCap_ == 0 || initialSupplyCap_ == 0) revert ZeroSupplyCap();
if (initialSupplyCap_ > maxSupplyCap_) revert CapExceedsMax();
for (uint256 i = 0; i < n; i++) {
address token = tokens_[i];
if (token == address(0)) revert ZeroAddress();
if (token.code.length == 0) revert NotAContract(token);
if (unitsPerBasket_[i] == 0) revert ZeroUnits();
for (uint256 j = 0; j < i; j++) {
if (tokens_[j] == token) revert DuplicateToken();
}
}
_tokens = tokens_;
_units = unitsPerBasket_;
mintFeeBps = mintFeeBps_;
feeRecipient = feeRecipient_;
guardian = guardian_;
maxSupplyCap = maxSupplyCap_;
supplyCap = initialSupplyCap_;
}
// ------------------------------------------------------------- modifiers
modifier onlyGuardian() {
if (msg.sender != guardian) revert NotGuardian();
_;
}
// ----------------------------------------------------------- mint/redeem
/// @notice Mint `basketAmount` basket tokens by depositing the required
/// raw amount of every constituent (see `getRequiredUnits`).
/// Caller must have approved this contract for each constituent.
/// @param basketAmount Gross amount minted; `to` receives it net of fee.
/// @param to Recipient of the minted basket tokens.
function mint(uint256 basketAmount, address to) external nonReentrant {
if (basketAmount == 0) revert ZeroAmount();
if (mintPaused) revert MintingPaused();
if (totalSupply() + basketAmount > supplyCap) revert SupplyCapExceeded();
uint256 n = _tokens.length;
for (uint256 i = 0; i < n; i++) {
IERC20 token = IERC20(_tokens[i]);
uint256 required = Math.mulDiv(basketAmount, _units[i], ONE, Math.Rounding.Ceil);
uint256 balanceBefore = token.balanceOf(address(this));
token.safeTransferFrom(msg.sender, address(this), required);
// Balance-delta check: guards against fee-on-transfer, deflationary
// or otherwise non-standard constituents under-delivering.
if (token.balanceOf(address(this)) - balanceBefore < required) {
revert InsufficientDeposit(address(token));
}
}
uint256 fee = (basketAmount * mintFeeBps) / 10_000;
_mint(to, basketAmount - fee);
if (fee > 0) _mint(feeRecipient, fee);
emit Minted(msg.sender, to, basketAmount, fee);
}
/// @notice Burn `basketAmount` basket tokens from the caller and transfer
/// the backing constituents (rounded down) to `to`.
/// @dev MUST be callable in every contract state: no pause, cap or
/// guardian power gates this function.
function redeem(uint256 basketAmount, address to) external nonReentrant {
if (basketAmount == 0) revert ZeroAmount();
if (to == address(0)) revert ZeroAddress();
_burn(msg.sender, basketAmount);
uint256 n = _tokens.length;
for (uint256 i = 0; i < n; i++) {
uint256 amount = Math.mulDiv(basketAmount, _units[i], ONE);
IERC20(_tokens[i]).safeTransfer(to, amount);
}
emit Redeemed(msg.sender, to, basketAmount);
}
// --------------------------------------------------------- guardian-only
/// @notice Pause or unpause minting. Never affects redeem.
function setMintPaused(bool paused) external onlyGuardian {
mintPaused = paused;
emit MintPausedSet(paused);
}
/// @notice Set the supply cap, up to the immutable `maxSupplyCap`.
function setSupplyCap(uint256 newCap) external onlyGuardian {
if (newCap > maxSupplyCap) revert CapExceedsMax();
supplyCap = newCap;
emit SupplyCapSet(newCap);
}
/// @notice Redirect future mint fees.
function setFeeRecipient(address newRecipient) external onlyGuardian {
if (newRecipient == address(0)) revert ZeroAddress();
feeRecipient = newRecipient;
emit FeeRecipientSet(newRecipient);
}
// ------------------------------------------------------------------ view
/// @notice Constituent token addresses.
function constituents() external view returns (address[] memory) {
return _tokens;
}
/// @notice Raw constituent wei per 1e18 basket wei, aligned with `constituents()`.
function units() external view returns (uint256[] memory) {
return _units;
}
/// @notice Exact raw deposits required to mint `basketAmount` (rounded up).
function getRequiredUnits(uint256 basketAmount)
external
view
returns (address[] memory tokens, uint256[] memory amounts)
{
tokens = _tokens;
amounts = new uint256[](tokens.length);
for (uint256 i = 0; i < tokens.length; i++) {
amounts[i] = Math.mulDiv(basketAmount, _units[i], ONE, Math.Rounding.Ceil);
}
}
/// @notice Raw constituent amounts returned when redeeming `basketAmount`
/// (rounded down).
function backingOf(uint256 basketAmount) external view returns (address[] memory tokens, uint256[] memory amounts) {
tokens = _tokens;
amounts = new uint256[](tokens.length);
for (uint256 i = 0; i < tokens.length; i++) {
amounts[i] = Math.mulDiv(basketAmount, _units[i], ONE);
}
}
/// @notice True when every constituent balance covers the total supply.
/// Should always hold; exposed for monitoring.
function isFullyBacked() external view returns (bool) {
uint256 supply = totalSupply();
uint256 n = _tokens.length;
for (uint256 i = 0; i < n; i++) {
uint256 required = Math.mulDiv(supply, _units[i], ONE, Math.Rounding.Ceil);
if (IERC20(_tokens[i]).balanceOf(address(this)) < required) return false;
}
return true;
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "name_",
"type": "string",
"internalType": "string"
},
{
"name": "symbol_",
"type": "string",
"internalType": "string"
},
{
"name": "tokens_",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "unitsPerBasket_",
"type": "uint256[]",
"internalType": "uint256[]"
},
{
"name": "mintFeeBps_",
"type": "uint16",
"internalType": "uint16"
},
{
"name": "feeRecipient_",
"type": "address",
"internalType": "address"
},
{
"name": "guardian_",
"type": "address",
"internalType": "address"
},
{
"name": "maxSupplyCap_",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "initialSupplyCap_",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "nonpayable"
},
{
"name": "CapExceedsMax",
"type": "error",
"inputs": []
},
{
"name": "DuplicateToken",
"type": "error",
"inputs": []
},
{
"name": "ERC20InsufficientAllowance",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "allowance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InsufficientBalance",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
},
{
"name": "balance",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "needed",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "ERC20InvalidApprover",
"type": "error",
"inputs": [
{
"name": "approver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidReceiver",
"type": "error",
"inputs": [
{
"name": "receiver",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSender",
"type": "error",
"inputs": [
{
"name": "sender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "ERC20InvalidSpender",
"type": "error",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "FeeTooHigh",
"type": "error",
"inputs": []
},
{
"name": "InsufficientDeposit",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "InvalidConstituentCount",
"type": "error",
"inputs": []
},
{
"name": "LengthMismatch",
"type": "error",
"inputs": []
},
{
"name": "MintingPaused",
"type": "error",
"inputs": []
},
{
"name": "NotAContract",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "NotGuardian",
"type": "error",
"inputs": []
},
{
"name": "ReentrancyGuardReentrantCall",
"type": "error",
"inputs": []
},
{
"name": "SafeERC20FailedOperation",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "SupplyCapExceeded",
"type": "error",
"inputs": []
},
{
"name": "ZeroAddress",
"type": "error",
"inputs": []
},
{
"name": "ZeroAmount",
"type": "error",
"inputs": []
},
{
"name": "ZeroSupplyCap",
"type": "error",
"inputs": []
},
{
"name": "ZeroUnits",
"type": "error",
"inputs": []
},
{
"name": "Approval",
"type": "event",
"inputs": [
{
"name": "owner",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "FeeRecipientSet",
"type": "event",
"inputs": [
{
"name": "newRecipient",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "MintPausedSet",
"type": "event",
"inputs": [
{
"name": "paused",
"type": "bool",
"indexed": false,
"internalType": "bool"
}
],
"anonymous": false
},
{
"name": "Minted",
"type": "event",
"inputs": [
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
},
{
"name": "fee",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Redeemed",
"type": "event",
"inputs": [
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "basketAmount",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "SupplyCapSet",
"type": "event",
"inputs": [
{
"name": "newCap",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "Transfer",
"type": "event",
"inputs": [
{
"name": "from",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "to",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"indexed": false,
"internalType": "uint256"
}
],
"anonymous": false
},
{
"name": "MAX_CONSTITUENTS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MAX_FEE_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "MIN_CONSTITUENTS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "allowance",
"type": "function",
"inputs": [
{
"name": "owner",
"type": "address",
"internalType": "address"
},
{
"name": "spender",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "approve",
"type": "function",
"inputs": [
{
"name": "spender",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "backingOf",
"type": "function",
"inputs": [
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokens",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "amounts",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "view"
},
{
"name": "balanceOf",
"type": "function",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "constituents",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address[]",
"internalType": "address[]"
}
],
"stateMutability": "view"
},
{
"name": "decimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "feeRecipient",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "getRequiredUnits",
"type": "function",
"inputs": [
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "tokens",
"type": "address[]",
"internalType": "address[]"
},
{
"name": "amounts",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "view"
},
{
"name": "guardian",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "isFullyBacked",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "maxSupplyCap",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "mint",
"type": "function",
"inputs": [
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "mintFeeBps",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint16",
"internalType": "uint16"
}
],
"stateMutability": "view"
},
{
"name": "mintPaused",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "name",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "redeem",
"type": "function",
"inputs": [
{
"name": "basketAmount",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "to",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setFeeRecipient",
"type": "function",
"inputs": [
{
"name": "newRecipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setMintPaused",
"type": "function",
"inputs": [
{
"name": "paused",
"type": "bool",
"internalType": "bool"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "setSupplyCap",
"type": "function",
"inputs": [
{
"name": "newCap",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "supplyCap",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "symbol",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "string",
"internalType": "string"
}
],
"stateMutability": "view"
},
{
"name": "totalSupply",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "transfer",
"type": "function",
"inputs": [
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "transferFrom",
"type": "function",
"inputs": [
{
"name": "from",
"type": "address",
"internalType": "address"
},
{
"name": "to",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "nonpayable"
},
{
"name": "units",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256[]",
"internalType": "uint256[]"
}
],
"stateMutability": "view"
}
]0x608060409080825260049081361015610016575f80fd5b5f3560e01c90816306fdde031461125757508063095ea7b31461116f57806318160ddd1461115157806323b872dd14610fe8578063313ce56714610fcd578063452a932014610f7d5780634690484014610f4957806369fe17d614610f245780636ebad4eb14610ef457806370a0823114610eb15780637bde82f214610c1b5780637e4831d314610bf85780638f770ad014610bda57806394bf804d146107ff57806395d89b41146106c9578063976a84351461063f57806397c8bcc1146106015780639d70902f146105c7578063a9059cbb14610597578063b6935501146104e1578063b6a3f59a146103e9578063bd7b76d214610371578063beb6421e14610356578063c72191e11461033b578063d55be8c614610320578063dd62ed3e146102c9578063e74b981b146101c95763ffbe484214610154575f80fd5b346101c55760206003193601126101c557359061016f6116cf565b9161017a83516117b2565b925f5b81518110156101b357806101a261019560019361153d565b90549060031b1c856119ac565b6101ac8288611801565b520161017d565b8351806101c18785836114a7565b0390f35b5f80fd5b50346101c55760206003193601126101c5576101e36113e5565b73ffffffffffffffffffffffffffffffffffffffff90817f000000000000000000000000c93b74b490d1bdd71045766c90f1f743d0c356be1633036102a1571691821561027b5782807fffffffffffffffffffffffff000000000000000000000000000000000000000060055416176005557fbf9a9534339a9d6b81696e05dcfb614b7dc518a31d48be3cfb757988381fb3235f80a2005b517fd92e233d000000000000000000000000000000000000000000000000000000008152fd5b8284517fef6d0f02000000000000000000000000000000000000000000000000000000008152fd5b82346101c557806003193601126101c5576020906102e56113e5565b6102ed611408565b9073ffffffffffffffffffffffffffffffffffffffff8091165f5260018452825f2091165f528252805f20549051908152f35b82346101c5575f6003193601126101c5576020905160328152f35b82346101c5575f6003193601126101c5576020905160148152f35b82346101c5575f6003193601126101c5576020905160028152f35b50346101c55760206003193601126101c557359061038d6116cf565b9161039883516117b2565b925f5b81518110156101b357806103d86103b360019361153d565b90549060031b1c670de0b6b3a76400006103cd82886119ac565b918709151590611753565b6103e28288611801565b520161039b565b5090346101c55760206003193601126101c55781359173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c93b74b490d1bdd71045766c90f1f743d0c356be1633036104ba577f00000000000000000000000000000000000000000000d3c21bcecceda10000008311610493577fbc585eed6f54aa16ec292be93276937803d5a047ba4eded0c87779270bbfdfe6602084848160065551908152a1005b90517fe53e5918000000000000000000000000000000000000000000000000000000008152fd5b90517fef6d0f02000000000000000000000000000000000000000000000000000000008152fd5b5090346101c55760206003193601126101c5578135918215158093036101c55773ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c93b74b490d1bdd71045766c90f1f743d0c356be1633036104ba577f0fb79081612032f5ce63340f421121d9f8b8ea04158f08b2dfafacb3393caf98602084847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006007541660ff83161760075551908152a1005b82346101c557806003193601126101c5576020906105c06105b66113e5565b6024359033611815565b5160018152f35b82346101c5575f6003193601126101c557602090517f00000000000000000000000000000000000000000000d3c21bcecceda10000008152f35b82346101c5575f6003193601126101c5576020905161ffff7f000000000000000000000000000000000000000000000000000000000000000a168152f35b82346101c5575f6003193601126101c5578051600980548083525f918252602080840194927f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af92915b8282106106b2576101c186866106a0828b03836114cf565b51918291602083526020830190611474565b835487529586019560019384019390910190610688565b5090346101c5575f6003193601126101c5578051905f9280549060018260011c91600184169384156107f5575b60209485851081146107c9578488529081156107895750600114610730575b6101c18686610726828b03836114cf565b5191829182611381565b5f9081529295507f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b5b82841061077657505050826101c19461072692820101945f610715565b8054868501880152928601928101610759565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001687860152505050151560051b8301019250610726826101c15f610715565b6022837f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b92607f16926106f6565b50346101c557816003193601126101c55780359061081b611408565b90610824611952565b8215610bb35760ff60075416610b8c5761084083600254611753565b60065410610b65576008545f5b81811061095257505061ffff7f000000000000000000000000000000000000000000000000000000000000000a1690818402918483040361092657507f03f17d66ad3bf18e9412eb06582908831508cdb9b8da9cddb1431f645a5b86329161271073ffffffffffffffffffffffffffffffffffffffff92046108d86108d2828761178d565b83611a50565b80610913575b8551948552602085015216923392a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055005b610921818460055416611a50565b6108de565b6011907f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b73ffffffffffffffffffffffffffffffffffffffff6109aa6109738361159f565b929054600393841b1c16916109878461153d565b9054911b1c670de0b6b3a764000061099f828a6119ac565b918909151590611753565b87517f70a082310000000000000000000000000000000000000000000000000000000080825230878301526024939291602080828781885afa918215610add575f92610b36575b508b517f23b872dd000000000000000000000000000000000000000000000000000000005f52338a52308752846044528c81835f606481808c5af1916001805f5114841615610b13575b50525f60605215610ae757508b51928352308984015280838781885afa908115610add575f91610aad575b50610a71925061178d565b10610a8057505060010161084d565b84908851917f51267e37000000000000000000000000000000000000000000000000000000008352820152fd5b905082813d8311610ad6575b610ac381836114cf565b810103126101c557610a7191515f610a66565b503d610ab9565b8c513d5f823e3d90fd5b80868b7f5274afe7000000000000000000000000000000000000000000000000000000008a9452820152fd5b915050811516610b2d573d15873b15151616818e5f610a3b565b503d5f823e3d90fd5b9080925081813d8311610b5e575b610b4e81836114cf565b810103126101c55751905f6109f1565b503d610b44565b83517ff58f733a000000000000000000000000000000000000000000000000000000008152fd5b83517feb560756000000000000000000000000000000000000000000000000000000008152fd5b83517f1f2a2005000000000000000000000000000000000000000000000000000000008152fd5b82346101c5575f6003193601126101c5576020906006549051908152f35b82346101c5575f6003193601126101c55760209060ff6007541690519015158152f35b5090346101c557806003193601126101c557813590610c38611408565b610c40611952565b8215610e895773ffffffffffffffffffffffffffffffffffffffff809116938415610e62573315610e3357335f526020905f602052835f2054858110610dee578590335f525f60205203845f205584600254036002555f84518681527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60203392a3600854925f5b848110610d2257878787519081527f27d4634c833b7622a0acddbf7f746183625f105945e95c723ad1d5a9f2a0b6fc60203392a360017f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0055005b610d3e82610d2f8361153d565b929054600393841b1c8a6119ac565b91610d488461159f565b9054911b1c168751907fa9059cbb000000000000000000000000000000000000000000000000000000005f528a86526024928352865f60448180855af16001805f5114821615610dd0575b50828a5215610da757505050600101610cc8565b857f5274afe7000000000000000000000000000000000000000000000000000000008352820152fd5b811516610de557813b15153d1516165f610d93565b823d5f823e3d90fd5b84517fe450d38c000000000000000000000000000000000000000000000000000000008152339281019283526020830191909152604082018690529081906060010390fd5b6024905f8451917f96c6fd1e000000000000000000000000000000000000000000000000000000008352820152fd5b82517fd92e233d000000000000000000000000000000000000000000000000000000008152fd5b8382517f1f2a2005000000000000000000000000000000000000000000000000000000008152fd5b82346101c55760206003193601126101c55760209073ffffffffffffffffffffffffffffffffffffffff610ee36113e5565b165f525f8252805f20549051908152f35b82346101c5575f6003193601126101c5576101c190610f116116cf565b905191829160208352602083019061142b565b82346101c5575f6003193601126101c557602090610f406115d4565b90519015158152f35b82346101c5575f6003193601126101c55760209073ffffffffffffffffffffffffffffffffffffffff600554169051908152f35b82346101c5575f6003193601126101c5576020905173ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000c93b74b490d1bdd71045766c90f1f743d0c356be168152f35b82346101c5575f6003193601126101c5576020905160128152f35b50346101c55760606003193601126101c5576110026113e5565b61100a611408565b906044359273ffffffffffffffffffffffffffffffffffffffff8216805f526001602052855f20335f52602052855f2054917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8310611072575b6020876105c0888888611815565b85831061110c5781156110dd5733156110ae57505f908152600160209081528682203383528152908690209185900390915582906105c0611064565b6024905f8851917f94280d62000000000000000000000000000000000000000000000000000000008352820152fd5b6024905f8851917fe602df05000000000000000000000000000000000000000000000000000000008352820152fd5b86517ffb8f41b2000000000000000000000000000000000000000000000000000000008152339181019182526020820193909352604081018690528291506060010390fd5b82346101c5575f6003193601126101c5576020906002549051908152f35b5090346101c557806003193601126101c5576111896113e5565b6024359033156112285773ffffffffffffffffffffffffffffffffffffffff169081156111f95760209350335f5260018452825f20825f52845280835f205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b6024845f8551917f94280d62000000000000000000000000000000000000000000000000000000008352820152fd5b6024845f8551917fe602df05000000000000000000000000000000000000000000000000000000008352820152fd5b905082346101c5575f6003193601126101c5575f9260035460018160011c91600181168015611377575b602094858510821461134b575083875290811561130d57506001146112b3575b505050610726826101c19403836114cf565b60035f9081529295507fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b5b8284106112fa57505050826101c19461072692820101946112a1565b80548685018801529286019281016112de565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016868501525050151560051b8301019250610726826101c16112a1565b6022907f4e487b71000000000000000000000000000000000000000000000000000000005f525260245ffd5b92607f1692611281565b6020808252825181830181905293925f5b8581106113d1575050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f845f6040809697860101520116010190565b818101830151848201604001528201611392565b6004359073ffffffffffffffffffffffffffffffffffffffff821682036101c557565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036101c557565b9081518082526020808093019301915f5b82811061144a575050505090565b835173ffffffffffffffffffffffffffffffffffffffff168552938101939281019260010161143c565b9081518082526020808093019301915f5b828110611493575050505090565b835185529381019392810192600101611485565b90916114be6114cc9360408452604084019061142b565b916020818403910152611474565b90565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761151057604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6009548110156115725760095f527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af01905f90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b6008548110156115725760085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee301905f90565b600254600854905f5b8281106115ec57505050600190565b61162973ffffffffffffffffffffffffffffffffffffffff61160d8361153d565b929054600393841b1c670de0b6b3a76400006103cd82886119ac565b916116338461159f565b9054911b1c16604090815180917f70a0823100000000000000000000000000000000000000000000000000000000825230600483015281602460209384935afa9283156116c657505f92611698575b505010611691576001016115dd565b5050505f90565b90809250813d83116116bf575b6116af81836114cf565b810103126101c557515f80611682565b503d6116a5565b513d5f823e3d90fd5b6040519060085480835282602091602082019060085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3935f905b82821061172357505050611721925003836114cf565b565b855473ffffffffffffffffffffffffffffffffffffffff168452600195860195889550938101939091019061170b565b9190820180921161176057565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9190820391821161176057565b67ffffffffffffffff81116115105760051b60200190565b906117bc8261179a565b6117c960405191826114cf565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06117f7829461179a565b0190602036910137565b80518210156115725760209160051b010190565b9173ffffffffffffffffffffffffffffffffffffffff80841692831561192257169283156118f257825f525f60205260405f20549082821061189a5750817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f5260405f20818154019055604051908152a3565b6040517fe450d38c00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff919091166004820152602481019190915260448101829052606490fd5b60246040517fec442f050000000000000000000000000000000000000000000000000000000081525f6004820152fd5b60246040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081525f6004820152fd5b7f9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f0060028154146119825760029055565b60046040517f3ee5aeb5000000000000000000000000000000000000000000000000000000008152fd5b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81830981830291828083109203918083039214611a3f57670de0b6b3a76400009082821115611a2d577faccb18165bd6fe31ae1cf318dc5b51eee0e1ba569b88cd74c1773b91fac10669940990828211900360ee1b910360121c170290565b634e487b715f5260116020526024601cfd5b5050670de0b6b3a764000091500490565b73ffffffffffffffffffffffffffffffffffffffff169081156118f2577fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef602082611a9e5f94600254611753565b60025584845283825260408420818154019055604051908152a356fea2646970667358221220271907f5c519b265948f06a8b0331b4dc190d6d84f0cbeec933b786eeca6cf8464736f6c63430008180033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
Amazon • Robinhood Token (AMZN) | AMZN | 0.980629 | — | — |
Alphabet Class A • Robinhood Token (GOOGL) | GOOGL | 0.670625 | — | — |
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| No direct transactions — this address is only ever reached via internal calls (common for a contract only invoked through a router or proxy). View Internal Transactions → | |||||||||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0x56a84c…135848 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x03f17d…8632 | [0] 0x000000000000…f3abc776 [1] 0x000000000000…a62d0437 data: 0x000000000000000000…37e08000 |
| 0x56a84c…135848 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…f4e9685f data: 0x000000000000000000…37e08000 |
| 0x56a84c…135848 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | Transfer | [0] 0x000000000000…00000000 [1] 0x000000000000…a62d0437 data: 0x000000000000000000…0d138000 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 11,289,011 | 32 days agoThu, 16 Jul 2026 13:21:48 UTC | 0x63a18f…01a9b1 | CREATE | createBasket | 0x51db…f988 | IN | 0xa8f2…c73e | 0 ETH |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | IN | 0xa8f2…c73e | 0.670625 GOOGL | Alphabet Class A • Robinhood Token (GOOGL) | |
| 0x56a84c24…135848 | Transfer | 11,435,504 | 32 days agoThu, 16 Jul 2026 17:25:51 UTC | 0x7ce8…c776 | IN | 0xa8f2…c73e | 0.980629 AMZN | Amazon • Robinhood Token (AMZN) |