Overview
HYPE Balance
HYPE Value
$0.00Latest 25 from a total of 1,578 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Update Validator... | 21660743 | 10 hrs ago | IN | 0 HYPE | 0.00015224 | ||||
| Update Validator... | 21660740 | 10 hrs ago | IN | 0 HYPE | 0.00015224 | ||||
| Update Validator... | 21660736 | 10 hrs ago | IN | 0 HYPE | 0.00000572 | ||||
| Update Validator... | 21660733 | 10 hrs ago | IN | 0 HYPE | 0.00015306 | ||||
| Update Validator... | 21660729 | 10 hrs ago | IN | 0 HYPE | 0.00015451 | ||||
| Update Validator... | 21660726 | 10 hrs ago | IN | 0 HYPE | 0.00015658 | ||||
| Update Validator... | 21660723 | 10 hrs ago | IN | 0 HYPE | 0.00015819 | ||||
| Update Validator... | 21660719 | 10 hrs ago | IN | 0 HYPE | 0.00016246 | ||||
| Update Validator... | 21660716 | 10 hrs ago | IN | 0 HYPE | 0.00001876 | ||||
| Update Validator... | 21660712 | 10 hrs ago | IN | 0 HYPE | 0.00016474 | ||||
| Update Validator... | 21660710 | 10 hrs ago | IN | 0 HYPE | 0.00018745 | ||||
| Update Validator... | 21660707 | 10 hrs ago | IN | 0 HYPE | 0.00003348 | ||||
| Update Validator... | 21660704 | 10 hrs ago | IN | 0 HYPE | 0.00003041 | ||||
| Update Validator... | 21660702 | 10 hrs ago | IN | 0 HYPE | 0.00003432 | ||||
| Update Validator... | 21660699 | 10 hrs ago | IN | 0 HYPE | 0.00002296 | ||||
| Update Validator... | 21660696 | 10 hrs ago | IN | 0 HYPE | 0.00001645 | ||||
| Update Validator... | 21660692 | 10 hrs ago | IN | 0 HYPE | 0.0000119 | ||||
| Update Validator... | 21660689 | 10 hrs ago | IN | 0 HYPE | 0.00000876 | ||||
| Update Validator... | 21660686 | 10 hrs ago | IN | 0 HYPE | 0.00017233 | ||||
| Update Validator... | 21660682 | 10 hrs ago | IN | 0 HYPE | 0.00000865 | ||||
| Update Validator... | 21571988 | 35 hrs ago | IN | 0 HYPE | 0.00015284 | ||||
| Update Validator... | 21571985 | 35 hrs ago | IN | 0 HYPE | 0.00015306 | ||||
| Update Validator... | 21571981 | 35 hrs ago | IN | 0 HYPE | 0.00015385 | ||||
| Update Validator... | 21571978 | 35 hrs ago | IN | 0 HYPE | 0.00015515 | ||||
| Update Validator... | 21571976 | 35 hrs ago | IN | 0 HYPE | 0.00015642 |
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
DefaultOracle
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.20;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
/**
* @title DefaultOracle
* @notice Oracle implementation for validator performance metrics
*/
contract DefaultOracle is AccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
/* ========== STRUCTS ========== */
struct ValidatorMetrics {
uint256 balance;
uint256 performanceScore; // Single aggregated score (0-10000 basis points)
uint256 reward;
uint256 slashing;
uint256 lastUpdateTime;
uint256 endBlock;
}
/* ========== CONSTANT ========== */
uint256 public constant BASIS_POINTS = 10000; // 100% in basis points
/* ========== STATE VARIABLES ========== */
// Role for updating metrics
bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR_ROLE");
// Minimum time between updates
uint256 public constant MIN_UPDATE_INTERVAL = 1 hours;
// Mapping of validator metrics
mapping(address => ValidatorMetrics) public validatorMetrics;
// Set of active validators
EnumerableSet.AddressSet private _validators;
/* ========== EVENTS ========== */
event MetricsUpdated(
address indexed validator,
uint256 balance,
uint256 performanceScore,
uint256 reward,
uint256 slashing,
uint256 endBlock
);
/* ========== CONSTRUCTOR ========== */
constructor(address admin, address operator) {
require(admin != address(0), "Invalid admin");
require(operator != address(0), "Invalid operator");
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(OPERATOR_ROLE, operator);
}
/* ========== EXTERNAL FUNCTIONS ========== */
/**
* @notice Update metrics for a validator
* @param validator Address of the validator
* @param balance Current balance
* @param performanceScore Single aggregated performance score (0-10000 basis points)
* @param reward Reward amount
* @param slashing Slashing amount
* @param endBlock End block number
*/
function updateValidatorMetrics(
address validator,
uint256 balance,
uint256 performanceScore,
uint256 reward,
uint256 slashing,
uint256 endBlock
) external onlyRole(OPERATOR_ROLE) {
require(validator != address(0), "Invalid validator");
require(performanceScore <= BASIS_POINTS, "Performance score exceeds BASIS_POINTS");
ValidatorMetrics memory metrics = validatorMetrics[validator];
require(block.timestamp >= metrics.lastUpdateTime + MIN_UPDATE_INTERVAL, "Update too frequent");
validatorMetrics[validator] = ValidatorMetrics({
balance: balance,
performanceScore: performanceScore,
reward: reward,
slashing: slashing,
lastUpdateTime: block.timestamp,
endBlock: endBlock
});
_validators.add(validator);
emit MetricsUpdated(validator, balance, performanceScore, reward, slashing, endBlock);
}
/**
* @notice Get metrics for a validator
* @param validator Address of the validator
*/
function getValidatorMetrics(address validator)
external
view
returns (uint256 balance, uint256 performanceScore, uint256 reward, uint256 slashing, uint256 timestamp)
{
ValidatorMetrics memory metrics = validatorMetrics[validator];
return (metrics.balance, metrics.performanceScore, metrics.reward, metrics.slashing, metrics.lastUpdateTime);
}
/**
* @notice Get all active validators
*/
function getValidators() external view returns (address[] memory) {
return _validators.values();
}
/**
* @notice Check if a validator has metrics
*/
function hasMetrics(address validator) external view returns (bool) {
return _validators.contains(validator);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` to `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.
pragma solidity ^0.8.20;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
assembly ("memory-safe") {
result := store
}
return result;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"admin","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"validator","type":"address"},{"indexed":false,"internalType":"uint256","name":"balance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"performanceScore","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"slashing","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"MetricsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_UPDATE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"getValidatorMetrics","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"slashing","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getValidators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"}],"name":"hasMetrics","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validator","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"slashing","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"name":"updateValidatorMetrics","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorMetrics","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"performanceScore","type":"uint256"},{"internalType":"uint256","name":"reward","type":"uint256"},{"internalType":"uint256","name":"slashing","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080346100ff57601f610cb038819003918201601f19168301916001600160401b038311848410176101035780849260409485528339810103126100ff57610052602061004b83610117565b9201610117565b6001600160a01b038216156100ca576001600160a01b038116156100925761007c6100829261012b565b506101a1565b50604051610a1b90816102358239f35b60405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b21037b832b930ba37b960811b6044820152606490fd5b60405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b21030b236b4b760991b6044820152606490fd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036100ff57565b6001600160a01b0381165f9081525f80516020610c90833981519152602052604090205460ff1661019c576001600160a01b03165f8181525f80516020610c9083398151915260205260408120805460ff191660011790553391905f80516020610c508339815191528180a4600190565b505f90565b6001600160a01b0381165f9081525f80516020610c70833981519152602052604090205460ff1661019c576001600160a01b03165f8181525f80516020610c7083398151915260205260408120805460ff191660011790553391907f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b929905f80516020610c508339815191529080a460019056fe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a71461077e57508063064a31fb1461070f578063248a9ca3146106dd5780632cd5a5a6146106a35780632f2ff15d1461066657806336568abe14610622578063669de2101461036e57806391d1485414610326578063a217fddf1461030c578063b5d8701814610262578063b7ab4db51461017b578063bd3be27c1461015f578063d547741f1461011b578063e1f1c4a7146100ff5763f5b541a6146100c1575f80fd5b346100fb575f3660031901126100fb5760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b346100fb575f3660031901126100fb5760206040516127108152f35b346100fb5760403660031901126100fb5761015d60043561013a6107e7565b90610158610153825f525f602052600160405f20015490565b610819565b6108d9565b005b346100fb575f3660031901126100fb576020604051610e108152f35b346100fb575f3660031901126100fb576040518060206002549182815201809160025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f5b81811061024c57505050829003601f01601f1916820167ffffffffffffffff8111838210176102385760408181526020808352845190830181905291928392918301915f5b818110610216575050500390f35b82516001600160a01b0316845285945060209384019390920191600101610208565b634e487b7160e01b5f52604160045260245ffd5b82548452602090930192600192830192016101c3565b346100fb5760203660031901126100fb576001600160a01b036102836107d1565b165f52600160205260405f206040519061029c826107fd565b610308815491828452600181015493846020820152600282015480604083015260038301549182606082015260a060056004860154958660808501520154910152604051958695869192608093969594919660a084019784526020840152604083015260608201520152565b0390f35b346100fb575f3660031901126100fb5760206040515f8152f35b346100fb5760403660031901126100fb5761033f6107e7565b6004355f525f60205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b346100fb5760c03660031901126100fb576103876107d1565b335f9081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460a43591608435916044359160243591606435919060ff16156105eb576001600160a01b03169485156105b257612710841161055e57855f52600160205260405f20604051610403816107fd565b8154815260018201546020820152600282015460408201526003820154606082015260a060056004840154938460808501520154910152610e10810180911161054a57421061050f577fd7f22bbfa2524e6e308b151c736e5b453ab2d8fa59fa8d2d46d0f2bf5362899a9461050a9260405161047e816107fd565b85815260058960208301898152604084018581526060850190878252608086019242845260a08701948a86525f52600160205260405f2096518755516001870155516002860155516003850155516004840155519101556104de88610959565b50604051958695869192608093969594919660a084019784526020840152604083015260608201520152565b0390a2005b60405162461bcd60e51b8152602060048201526013602482015272155c19185d19481d1bdbc8199c995c5d595b9d606a1b6044820152606490fd5b634e487b7160e01b5f52601160045260245ffd5b60405162461bcd60e51b815260206004820152602660248201527f506572666f726d616e63652073636f726520657863656564732042415349535f604482015265504f494e545360d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2103b30b634b230ba37b960791b6044820152606490fd5b63e2517d3f60e01b5f52336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260445ffd5b346100fb5760403660031901126100fb5761063b6107e7565b336001600160a01b038216036106575761015d906004356108d9565b63334bd91960e11b5f5260045ffd5b346100fb5760403660031901126100fb5761015d6004356106856107e7565b9061069e610153825f525f602052600160405f20015490565b610851565b346100fb5760203660031901126100fb576001600160a01b036106c46107d1565b165f526003602052602060405f20541515604051908152f35b346100fb5760203660031901126100fb5760206107076004355f525f602052600160405f20015490565b604051908152f35b346100fb5760203660031901126100fb576001600160a01b036107306107d1565b165f52600160205260c060405f2080549060018101549060028101546003820154906005600484015493015493604051958652602086015260408501526060840152608083015260a0820152f35b346100fb5760203660031901126100fb576004359063ffffffff60e01b82168092036100fb57602091637965db0b60e01b81149081156107c0575b5015158152f35b6301ffc9a760e01b149050836107b9565b600435906001600160a01b03821682036100fb57565b602435906001600160a01b03821682036100fb57565b60c0810190811067ffffffffffffffff82111761023857604052565b5f8181526020818152604080832033845290915290205460ff161561083b5750565b63e2517d3f60e01b5f523360045260245260445ffd5b5f818152602081815260408083206001600160a01b038616845290915290205460ff166108d3575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b50505f90565b5f818152602081815260408083206001600160a01b038616845290915290205460ff16156108d3575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b805f52600360205260405f2054155f146109e057600254680100000000000000008110156102385760018101806002558110156109cc577f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018190556002545f9182526003602052604090912055600190565b634e487b7160e01b5f52603260045260245ffd5b505f9056fea26469706673582212207233907a6f6ce0539ee51cd04bfc0b5990299c749c09cbeb3bdf01e1948b146864736f6c634300081a00332f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0dee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319fad3228b676f7d3cd4284a5443f17f1962b36e491b30a40b2405849e597ba5fb5000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a71461077e57508063064a31fb1461070f578063248a9ca3146106dd5780632cd5a5a6146106a35780632f2ff15d1461066657806336568abe14610622578063669de2101461036e57806391d1485414610326578063a217fddf1461030c578063b5d8701814610262578063b7ab4db51461017b578063bd3be27c1461015f578063d547741f1461011b578063e1f1c4a7146100ff5763f5b541a6146100c1575f80fd5b346100fb575f3660031901126100fb5760206040517f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b9298152f35b5f80fd5b346100fb575f3660031901126100fb5760206040516127108152f35b346100fb5760403660031901126100fb5761015d60043561013a6107e7565b90610158610153825f525f602052600160405f20015490565b610819565b6108d9565b005b346100fb575f3660031901126100fb576020604051610e108152f35b346100fb575f3660031901126100fb576040518060206002549182815201809160025f527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace905f5b81811061024c57505050829003601f01601f1916820167ffffffffffffffff8111838210176102385760408181526020808352845190830181905291928392918301915f5b818110610216575050500390f35b82516001600160a01b0316845285945060209384019390920191600101610208565b634e487b7160e01b5f52604160045260245ffd5b82548452602090930192600192830192016101c3565b346100fb5760203660031901126100fb576001600160a01b036102836107d1565b165f52600160205260405f206040519061029c826107fd565b610308815491828452600181015493846020820152600282015480604083015260038301549182606082015260a060056004860154958660808501520154910152604051958695869192608093969594919660a084019784526020840152604083015260608201520152565b0390f35b346100fb575f3660031901126100fb5760206040515f8152f35b346100fb5760403660031901126100fb5761033f6107e7565b6004355f525f60205260405f209060018060a01b03165f52602052602060ff60405f2054166040519015158152f35b346100fb5760c03660031901126100fb576103876107d1565b335f9081527fee57cd81e84075558e8fcc182a1f4393f91fc97f963a136e66b7f949a62f319f602052604090205460a43591608435916044359160243591606435919060ff16156105eb576001600160a01b03169485156105b257612710841161055e57855f52600160205260405f20604051610403816107fd565b8154815260018201546020820152600282015460408201526003820154606082015260a060056004840154938460808501520154910152610e10810180911161054a57421061050f577fd7f22bbfa2524e6e308b151c736e5b453ab2d8fa59fa8d2d46d0f2bf5362899a9461050a9260405161047e816107fd565b85815260058960208301898152604084018581526060850190878252608086019242845260a08701948a86525f52600160205260405f2096518755516001870155516002860155516003850155516004840155519101556104de88610959565b50604051958695869192608093969594919660a084019784526020840152604083015260608201520152565b0390a2005b60405162461bcd60e51b8152602060048201526013602482015272155c19185d19481d1bdbc8199c995c5d595b9d606a1b6044820152606490fd5b634e487b7160e01b5f52601160045260245ffd5b60405162461bcd60e51b815260206004820152602660248201527f506572666f726d616e63652073636f726520657863656564732042415349535f604482015265504f494e545360d01b6064820152608490fd5b60405162461bcd60e51b815260206004820152601160248201527024b73b30b634b2103b30b634b230ba37b960791b6044820152606490fd5b63e2517d3f60e01b5f52336004527f97667070c54ef182b0f5858b034beac1b6f3089aa2d3188bb1e8929f4fa9b92960245260445ffd5b346100fb5760403660031901126100fb5761063b6107e7565b336001600160a01b038216036106575761015d906004356108d9565b63334bd91960e11b5f5260045ffd5b346100fb5760403660031901126100fb5761015d6004356106856107e7565b9061069e610153825f525f602052600160405f20015490565b610851565b346100fb5760203660031901126100fb576001600160a01b036106c46107d1565b165f526003602052602060405f20541515604051908152f35b346100fb5760203660031901126100fb5760206107076004355f525f602052600160405f20015490565b604051908152f35b346100fb5760203660031901126100fb576001600160a01b036107306107d1565b165f52600160205260c060405f2080549060018101549060028101546003820154906005600484015493015493604051958652602086015260408501526060840152608083015260a0820152f35b346100fb5760203660031901126100fb576004359063ffffffff60e01b82168092036100fb57602091637965db0b60e01b81149081156107c0575b5015158152f35b6301ffc9a760e01b149050836107b9565b600435906001600160a01b03821682036100fb57565b602435906001600160a01b03821682036100fb57565b60c0810190811067ffffffffffffffff82111761023857604052565b5f8181526020818152604080832033845290915290205460ff161561083b5750565b63e2517d3f60e01b5f523360045260245260445ffd5b5f818152602081815260408083206001600160a01b038616845290915290205460ff166108d3575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b50505f90565b5f818152602081815260408083206001600160a01b038616845290915290205460ff16156108d3575f818152602081815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b805f52600360205260405f2054155f146109e057600254680100000000000000008110156102385760018101806002558110156109cc577f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018190556002545f9182526003602052604090912055600190565b634e487b7160e01b5f52603260045260245ffd5b505f9056fea26469706673582212207233907a6f6ce0539ee51cd04bfc0b5990299c749c09cbeb3bdf01e1948b146864736f6c634300081a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509
-----Decoded View---------------
Arg [0] : admin (address): 0xb05cb1a8188110ac2cB062996526b43179162509
Arg [1] : operator (address): 0xb05cb1a8188110ac2cB062996526b43179162509
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509
Arg [1] : 000000000000000000000000b05cb1a8188110ac2cb062996526b43179162509
Loading...
Loading
OVERVIEW
Oracle implementation for validator performance metrics.Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.