// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {Math} from "@openzeppelin/contracts/utils/math/Math.sol";
import {IChainlinkAggregatorV3} from "../interfaces/IChainlinkAggregatorV3.sol";
import {IStockPriceGuard} from "../interfaces/IStockPriceGuard.sol";
import {IStockTokenOracleState} from "../interfaces/IStockTokenOracleState.sol";
contract ChainlinkStockPriceGuard is IStockPriceGuard, AccessControl {
uint256 public constant BPS = 10_000;
uint256 public constant MAX_DEVIATION_BPS = 500;
uint256 public constant ORACLE_MINIMUM_BPS = 9_500;
uint256 private constant MAX_POWER_OF_TEN = 77;
struct TokenConfig {
address feed;
uint48 heartbeat;
uint8 feedDecimals;
uint8 tokenDecimals;
bool configured;
}
error InvalidAddress();
error InvalidHeartbeat();
error InvalidDecimals();
error InvalidAmount();
error UnsupportedPaymentToken();
error TokenNotConfigured(address token);
error InvalidPrice();
error StalePrice();
error StockOraclePaused(address token);
error SequencerDown();
error SequencerGracePeriod();
error QuoteOutsideDeviation(uint256 quotedAmountOut, uint256 minimumAmountOut, uint256 maximumAmountOut);
address public immutable paymentToken;
uint8 public immutable paymentDecimals;
/// @notice Optional Chainlink L2 uptime proxy. The zero address disables
/// only this check; stock-feed freshness and deviation checks stay active.
address public immutable sequencerUptimeFeed;
uint48 public immutable sequencerGracePeriod;
mapping(address token => TokenConfig config) private _tokenConfig;
event TokenConfigured(
address indexed token, address indexed feed, uint48 heartbeat, uint8 feedDecimals, uint8 tokenDecimals
);
constructor(address paymentToken_, address sequencerUptimeFeed_, uint48 sequencerGracePeriod_, address admin) {
if (paymentToken_ == address(0) || admin == address(0)) {
revert InvalidAddress();
}
if (sequencerUptimeFeed_ != address(0) && sequencerGracePeriod_ == 0) revert InvalidAmount();
uint8 paymentDecimals_ = IERC20Metadata(paymentToken_).decimals();
if (paymentDecimals_ > MAX_POWER_OF_TEN) revert InvalidDecimals();
paymentToken = paymentToken_;
paymentDecimals = paymentDecimals_;
sequencerUptimeFeed = sequencerUptimeFeed_;
sequencerGracePeriod = sequencerGracePeriod_;
_grantRole(DEFAULT_ADMIN_ROLE, admin);
}
function configureToken(address token, address feed, uint48 heartbeat) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (token == address(0) || feed == address(0)) revert InvalidAddress();
if (heartbeat == 0) revert InvalidHeartbeat();
uint8 feedDecimals = IChainlinkAggregatorV3(feed).decimals();
uint8 tokenDecimals = IStockTokenOracleState(token).decimals();
if (uint256(feedDecimals) + uint256(tokenDecimals) > MAX_POWER_OF_TEN) revert InvalidDecimals();
_tokenConfig[token] = TokenConfig({
feed: feed, heartbeat: heartbeat, feedDecimals: feedDecimals, tokenDecimals: tokenDecimals, configured: true
});
emit TokenConfigured(token, feed, heartbeat, feedDecimals, tokenDecimals);
}
function tokenConfig(address token)
external
view
returns (address feed, uint48 heartbeat, uint8 feedDecimals, uint8 tokenDecimals, bool configured)
{
TokenConfig memory config = _tokenConfig[token];
return (config.feed, config.heartbeat, config.feedDecimals, config.tokenDecimals, config.configured);
}
function validateQuote(address inputToken, address outputToken, uint256 amountIn, uint256 quotedAmountOut)
external
view
returns (uint256 oracleMinimumOut)
{
if (inputToken != paymentToken) revert UnsupportedPaymentToken();
if (amountIn == 0 || quotedAmountOut == 0) revert InvalidAmount();
TokenConfig memory config = _tokenConfig[outputToken];
if (!config.configured) revert TokenNotConfigured(outputToken);
_validateSequencer();
if (IStockTokenOracleState(outputToken).oraclePaused()) revert StockOraclePaused(outputToken);
(, int256 answer,, uint256 updatedAt,) = IChainlinkAggregatorV3(config.feed).latestRoundData();
if (answer <= 0) revert InvalidPrice();
if (updatedAt == 0 || updatedAt > block.timestamp || block.timestamp - updatedAt > config.heartbeat) {
revert StalePrice();
}
uint256 numeratorScale = 10 ** (uint256(config.feedDecimals) + uint256(config.tokenDecimals));
uint256 denominatorScale = 10 ** uint256(paymentDecimals);
uint256 expectedOut = Math.mulDiv(amountIn, numeratorScale, denominatorScale * uint256(answer));
if (expectedOut == 0) revert InvalidAmount();
uint256 minimumOut = Math.mulDiv(expectedOut, BPS - MAX_DEVIATION_BPS, BPS);
uint256 maximumOut = Math.mulDiv(expectedOut, BPS + MAX_DEVIATION_BPS, BPS);
if (quotedAmountOut < minimumOut || quotedAmountOut > maximumOut) {
revert QuoteOutsideDeviation(quotedAmountOut, minimumOut, maximumOut);
}
return Math.mulDiv(expectedOut, ORACLE_MINIMUM_BPS, BPS);
}
function _validateSequencer() private view {
if (sequencerUptimeFeed == address(0)) return;
(, int256 answer, uint256 startedAt,,) = IChainlinkAggregatorV3(sequencerUptimeFeed).latestRoundData();
if (answer != 0) revert SequencerDown();
if (startedAt == 0 || startedAt > block.timestamp || block.timestamp - startedAt <= sequencerGracePeriod) {
revert SequencerGracePeriod();
}
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "paymentToken_",
"type": "address",
"internalType": "address"
},
{
"name": "sequencerUptimeFeed_",
"type": "address",
"internalType": "address"
},
{
"name": "sequencerGracePeriod_",
"type": "uint48",
"internalType": "uint48"
},
{
"name": "admin",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "AccessControlBadConfirmation",
"type": "error",
"inputs": []
},
{
"name": "AccessControlUnauthorizedAccount",
"type": "error",
"inputs": [
{
"name": "account",
"type": "address",
"internalType": "address"
},
{
"name": "neededRole",
"type": "bytes32",
"internalType": "bytes32"
}
]
},
{
"name": "InvalidAddress",
"type": "error",
"inputs": []
},
{
"name": "InvalidAmount",
"type": "error",
"inputs": []
},
{
"name": "InvalidDecimals",
"type": "error",
"inputs": []
},
{
"name": "InvalidHeartbeat",
"type": "error",
"inputs": []
},
{
"name": "InvalidPrice",
"type": "error",
"inputs": []
},
{
"name": "QuoteOutsideDeviation",
"type": "error",
"inputs": [
{
"name": "quotedAmountOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "minimumAmountOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "maximumAmountOut",
"type": "uint256",
"internalType": "uint256"
}
]
},
{
"name": "SequencerDown",
"type": "error",
"inputs": []
},
{
"name": "SequencerGracePeriod",
"type": "error",
"inputs": []
},
{
"name": "StalePrice",
"type": "error",
"inputs": []
},
{
"name": "StockOraclePaused",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "TokenNotConfigured",
"type": "error",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
]
},
{
"name": "UnsupportedPaymentToken",
"type": "error",
"inputs": []
},
{
"name": "RoleAdminChanged",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "previousAdminRole",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "newAdminRole",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
}
],
"anonymous": false
},
{
"name": "RoleGranted",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "RoleRevoked",
"type": "event",
"inputs": [
{
"name": "role",
"type": "bytes32",
"indexed": true,
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "sender",
"type": "address",
"indexed": true,
"internalType": "address"
}
],
"anonymous": false
},
{
"name": "TokenConfigured",
"type": "event",
"inputs": [
{
"name": "token",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "feed",
"type": "address",
"indexed": true,
"internalType": "address"
},
{
"name": "heartbeat",
"type": "uint48",
"indexed": false,
"internalType": "uint48"
},
{
"name": "feedDecimals",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
},
{
"name": "tokenDecimals",
"type": "uint8",
"indexed": false,
"internalType": "uint8"
}
],
"anonymous": false
},
{
"name": "BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "DEFAULT_ADMIN_ROLE",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "MAX_DEVIATION_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "ORACLE_MINIMUM_BPS",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
},
{
"name": "configureToken",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "feed",
"type": "address",
"internalType": "address"
},
{
"name": "heartbeat",
"type": "uint48",
"internalType": "uint48"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "getRoleAdmin",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [
{
"name": "",
"type": "bytes32",
"internalType": "bytes32"
}
],
"stateMutability": "view"
},
{
"name": "grantRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "hasRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "paymentDecimals",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint8",
"internalType": "uint8"
}
],
"stateMutability": "view"
},
{
"name": "paymentToken",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "renounceRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "callerConfirmation",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "revokeRole",
"type": "function",
"inputs": [
{
"name": "role",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "account",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "sequencerGracePeriod",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "uint48",
"internalType": "uint48"
}
],
"stateMutability": "view"
},
{
"name": "sequencerUptimeFeed",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "supportsInterface",
"type": "function",
"inputs": [
{
"name": "interfaceId",
"type": "bytes4",
"internalType": "bytes4"
}
],
"outputs": [
{
"name": "",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "tokenConfig",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
}
],
"outputs": [
{
"name": "feed",
"type": "address",
"internalType": "address"
},
{
"name": "heartbeat",
"type": "uint48",
"internalType": "uint48"
},
{
"name": "feedDecimals",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "tokenDecimals",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "configured",
"type": "bool",
"internalType": "bool"
}
],
"stateMutability": "view"
},
{
"name": "validateQuote",
"type": "function",
"inputs": [
{
"name": "inputToken",
"type": "address",
"internalType": "address"
},
{
"name": "outputToken",
"type": "address",
"internalType": "address"
},
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "quotedAmountOut",
"type": "uint256",
"internalType": "uint256"
}
],
"outputs": [
{
"name": "oracleMinimumOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "view"
}
]0x610100806040523461016e5760808161120b803803809161002082856101bd565b83398101031261016e57610033816101f4565b90610040602082016101f4565b60408201519065ffffffffffff82169283830361016e57606061006391016101f4565b926001600160a01b03851690811580156101ac575b61019d576001600160a01b03831615159081610194575b506101855760206004916040519283809263313ce56760e01b82525afa90811561017a575f9161013a575b50604d60ff82161161012b576100db9460805260a05260c05260e052610208565b50604051610f59908161029282396080518181816102d601526108bb015260a05181818161027e015261042b015260c0518181816101d40152610c87015260e0518181816109610152610d1d0152f35b630692acc560e51b5f5260045ffd5b90506020813d602011610172575b81610155602093836101bd565b8101031261016e575160ff8116810361016e575f6100ba565b5f80fd5b3d9150610148565b6040513d5f823e3d90fd5b63162908e360e11b5f5260045ffd5b9050155f61008f565b63e6c4247b60e01b5f5260045ffd5b506001600160a01b03851615610078565b601f909101601f19168101906001600160401b038211908210176101e057604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361016e57565b6001600160a01b0381165f9081525f805160206111eb833981519152602052604090205460ff1661028c576001600160a01b03165f8181525f805160206111eb83398151915260205260408120805460ff191660011790553391907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d8180a4600190565b505f9056fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a7146109e757508063248a9ca3146109bd578063249d39e9146109a157806325c684031461098557806326a97b9414610943578063290424cd146109275780632f2ff15d146108ea5780633013ce29146108a657806336568abe1461086257806336bc435b146105e857806368ea8ce9146102a25780638018b5ae1461026557806391d148541461021d578063a217fddf14610203578063a7264705146101bf578063d547741f1461017b5763fe136c4e146100d7575f80fd5b34610177576020366003190112610177576001600160a01b036100f8610a50565b165f52600160205260a060405f2060806040519161011583610a66565b54600180851b0381169283815265ffffffffffff82861c1680602083015260ff8360d01c169182604082015260ff808560d81c169485606084015260e01c16151594859101526040519485526020850152604084015260608301526080820152f35b5f80fd5b34610177576040366003190112610177576101bd60043561019a610a3a565b906101b86101b3825f525f602052600160405f20015490565b610b45565b610c05565b005b34610177575f366003190112610177576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610177575f3660031901126101775760206040515f8152f35b3461017757604036600319011261017757610236610a3a565b6004355f525f60205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610177575f36600319011261017757602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610177576080366003190112610177576102bb610a50565b6102c3610a3a565b6044359160643591906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169116036105d957821580156105d1575b6104c5576001600160a01b03165f8181526001602052604090819020905193919061033185610a66565b549060018060a01b03821685526020850165ffffffffffff8360a01c168152604086019160ff8460d01c16835260ff6060880194818160d81c16865260e01c1615801560808901526105bf57610385610c85565b604051633b835d2960e11b8152602081600481855afa908115610567575f91610584575b5061057257509451604051633fabe5a360e21b815294959394939060a090859060049082906001600160a01b03165afa908115610567575f945f9261052e575b505f851315610520578115918215610516575b82156104f7575b50506104e8576104249160ff8061041f93511691511690610ad1565b610b37565b61045060ff7f000000000000000000000000000000000000000000000000000000000000000016610b37565b8281029281840414901517156104d45761046992610e70565b9081156104c55761047982610d85565b61048283610e09565b9181811080156104bc575b6104a457602061049c85610d85565b604051908152f35b630bb4e9d560e41b5f5260045260245260445260645ffd5b5082811161048d565b63162908e360e11b5f5260045ffd5b634e487b7160e01b5f52601160045260245ffd5b630cd5fa0760e11b5f5260045ffd5b65ffffffffffff91925061050b9042610b2a565b915116108680610403565b42811192506103fc565b62bfc92160e01b5f5260045ffd5b909450610553915060a03d60a011610560575b61054b8183610a96565b810190610af5565b50959250509390876103e9565b503d610541565b6040513d5f823e3d90fd5b63071f6c4d60e01b5f5260045260245ffd5b90506020813d6020116105b7575b8161059f60209383610a96565b810103126101775751801515810361017757886103a9565b3d9150610592565b63a5be5e0f60e01b5f5260045260245ffd5b508115610307565b63a29cc06960e01b5f5260045ffd5b3461017757606036600319011261017757610601610a50565b610609610a3a565b6044359165ffffffffffff831680930361017757335f9081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561084b576001600160a01b0316908115801561083a575b61082b57821561081c5760405163313ce56760e01b81526001600160a01b03919091169290602081600481875afa908115610567575f916107fd575b5060405163313ce56760e01b815290602082600481875afa918215610567575f926107c7575b5060ff809116911691604d6106dd8484610ad1565b116107b8577fd4008f6c5dd7926276fe5a608dc17fb517cc26c5c151c05ce37afeb1d16c3f659260609260405161071381610a66565b878152602080820185815260408084018581528885018781526001608087018181525f8e8152918752908490209651875495519351925191516001600160e81b03199096166001600160a01b03919091161760a09390931b65ffffffffffff60a01b169290921760d09190911b60ff60d01b161760d89190911b60ff60d81b161791151560e01b60ff60e01b16919091179092558151948552840191909152820152a3005b630692acc560e51b5f5260045ffd5b60ff9192506107ee829160203d6020116107f6575b6107e68183610a96565b810190610ab8565b9291506106c8565b503d6107dc565b610816915060203d6020116107f6576107e68183610a96565b846106a2565b638f1825c960e01b5f5260045ffd5b63e6c4247b60e01b5f5260045ffd5b506001600160a01b03811615610666565b63e2517d3f60e01b5f52336004525f60245260445ffd5b346101775760403660031901126101775761087b610a3a565b336001600160a01b03821603610897576101bd90600435610c05565b63334bd91960e11b5f5260045ffd5b34610177575f366003190112610177576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610177576040366003190112610177576101bd600435610909610a3a565b906109226101b3825f525f602052600160405f20015490565b610b7d565b34610177575f36600319011261017757602060405161251c8152f35b34610177575f36600319011261017757602060405165ffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610177575f3660031901126101775760206040516101f48152f35b34610177575f3660031901126101775760206040516127108152f35b3461017757602036600319011261017757602061049c6004355f525f602052600160405f20015490565b34610177576020366003190112610177576004359063ffffffff60e01b821680920361017757602091637965db0b60e01b8114908115610a29575b5015158152f35b6301ffc9a760e01b14905083610a22565b602435906001600160a01b038216820361017757565b600435906001600160a01b038216820361017757565b60a0810190811067ffffffffffffffff821117610a8257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610a8257604052565b90816020910312610177575160ff811681036101775790565b919082018092116104d457565b519069ffffffffffffffffffff8216820361017757565b908160a091031261017757610b0981610ade565b91602082015191604081015191610b27608060608401519301610ade565b90565b919082039182116104d457565b604d81116104d457600a0a90565b5f8181526020818152604080832033845290915290205460ff1615610b675750565b63e2517d3f60e01b5f523360045260245260445ffd5b5f818152602081815260408083206001600160a01b038616845290915290205460ff16610bff575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b50505f90565b5f818152602081815260408083206001600160a01b038616845290915290205460ff1615610bff575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168015610d825760a060049160405192838092633fabe5a360e21b82525afa908115610567575f905f92610d5d575b50610d4f578015908115610d45575b8115610d09575b50610cfa57565b632d7512d760e21b5f5260045ffd5b610d14915042610b2a565b65ffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001610155f610cf3565b4281119150610cec565b62032b3d60e81b5f5260045ffd5b9050610d78915060a03d60a0116105605761054b8183610a96565b505091505f610cdd565b50565b905f5f1961251c840961251c840291828083109203918083039214610dfe57816127101115610dec575061271061251c7fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e9194950990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b505061271090049150565b905f5f196129048409612904840291828083109203918083039214610dfe57816127101115610dec57506127106129047fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e9194950990828211900360fc1b910360041c170290565b90915f198383099280830292838086109503948086039514610f015784831115610ee95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b505080925015610f0f570490565b634e487b7160e01b5f52601260045260245ffdfea2646970667358221220594e1d046fadf73884a17d029159954415f6c997118aa9ad5f18546964d8c86364736f6c634300081a0033ad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb50000000000000000000000005fc5360d0400a0fd4f2af552add042d716f1d16800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e10000000000000000000000000c0e13bf8ed6531112da483105b99af9fa7fcf507
0x6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a7146109e757508063248a9ca3146109bd578063249d39e9146109a157806325c684031461098557806326a97b9414610943578063290424cd146109275780632f2ff15d146108ea5780633013ce29146108a657806336568abe1461086257806336bc435b146105e857806368ea8ce9146102a25780638018b5ae1461026557806391d148541461021d578063a217fddf14610203578063a7264705146101bf578063d547741f1461017b5763fe136c4e146100d7575f80fd5b34610177576020366003190112610177576001600160a01b036100f8610a50565b165f52600160205260a060405f2060806040519161011583610a66565b54600180851b0381169283815265ffffffffffff82861c1680602083015260ff8360d01c169182604082015260ff808560d81c169485606084015260e01c16151594859101526040519485526020850152604084015260608301526080820152f35b5f80fd5b34610177576040366003190112610177576101bd60043561019a610a3a565b906101b86101b3825f525f602052600160405f20015490565b610b45565b610c05565b005b34610177575f366003190112610177576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610177575f3660031901126101775760206040515f8152f35b3461017757604036600319011261017757610236610a3a565b6004355f525f60205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b34610177575f36600319011261017757602060405160ff7f0000000000000000000000000000000000000000000000000000000000000006168152f35b34610177576080366003190112610177576102bb610a50565b6102c3610a3a565b6044359160643591906001600160a01b037f0000000000000000000000005fc5360d0400a0fd4f2af552add042d716f1d16881169116036105d957821580156105d1575b6104c5576001600160a01b03165f8181526001602052604090819020905193919061033185610a66565b549060018060a01b03821685526020850165ffffffffffff8360a01c168152604086019160ff8460d01c16835260ff6060880194818160d81c16865260e01c1615801560808901526105bf57610385610c85565b604051633b835d2960e11b8152602081600481855afa908115610567575f91610584575b5061057257509451604051633fabe5a360e21b815294959394939060a090859060049082906001600160a01b03165afa908115610567575f945f9261052e575b505f851315610520578115918215610516575b82156104f7575b50506104e8576104249160ff8061041f93511691511690610ad1565b610b37565b61045060ff7f000000000000000000000000000000000000000000000000000000000000000616610b37565b8281029281840414901517156104d45761046992610e70565b9081156104c55761047982610d85565b61048283610e09565b9181811080156104bc575b6104a457602061049c85610d85565b604051908152f35b630bb4e9d560e41b5f5260045260245260445260645ffd5b5082811161048d565b63162908e360e11b5f5260045ffd5b634e487b7160e01b5f52601160045260245ffd5b630cd5fa0760e11b5f5260045ffd5b65ffffffffffff91925061050b9042610b2a565b915116108680610403565b42811192506103fc565b62bfc92160e01b5f5260045ffd5b909450610553915060a03d60a011610560575b61054b8183610a96565b810190610af5565b50959250509390876103e9565b503d610541565b6040513d5f823e3d90fd5b63071f6c4d60e01b5f5260045260245ffd5b90506020813d6020116105b7575b8161059f60209383610a96565b810103126101775751801515810361017757886103a9565b3d9150610592565b63a5be5e0f60e01b5f5260045260245ffd5b508115610307565b63a29cc06960e01b5f5260045ffd5b3461017757606036600319011261017757610601610a50565b610609610a3a565b6044359165ffffffffffff831680930361017757335f9081527fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5602052604090205460ff161561084b576001600160a01b0316908115801561083a575b61082b57821561081c5760405163313ce56760e01b81526001600160a01b03919091169290602081600481875afa908115610567575f916107fd575b5060405163313ce56760e01b815290602082600481875afa918215610567575f926107c7575b5060ff809116911691604d6106dd8484610ad1565b116107b8577fd4008f6c5dd7926276fe5a608dc17fb517cc26c5c151c05ce37afeb1d16c3f659260609260405161071381610a66565b878152602080820185815260408084018581528885018781526001608087018181525f8e8152918752908490209651875495519351925191516001600160e81b03199096166001600160a01b03919091161760a09390931b65ffffffffffff60a01b169290921760d09190911b60ff60d01b161760d89190911b60ff60d81b161791151560e01b60ff60e01b16919091179092558151948552840191909152820152a3005b630692acc560e51b5f5260045ffd5b60ff9192506107ee829160203d6020116107f6575b6107e68183610a96565b810190610ab8565b9291506106c8565b503d6107dc565b610816915060203d6020116107f6576107e68183610a96565b846106a2565b638f1825c960e01b5f5260045ffd5b63e6c4247b60e01b5f5260045ffd5b506001600160a01b03811615610666565b63e2517d3f60e01b5f52336004525f60245260445ffd5b346101775760403660031901126101775761087b610a3a565b336001600160a01b03821603610897576101bd90600435610c05565b63334bd91960e11b5f5260045ffd5b34610177575f366003190112610177576040517f0000000000000000000000005fc5360d0400a0fd4f2af552add042d716f1d1686001600160a01b03168152602090f35b34610177576040366003190112610177576101bd600435610909610a3a565b906109226101b3825f525f602052600160405f20015490565b610b7d565b34610177575f36600319011261017757602060405161251c8152f35b34610177575f36600319011261017757602060405165ffffffffffff7f0000000000000000000000000000000000000000000000000000000000000e10168152f35b34610177575f3660031901126101775760206040516101f48152f35b34610177575f3660031901126101775760206040516127108152f35b3461017757602036600319011261017757602061049c6004355f525f602052600160405f20015490565b34610177576020366003190112610177576004359063ffffffff60e01b821680920361017757602091637965db0b60e01b8114908115610a29575b5015158152f35b6301ffc9a760e01b14905083610a22565b602435906001600160a01b038216820361017757565b600435906001600160a01b038216820361017757565b60a0810190811067ffffffffffffffff821117610a8257604052565b634e487b7160e01b5f52604160045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610a8257604052565b90816020910312610177575160ff811681036101775790565b919082018092116104d457565b519069ffffffffffffffffffff8216820361017757565b908160a091031261017757610b0981610ade565b91602082015191604081015191610b27608060608401519301610ade565b90565b919082039182116104d457565b604d81116104d457600a0a90565b5f8181526020818152604080832033845290915290205460ff1615610b675750565b63e2517d3f60e01b5f523360045260245260445ffd5b5f818152602081815260408083206001600160a01b038616845290915290205460ff16610bff575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b50505f90565b5f818152602081815260408083206001600160a01b038616845290915290205460ff1615610bff575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168015610d825760a060049160405192838092633fabe5a360e21b82525afa908115610567575f905f92610d5d575b50610d4f578015908115610d45575b8115610d09575b50610cfa57565b632d7512d760e21b5f5260045ffd5b610d14915042610b2a565b65ffffffffffff7f0000000000000000000000000000000000000000000000000000000000000e101610155f610cf3565b4281119150610cec565b62032b3d60e81b5f5260045ffd5b9050610d78915060a03d60a0116105605761054b8183610a96565b505091505f610cdd565b50565b905f5f1961251c840961251c840291828083109203918083039214610dfe57816127101115610dec575061271061251c7fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e9194950990828211900360fc1b910360041c170290565b634e487b71905260116020526024601cfd5b505061271090049150565b905f5f196129048409612904840291828083109203918083039214610dfe57816127101115610dec57506127106129047fbc01a36e2eb1c432ca57a786c226809d495182a9930be0ded288ce703afb7e9194950990828211900360fc1b910360041c170290565b90915f198383099280830292838086109503948086039514610f015784831115610ee95790829109815f0382168092046002816003021880820260020302808202600203028082026002030280820260020302808202600203028091026002030293600183805f03040190848311900302920304170290565b82634e487b715f52156003026011186020526024601cfd5b505080925015610f0f570490565b634e487b7160e01b5f52601260045260245ffdfea2646970667358221220594e1d046fadf73884a17d029159954415f6c997118aa9ad5f18546964d8c86364736f6c634300081a0033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| no token holdings | ||||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xa829f5…1b5ebe | configureToken | 16,718,964 | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000634 | |
| 0xb718cf…9b5e70 | configureToken | 16,718,960 | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000628 | |
| 0x5f6f52…699dc3 | configureToken | 16,718,956 | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000620 | |
| 0x68c8e2…b9e618 | configureToken | 16,718,953 | 25 days agoWed, 22 Jul 2026 20:38:27 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000632 | |
| 0x65ae3a…3658e4 | configureToken | 16,718,938 | 25 days agoWed, 22 Jul 2026 20:38:26 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000625 | |
| 0xf0a3c5…014103 | configureToken | 16,718,934 | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000637 | |
| 0x04c23a…be6feb | configureToken | 16,718,930 | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000630 | |
| 0xd0a1ed…799f51 | configureToken | 16,718,927 | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000624 | |
| 0xcef65c…c5267a | configureToken | 16,718,923 | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000632 | |
| 0x61a437…0738ca | configureToken | 16,718,920 | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000628 | |
| 0xded90d…13259a | configureToken | 16,718,917 | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000623 | |
| 0x605ab4…22bef4 | configureToken | 16,718,914 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000632 | |
| 0xa1ee67…2ab9d9 | configureToken | 16,718,911 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000629 | |
| 0xb4ba6d…5e79c9 | configureToken | 16,718,907 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000623 | |
| 0xf581a8…2d2e19 | configureToken | 16,718,904 | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000638 | |
| 0x2adf81…cdb5f8 | configureToken | 16,718,901 | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000634 | |
| 0x7295d6…135bac | configureToken | 16,718,897 | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000621 | |
| 0xea8067…b7e217 | configureToken | 16,718,883 | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000625 | |
| 0xeaa769…34543c | configureToken | 16,718,880 | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000623 | |
| 0xc05df2…a5a3cc | configureToken | 16,718,876 | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000620 | |
| 0x11f26a…087ef6 | configureToken | 16,718,873 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000626 | |
| 0x7859bc…e53bc9 | configureToken | 16,718,870 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000625 | |
| 0x6f21f6…cd0ac2 | configureToken | 16,718,866 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xc0e1…f507 | IN | ChainlinkStockPriceGuard | $0.000 ETH | 0.00000620 |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| no internal transactions found for this address yet (traced blocks + on-demand) | ||||||||
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| no token transfers for this address yet | |||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| 0xa829f5…1b5ebe | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xd4008f…3f65 | [0] 0x000000000000…4d56d344 [1] 0x000000000000…3766431c data: 0x000000000000000000…00000012 |
| 0xb718cf…9b5e70 | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xd4008f…3f65 | [0] 0x000000000000…ef09e7aa [1] 0x000000000000…3e41fc2f data: 0x000000000000000000…00000012 |
| 0x5f6f52…699dc3 | 25 days agoWed, 22 Jul 2026 20:38:28 UTC | 0xd4008f…3f65 | [0] 0x000000000000…1c003b2d [1] 0x000000000000…a5547c38 data: 0x000000000000000000…00000012 |
| 0x68c8e2…b9e618 | 25 days agoWed, 22 Jul 2026 20:38:27 UTC | 0xd4008f…3f65 | [0] 0x000000000000…2b3b4c0c [1] 0x000000000000…621f9f6a data: 0x000000000000000000…00000012 |
| 0x65ae3a…3658e4 | 25 days agoWed, 22 Jul 2026 20:38:26 UTC | 0xd4008f…3f65 | [0] 0x000000000000…fae35eea [1] 0x000000000000…6fd8bffb data: 0x000000000000000000…00000012 |
| 0xf0a3c5…014103 | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xd4008f…3f65 | [0] 0x000000000000…0ad7d89f [1] 0x000000000000…1ecba2ce data: 0x000000000000000000…00000012 |
| 0x04c23a…be6feb | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xd4008f…3f65 | [0] 0x000000000000…45fc12e2 [1] 0x000000000000…8381cc74 data: 0x000000000000000000…00000012 |
| 0xd0a1ed…799f51 | 25 days agoWed, 22 Jul 2026 20:38:25 UTC | 0xd4008f…3f65 | [0] 0x000000000000…be2597ba [1] 0x000000000000…d984f765 data: 0x000000000000000000…00000012 |
| 0xcef65c…c5267a | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xd4008f…3f65 | [0] 0x000000000000…5888de68 [1] 0x000000000000…9374c2ae data: 0x000000000000000000…00000012 |
| 0x61a437…0738ca | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xd4008f…3f65 | [0] 0x000000000000…320d9eec [1] 0x000000000000…3e8e9f15 data: 0x000000000000000000…00000012 |
| 0xded90d…13259a | 25 days agoWed, 22 Jul 2026 20:38:24 UTC | 0xd4008f…3f65 | [0] 0x000000000000…232d4afd [1] 0x000000000000…28a6d596 data: 0x000000000000000000…00000012 |
| 0x605ab4…22bef4 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xd4008f…3f65 | [0] 0x000000000000…9d42da09 [1] 0x000000000000…1c0edc3d data: 0x000000000000000000…00000012 |
| 0xa1ee67…2ab9d9 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xd4008f…3f65 | [0] 0x000000000000…669c2e74 [1] 0x000000000000…14c1af2e data: 0x000000000000000000…00000012 |
| 0xb4ba6d…5e79c9 | 25 days agoWed, 22 Jul 2026 20:38:23 UTC | 0xd4008f…3f65 | [0] 0x000000000000…7ce02f35 [1] 0x000000000000…356d71b1 data: 0x000000000000000000…00000012 |
| 0xf581a8…2d2e19 | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xd4008f…3f65 | [0] 0x000000000000…07640efe [1] 0x000000000000…de4971eb data: 0x000000000000000000…00000012 |
| 0x2adf81…cdb5f8 | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xd4008f…3f65 | [0] 0x000000000000…adad4fe3 [1] 0x000000000000…85ae638b data: 0x000000000000000000…00000012 |
| 0x7295d6…135bac | 25 days agoWed, 22 Jul 2026 20:38:22 UTC | 0xd4008f…3f65 | [0] 0x000000000000…66bf1cb5 [1] 0x000000000000…1f6b482a data: 0x000000000000000000…00000012 |
| 0xea8067…b7e217 | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xd4008f…3f65 | [0] 0x000000000000…7ccf450b [1] 0x000000000000…09a98ef2 data: 0x000000000000000000…00000012 |
| 0xeaa769…34543c | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xd4008f…3f65 | [0] 0x000000000000…a257cee3 [1] 0x000000000000…941f50ef data: 0x000000000000000000…00000012 |
| 0xc05df2…a5a3cc | 25 days agoWed, 22 Jul 2026 20:38:20 UTC | 0xd4008f…3f65 | [0] 0x000000000000…0a60daea [1] 0x000000000000…1b70f87d data: 0x000000000000000000…00000012 |
| 0x11f26a…087ef6 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xd4008f…3f65 | [0] 0x000000000000…e941bf54 [1] 0x000000000000…fb2a651c data: 0x000000000000000000…00000012 |
| 0x7859bc…e53bc9 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xd4008f…3f65 | [0] 0x000000000000…d2023fdc [1] 0x000000000000…b2a22c72 data: 0x000000000000000000…00000012 |
| 0x6f21f6…cd0ac2 | 25 days agoWed, 22 Jul 2026 20:38:19 UTC | 0xd4008f…3f65 | [0] 0x000000000000…8f8a93f9 [1] 0x000000000000…c99f2cd0 data: 0x000000000000000000…00000012 |
| 0x14b1b2…0bd98a | 25 days agoWed, 22 Jul 2026 20:38:18 UTC | 0x2f8788…6f0d | [0] 0x000000000000…00000000 [1] 0x000000000000…a7fcf507 [2] 0x000000000000…a7fcf507 |