Source Code
Overview
S Balance
S Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ValidatorsRegistry
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import {IUpdateVerifier} from "./interfaces/IUpdateVerifier.sol";
import {IStateOracle} from "./interfaces/IStateOracle.sol";
/// Validators registry is an update verifier which use its internal storage of validators.
/// To be owned by UpdateManager, to allow setting validators by signed updates.
/// @custom:security-contact [email protected]
contract ValidatorsRegistry is Ownable, IUpdateVerifier {
mapping(address validatorId => uint256 weight) public validatorWeight;
mapping(address validatorAddr => uint256 validatorId) public validatorId;
uint256 public totalWeight;
address[] public validatorAddress;
IStateOracle public immutable stateOracle; // for threshold decreasing on stateOracle inactivity
constructor(address _stateOracle, address _ownedBy) Ownable(_ownedBy) {
stateOracle = IStateOracle(_stateOracle); // zero allowed (if no threshold decreasing should be applied)
validatorAddress.push(); // avoid lastValidatorId underflow
}
function lastValidatorId() public view returns(uint256) {
return validatorAddress.length - 1; // index 0 is not used
}
function setValidators(bytes calldata newValidatorsBytes) onlyOwner external {
IUpdateVerifier.Validator[] memory newValidators = abi.decode(newValidatorsBytes, (IUpdateVerifier.Validator[]));
uint256 total = totalWeight;
for (uint16 i; i < newValidators.length; i++) {
uint256 id = newValidators[i].id;
address newAddr = newValidators[i].addr;
uint256 newWeight = newValidators[i].weight;
require(id != 0, "validator id cannot be 0");
if (validatorAddress.length <= id) {
// adding new validator id
require(validatorId[newAddr] == 0, "setting duplicate address");
extendValidatorsArray(id + 1);
validatorAddress[id] = newAddr;
validatorId[newAddr] = id;
} else {
// existing validator id
address oldAddr = validatorAddress[id];
total -= validatorWeight[oldAddr];
if (oldAddr != newAddr) {
// setting new address (public key)
require(validatorId[newAddr] == 0, "setting duplicate address");
delete validatorWeight[oldAddr];
delete validatorId[oldAddr];
validatorAddress[id] = newAddr;
validatorId[newAddr] = id;
}
}
validatorWeight[newAddr] = newWeight;
total += newWeight;
}
totalWeight = total;
}
function extendValidatorsArray(uint256 newLength) private {
// set validatorAddress.length
assembly {
sstore(validatorAddress.slot, newLength)
}
}
/// Verify the state oracle update signatures
function verifyUpdate(uint256 blockNum, bytes32 stateRoot, uint256 chainId, bytes calldata newValidators, address proofVerifier, address updateVerifier, address exitAdmin, bytes[] calldata signatures) external view returns (uint256[] memory) {
bytes32 messageHash = keccak256(abi.encodePacked(uint8(0x19), uint8(0x00), msg.sender, blockNum, stateRoot, chainId, newValidators, proofVerifier, updateVerifier, exitAdmin));
uint256 weight = 0;
address lastSigner = address(0);
uint256[] memory signers = new uint256[](signatures.length);
for (uint16 i; i < signatures.length; i++) {
address signer = ECDSA.recover(messageHash, signatures[i]);
uint256 signerWeight = validatorWeight[signer];
require(signerWeight > 0, "Invalid signer");
require(signer > lastSigner, "Invalid signatures order"); // ensures signers uniqueness
lastSigner = signer;
weight += signerWeight;
signers[i] = validatorId[signer];
}
if (weight > (totalWeight * 2 / 3)) {
return signers; // fast path
}
// allow updating with lower quorum if the oracle is dying
if (weight > getQuorum()) {
return signers;
}
revert("Insufficient signatures weight");
}
function getQuorum() public view returns (uint256) {
uint256 total = totalWeight;
uint256 initialQuorum = total * 2 / 3; // 66%
uint256 recoveryQuorum = total * 55 / 100; // 55%
uint256 rebornQuorum = total / 3; // 33%
if (address(stateOracle) == address(0)) {
return initialQuorum; // threshold decreasing not enabled
}
uint256 lastUpdateTime = stateOracle.lastUpdateTime();
if (lastUpdateTime == 0) {
return initialQuorum; // state oracle not initialized yet
}
uint256 offlineTime = block.timestamp - lastUpdateTime;
if (offlineTime <= 5 days) {
return initialQuorum;
}
if (offlineTime <= 7 days) {
return slope(initialQuorum, recoveryQuorum, offlineTime - 5 days, 2 days);
}
if (offlineTime <= 182 days) {
return recoveryQuorum;
}
if (offlineTime <= 189 days) {
return slope(recoveryQuorum, rebornQuorum, offlineTime - 182 days, 7 days);
}
return rebornQuorum;
}
function slope(uint256 maxOut, uint256 minOut, uint256 currentDuration, uint256 totalDuration) private pure returns (uint256) {
uint256 slopeHeight = maxOut - minOut;
return maxOut - (slopeHeight * currentDuration / totalDuration);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// 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/cryptography/ECDSA.sol)
pragma solidity ^0.8.20;
/**
* @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
*
* These functions can be used to verify that a message was signed by the holder
* of the private keys of a given address.
*/
library ECDSA {
enum RecoverError {
NoError,
InvalidSignature,
InvalidSignatureLength,
InvalidSignatureS
}
/**
* @dev The signature derives the `address(0)`.
*/
error ECDSAInvalidSignature();
/**
* @dev The signature has an invalid length.
*/
error ECDSAInvalidSignatureLength(uint256 length);
/**
* @dev The signature has an S value that is in the upper half order.
*/
error ECDSAInvalidSignatureS(bytes32 s);
/**
* @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
* return address(0) without also returning an error description. Errors are documented using an enum (error type)
* and a bytes32 providing additional information about the error.
*
* If no error is returned, then the address can be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*
* Documentation for signature generation:
* - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
* - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
*/
function tryRecover(
bytes32 hash,
bytes memory signature
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
if (signature.length == 65) {
bytes32 r;
bytes32 s;
uint8 v;
// ecrecover takes the signature parameters, and the only way to get them
// currently is to use assembly.
assembly ("memory-safe") {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return tryRecover(hash, v, r, s);
} else {
return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
}
}
/**
* @dev Returns the address that signed a hashed message (`hash`) with
* `signature`. This address can then be used for verification purposes.
*
* The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
* this function rejects them by requiring the `s` value to be in the lower
* half order, and the `v` value to be either 27 or 28.
*
* IMPORTANT: `hash` _must_ be the result of a hash operation for the
* verification to be secure: it is possible to craft signatures that
* recover to arbitrary addresses for non-hashed data. A safe way to ensure
* this is by receiving a hash of the original message (which may otherwise
* be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
*/
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
*
* See https://eips.ethereum.org/EIPS/eip-2098[ERC-2098 short signatures]
*/
function tryRecover(
bytes32 hash,
bytes32 r,
bytes32 vs
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
unchecked {
bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
// We do not check for an overflow here since the shift operation results in 0 or 1.
uint8 v = uint8((uint256(vs) >> 255) + 27);
return tryRecover(hash, v, r, s);
}
}
/**
* @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
*/
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Overload of {ECDSA-tryRecover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function tryRecover(
bytes32 hash,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address recovered, RecoverError err, bytes32 errArg) {
// EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
// unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
// the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
// signatures from current libraries generate a unique signature with an s-value in the lower half order.
//
// If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
// with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
// vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
// these malleable signatures as well.
if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
return (address(0), RecoverError.InvalidSignatureS, s);
}
// If the signature is valid (and not malleable), return the signer address
address signer = ecrecover(hash, v, r, s);
if (signer == address(0)) {
return (address(0), RecoverError.InvalidSignature, bytes32(0));
}
return (signer, RecoverError.NoError, bytes32(0));
}
/**
* @dev Overload of {ECDSA-recover} that receives the `v`,
* `r` and `s` signature fields separately.
*/
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
(address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
_throwError(error, errorArg);
return recovered;
}
/**
* @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
*/
function _throwError(RecoverError error, bytes32 errorArg) private pure {
if (error == RecoverError.NoError) {
return; // no error: do nothing
} else if (error == RecoverError.InvalidSignature) {
revert ECDSAInvalidSignature();
} else if (error == RecoverError.InvalidSignatureLength) {
revert ECDSAInvalidSignatureLength(uint256(errorArg));
} else if (error == RecoverError.InvalidSignatureS) {
revert ECDSAInvalidSignatureS(errorArg);
}
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
/// State oracle provides the hash of a different chain state.
interface IStateOracle {
function lastState() external view returns (bytes32);
function lastBlockNum() external view returns (uint256);
function lastUpdateTime() external view returns (uint256);
function chainId() external view returns (uint256);
function update(uint256 blockNum, bytes32 stateRoot) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.27;
/// Update verifier provides a way to verify validators signatures on an update.
/// It provides access to the validators registry for the purpose of inter-chain synchronization.
interface IUpdateVerifier {
struct Validator {
uint256 id;
address addr;
uint256 weight;
}
/// Verify the state oracle update signatures
function verifyUpdate(uint256 blockNum, bytes32 stateRoot, uint256 chainId, bytes calldata newValidators, address proofVerifier, address updateVerifier, address exitAdmin, bytes[] calldata signatures) external view returns (uint256[] memory);
/// Write into the validators registry - reverts if the registry is readonly.
function setValidators(bytes calldata newValidators) external;
/// Get the highest validator id for purpose of iterating
function lastValidatorId() external view returns(uint256);
/// Get validator pubkey address by validator id
function validatorAddress(uint256 index) external view returns(address);
/// Get validator weight by validator address
function validatorWeight(address addr) external view returns(uint256);
/// Get validator id by validator pubkey address
function validatorId(address addr) external view returns(uint256);
/// Get weight of all registered validators
function totalWeight() external view returns(uint256);
/// Get weight necessary to update the state oracle
function getQuorum() external view returns (uint256);
}{
"evmVersion": "cancun",
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_stateOracle","type":"address"},{"internalType":"address","name":"_ownedBy","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"getQuorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastValidatorId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"newValidatorsBytes","type":"bytes"}],"name":"setValidators","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stateOracle","outputs":[{"internalType":"contract IStateOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"validatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorAddr","type":"address"}],"name":"validatorId","outputs":[{"internalType":"uint256","name":"validatorId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"validatorId","type":"address"}],"name":"validatorWeight","outputs":[{"internalType":"uint256","name":"weight","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNum","type":"uint256"},{"internalType":"bytes32","name":"stateRoot","type":"bytes32"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"bytes","name":"newValidators","type":"bytes"},{"internalType":"address","name":"proofVerifier","type":"address"},{"internalType":"address","name":"updateVerifier","type":"address"},{"internalType":"address","name":"exitAdmin","type":"address"},{"internalType":"bytes[]","name":"signatures","type":"bytes[]"}],"name":"verifyUpdate","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405234801561000f575f5ffd5b5060405161133638038061133683398101604081905261002e916100ed565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610083565b50506001600160a01b03166080526004805460010181555f5261011e565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146100e8575f5ffd5b919050565b5f5f604083850312156100fe575f5ffd5b610107836100d2565b9150610115602084016100d2565b90509250929050565b6080516111f36101435f395f818160ba0152818161085b015261089301526111f35ff3fe608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806396c82e571161006e57806396c82e5714610173578063a08d64ae1461017c578063a6ca5a8814610184578063af020388146101a3578063c26c12eb146101b6578063f2fde38b146101be575f5ffd5b8063076d27f5146100b55780630a6f1fe8146100f95780634d8d3d8c14610126578063715018a61461014657806387bdb56d146101505780638da5cb5b14610163575b5f5ffd5b6100dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610118610107366004610cbc565b60026020525f908152604090205481565b6040519081526020016100f0565b610139610134366004610d21565b6101d1565b6040516100f09190610e17565b61014e61048f565b005b61014e61015e366004610e4e565b6104a2565b5f546001600160a01b03166100dc565b61011860035481565b6101186107d4565b610118610192366004610cbc565b60016020525f908152604090205481565b6100dc6101b1366004610e8d565b6107ea565b610118610812565b61014e6101cc366004610cbc565b6109bb565b60605f60195f338e8e8e8e8e8e8e8e6040516020016101fa9b9a99989796959493929190610ea4565b60408051601f19818403018152919052805160209091012090505f80808567ffffffffffffffff81111561023057610230610f61565b604051908082528060200260200182016040528015610259578160200160208202803683370190505b5090505f5b61ffff81168711156103f3575f6102d0868a8a8561ffff1681811061028557610285610f75565b90506020028101906102979190610f89565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f892505050565b6001600160a01b0381165f908152600160205260409020549091508061032e5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b60448201526064015b60405180910390fd5b846001600160a01b0316826001600160a01b03161161038f5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e617475726573206f7264657200000000000000006044820152606401610325565b819450808661039e9190610fe0565b6001600160a01b0383165f90815260026020526040902054855191975090859061ffff86169081106103d2576103d2610f75565b602002602001018181525050505080806103eb90610ff3565b91505061025e565b5060038054610403906002611013565b61040d919061102a565b83111561041f57935061048192505050565b610427610812565b83111561043957935061048192505050565b60405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e74207369676e6174757265732077656967687400006044820152606401610325565b9a9950505050505050505050565b610497610a22565b6104a05f610a4e565b565b6104aa610a22565b5f6104b7828401846110a3565b6003549091505f5b82518161ffff1610156107cb575f838261ffff16815181106104e3576104e3610f75565b60200260200101515f015190505f848361ffff168151811061050757610507610f75565b60200260200101516020015190505f858461ffff168151811061052c5761052c610f75565b6020026020010151604001519050825f036105895760405162461bcd60e51b815260206004820152601860248201527f76616c696461746f722069642063616e6e6f74206265203000000000000000006044820152606401610325565b6004548310610657576001600160a01b0382165f90815260026020526040902054156105f35760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b610606610601846001610fe0565b600455565b816004848154811061061a5761061a610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918416815260029091526040902083905561078f565b5f6004848154811061066b5761066b610f75565b5f9182526020808320909101546001600160a01b0316808352600190915260409091205490915061069c908761117f565b9550826001600160a01b0316816001600160a01b03161461078d576001600160a01b0383165f90815260026020526040902054156107185760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b6001600160a01b0381165f9081526001602090815260408083208390556002909152812055600480548491908690811061075457610754610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591851681526002909152604090208490555b505b6001600160a01b0382165f9081526001602052604090208190556107b38186610fe0565b945050505080806107c390610ff3565b9150506104bf565b50600355505050565b6004545f906107e59060019061117f565b905090565b600481815481106107f9575f80fd5b5f918252602090912001546001600160a01b0316905081565b600380545f918290610825836002611013565b61082f919061102a565b90505f606461083f846037611013565b610849919061102a565b90505f61085760038561102a565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108905750909392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ed573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109119190611192565b9050805f03610924575091949350505050565b5f61092f824261117f565b905062069780811161094657509295945050505050565b62093a8081116109765761096b8585610962620697808561117f565b6202a300610a9d565b965050505050505090565b62eff100811161098b57509195945050505050565b62f92b8081116109b05761096b84846109a762eff1008561117f565b62093a80610a9d565b509095945050505050565b6109c3610a22565b6001600160a01b0381166109ec57604051631e4fbdf760e01b81525f6004820152602401610325565b6109f581610a4e565b50565b5f5f5f5f610a068686610ad4565b925092509250610a168282610b1d565b50909150505b92915050565b5f546001600160a01b031633146104a05760405163118cdaa760e01b8152336004820152602401610325565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f80610aa9858761117f565b905082610ab68583611013565b610ac0919061102a565b610aca908761117f565b9695505050505050565b5f5f5f8351604103610b0b576020840151604085015160608601515f1a610afd88828585610bd9565b955095509550505050610b16565b505081515f91506002905b9250925092565b5f826003811115610b3057610b306111a9565b03610b39575050565b6001826003811115610b4d57610b4d6111a9565b03610b6b5760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610b7f57610b7f6111a9565b03610ba05760405163fce698f760e01b815260048101829052602401610325565b6003826003811115610bb457610bb46111a9565b03610bd5576040516335e2f38360e21b815260048101829052602401610325565b5050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610c1257505f91506003905082610c97565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c63573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610c8e57505f925060019150829050610c97565b92505f91508190505b9450945094915050565b80356001600160a01b0381168114610cb7575f5ffd5b919050565b5f60208284031215610ccc575f5ffd5b610cd582610ca1565b9392505050565b5f5f83601f840112610cec575f5ffd5b50813567ffffffffffffffff811115610d03575f5ffd5b602083019150836020828501011115610d1a575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f5f6101008b8d031215610d3b575f5ffd5b8a35995060208b0135985060408b0135975060608b013567ffffffffffffffff811115610d66575f5ffd5b610d728d828e01610cdc565b9098509650610d85905060808c01610ca1565b9450610d9360a08c01610ca1565b9350610da160c08c01610ca1565b925060e08b013567ffffffffffffffff811115610dbc575f5ffd5b8b015f80601f83018f13610dce575f5ffd5b50813567ffffffffffffffff811115610de5575f5ffd5b6020830191508e60208260051b8501011115610dff575f5ffd5b8194508093505050509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b818110156109b0578351835260209384019390920191600101610e30565b5f5f60208385031215610e5f575f5ffd5b823567ffffffffffffffff811115610e75575f5ffd5b610e8185828601610cdc565b90969095509350505050565b5f60208284031215610e9d575f5ffd5b5035919050565b60ff60f81b8c60f81b16815260ff60f81b8b60f81b1660018201526bffffffffffffffffffffffff198a60601b166002820152886016820152876036820152866056820152848660768301375f858201607681015f81526bffffffffffffffffffffffff198760601b16815250610f2f608a82018660601b6bffffffffffffffffffffffff19169052565b610f4d609e82018560601b6bffffffffffffffffffffffff19169052565b60b2019d9c50505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112610f9e575f5ffd5b83018035915067ffffffffffffffff821115610fb8575f5ffd5b602001915036819003821315610d1a575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610a1c57610a1c610fcc565b5f61ffff821661ffff810361100a5761100a610fcc565b60010192915050565b8082028115828204841417610a1c57610a1c610fcc565b5f8261104457634e487b7160e01b5f52601260045260245ffd5b500490565b6040516060810167ffffffffffffffff8111828210171561106c5761106c610f61565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561109b5761109b610f61565b604052919050565b5f602082840312156110b3575f5ffd5b813567ffffffffffffffff8111156110c9575f5ffd5b8201601f810184136110d9575f5ffd5b803567ffffffffffffffff8111156110f3576110f3610f61565b61110260208260051b01611072565b80828252602082019150602060608402850101925086831115611123575f5ffd5b6020840193505b82841015610aca5760608488031215611141575f5ffd5b611149611049565b8435815261115960208601610ca1565b60208281019190915260408681013590830152908352606090940193919091019061112a565b81810381811115610a1c57610a1c610fcc565b5f602082840312156111a2575f5ffd5b5051919050565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220f3ec20db9e1410aaf82536137afeb935e35edbf784b0172c4db7352cd11aa9e264736f6c634300081b0033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080957d62c7cc252e5dd2f8691a9afb3087f88fa1
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806396c82e571161006e57806396c82e5714610173578063a08d64ae1461017c578063a6ca5a8814610184578063af020388146101a3578063c26c12eb146101b6578063f2fde38b146101be575f5ffd5b8063076d27f5146100b55780630a6f1fe8146100f95780634d8d3d8c14610126578063715018a61461014657806387bdb56d146101505780638da5cb5b14610163575b5f5ffd5b6100dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610118610107366004610cbc565b60026020525f908152604090205481565b6040519081526020016100f0565b610139610134366004610d21565b6101d1565b6040516100f09190610e17565b61014e61048f565b005b61014e61015e366004610e4e565b6104a2565b5f546001600160a01b03166100dc565b61011860035481565b6101186107d4565b610118610192366004610cbc565b60016020525f908152604090205481565b6100dc6101b1366004610e8d565b6107ea565b610118610812565b61014e6101cc366004610cbc565b6109bb565b60605f60195f338e8e8e8e8e8e8e8e6040516020016101fa9b9a99989796959493929190610ea4565b60408051601f19818403018152919052805160209091012090505f80808567ffffffffffffffff81111561023057610230610f61565b604051908082528060200260200182016040528015610259578160200160208202803683370190505b5090505f5b61ffff81168711156103f3575f6102d0868a8a8561ffff1681811061028557610285610f75565b90506020028101906102979190610f89565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f892505050565b6001600160a01b0381165f908152600160205260409020549091508061032e5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b60448201526064015b60405180910390fd5b846001600160a01b0316826001600160a01b03161161038f5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e617475726573206f7264657200000000000000006044820152606401610325565b819450808661039e9190610fe0565b6001600160a01b0383165f90815260026020526040902054855191975090859061ffff86169081106103d2576103d2610f75565b602002602001018181525050505080806103eb90610ff3565b91505061025e565b5060038054610403906002611013565b61040d919061102a565b83111561041f57935061048192505050565b610427610812565b83111561043957935061048192505050565b60405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e74207369676e6174757265732077656967687400006044820152606401610325565b9a9950505050505050505050565b610497610a22565b6104a05f610a4e565b565b6104aa610a22565b5f6104b7828401846110a3565b6003549091505f5b82518161ffff1610156107cb575f838261ffff16815181106104e3576104e3610f75565b60200260200101515f015190505f848361ffff168151811061050757610507610f75565b60200260200101516020015190505f858461ffff168151811061052c5761052c610f75565b6020026020010151604001519050825f036105895760405162461bcd60e51b815260206004820152601860248201527f76616c696461746f722069642063616e6e6f74206265203000000000000000006044820152606401610325565b6004548310610657576001600160a01b0382165f90815260026020526040902054156105f35760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b610606610601846001610fe0565b600455565b816004848154811061061a5761061a610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918416815260029091526040902083905561078f565b5f6004848154811061066b5761066b610f75565b5f9182526020808320909101546001600160a01b0316808352600190915260409091205490915061069c908761117f565b9550826001600160a01b0316816001600160a01b03161461078d576001600160a01b0383165f90815260026020526040902054156107185760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b6001600160a01b0381165f9081526001602090815260408083208390556002909152812055600480548491908690811061075457610754610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591851681526002909152604090208490555b505b6001600160a01b0382165f9081526001602052604090208190556107b38186610fe0565b945050505080806107c390610ff3565b9150506104bf565b50600355505050565b6004545f906107e59060019061117f565b905090565b600481815481106107f9575f80fd5b5f918252602090912001546001600160a01b0316905081565b600380545f918290610825836002611013565b61082f919061102a565b90505f606461083f846037611013565b610849919061102a565b90505f61085760038561102a565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108905750909392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ed573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109119190611192565b9050805f03610924575091949350505050565b5f61092f824261117f565b905062069780811161094657509295945050505050565b62093a8081116109765761096b8585610962620697808561117f565b6202a300610a9d565b965050505050505090565b62eff100811161098b57509195945050505050565b62f92b8081116109b05761096b84846109a762eff1008561117f565b62093a80610a9d565b509095945050505050565b6109c3610a22565b6001600160a01b0381166109ec57604051631e4fbdf760e01b81525f6004820152602401610325565b6109f581610a4e565b50565b5f5f5f5f610a068686610ad4565b925092509250610a168282610b1d565b50909150505b92915050565b5f546001600160a01b031633146104a05760405163118cdaa760e01b8152336004820152602401610325565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f80610aa9858761117f565b905082610ab68583611013565b610ac0919061102a565b610aca908761117f565b9695505050505050565b5f5f5f8351604103610b0b576020840151604085015160608601515f1a610afd88828585610bd9565b955095509550505050610b16565b505081515f91506002905b9250925092565b5f826003811115610b3057610b306111a9565b03610b39575050565b6001826003811115610b4d57610b4d6111a9565b03610b6b5760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610b7f57610b7f6111a9565b03610ba05760405163fce698f760e01b815260048101829052602401610325565b6003826003811115610bb457610bb46111a9565b03610bd5576040516335e2f38360e21b815260048101829052602401610325565b5050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610c1257505f91506003905082610c97565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c63573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610c8e57505f925060019150829050610c97565b92505f91508190505b9450945094915050565b80356001600160a01b0381168114610cb7575f5ffd5b919050565b5f60208284031215610ccc575f5ffd5b610cd582610ca1565b9392505050565b5f5f83601f840112610cec575f5ffd5b50813567ffffffffffffffff811115610d03575f5ffd5b602083019150836020828501011115610d1a575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f5f6101008b8d031215610d3b575f5ffd5b8a35995060208b0135985060408b0135975060608b013567ffffffffffffffff811115610d66575f5ffd5b610d728d828e01610cdc565b9098509650610d85905060808c01610ca1565b9450610d9360a08c01610ca1565b9350610da160c08c01610ca1565b925060e08b013567ffffffffffffffff811115610dbc575f5ffd5b8b015f80601f83018f13610dce575f5ffd5b50813567ffffffffffffffff811115610de5575f5ffd5b6020830191508e60208260051b8501011115610dff575f5ffd5b8194508093505050509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b818110156109b0578351835260209384019390920191600101610e30565b5f5f60208385031215610e5f575f5ffd5b823567ffffffffffffffff811115610e75575f5ffd5b610e8185828601610cdc565b90969095509350505050565b5f60208284031215610e9d575f5ffd5b5035919050565b60ff60f81b8c60f81b16815260ff60f81b8b60f81b1660018201526bffffffffffffffffffffffff198a60601b166002820152886016820152876036820152866056820152848660768301375f858201607681015f81526bffffffffffffffffffffffff198760601b16815250610f2f608a82018660601b6bffffffffffffffffffffffff19169052565b610f4d609e82018560601b6bffffffffffffffffffffffff19169052565b60b2019d9c50505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112610f9e575f5ffd5b83018035915067ffffffffffffffff821115610fb8575f5ffd5b602001915036819003821315610d1a575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610a1c57610a1c610fcc565b5f61ffff821661ffff810361100a5761100a610fcc565b60010192915050565b8082028115828204841417610a1c57610a1c610fcc565b5f8261104457634e487b7160e01b5f52601260045260245ffd5b500490565b6040516060810167ffffffffffffffff8111828210171561106c5761106c610f61565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561109b5761109b610f61565b604052919050565b5f602082840312156110b3575f5ffd5b813567ffffffffffffffff8111156110c9575f5ffd5b8201601f810184136110d9575f5ffd5b803567ffffffffffffffff8111156110f3576110f3610f61565b61110260208260051b01611072565b80828252602082019150602060608402850101925086831115611123575f5ffd5b6020840193505b82841015610aca5760608488031215611141575f5ffd5b611149611049565b8435815261115960208601610ca1565b60208281019190915260408681013590830152908352606090940193919091019061112a565b81810381811115610a1c57610a1c610fcc565b5f602082840312156111a2575f5ffd5b5051919050565b634e487b7160e01b5f52602160045260245ffdfea2646970667358221220f3ec20db9e1410aaf82536137afeb935e35edbf784b0172c4db7352cd11aa9e264736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080957d62c7cc252e5dd2f8691a9afb3087f88fa1
-----Decoded View---------------
Arg [0] : _stateOracle (address): 0x0000000000000000000000000000000000000000
Arg [1] : _ownedBy (address): 0x80957D62C7Cc252E5dd2f8691a9afB3087f88Fa1
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 00000000000000000000000080957d62c7cc252e5dd2f8691a9afb3087f88fa1
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in S
Multichain Portfolio | 35 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.