Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
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.0.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, RecoverError, bytes32) { 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. /// @solidity memory-safe-assembly assembly { 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[EIP-2098 short signatures] */ function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) { 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, RecoverError, bytes32) { // 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
[{"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
60a060405234801561000f575f5ffd5b5060405161133638038061133683398101604081905261002e916100ed565b806001600160a01b03811661005c57604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b61006581610083565b50506001600160a01b03166080526004805460010181555f5261011e565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b03811681146100e8575f5ffd5b919050565b5f5f604083850312156100fe575f5ffd5b610107836100d2565b9150610115602084016100d2565b90509250929050565b6080516111f36101435f395f818160ba0152818161085b015261089301526111f35ff3fe608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806396c82e571161006e57806396c82e5714610173578063a08d64ae1461017c578063a6ca5a8814610184578063af020388146101a3578063c26c12eb146101b6578063f2fde38b146101be575f5ffd5b8063076d27f5146100b55780630a6f1fe8146100f95780634d8d3d8c14610126578063715018a61461014657806387bdb56d146101505780638da5cb5b14610163575b5f5ffd5b6100dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610118610107366004610cbc565b60026020525f908152604090205481565b6040519081526020016100f0565b610139610134366004610d21565b6101d1565b6040516100f09190610e17565b61014e61048f565b005b61014e61015e366004610e4e565b6104a2565b5f546001600160a01b03166100dc565b61011860035481565b6101186107d4565b610118610192366004610cbc565b60016020525f908152604090205481565b6100dc6101b1366004610e8d565b6107ea565b610118610812565b61014e6101cc366004610cbc565b6109bb565b60605f60195f338e8e8e8e8e8e8e8e6040516020016101fa9b9a99989796959493929190610ea4565b60408051601f19818403018152919052805160209091012090505f80808567ffffffffffffffff81111561023057610230610f61565b604051908082528060200260200182016040528015610259578160200160208202803683370190505b5090505f5b61ffff81168711156103f3575f6102d0868a8a8561ffff1681811061028557610285610f75565b90506020028101906102979190610f89565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f892505050565b6001600160a01b0381165f908152600160205260409020549091508061032e5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b60448201526064015b60405180910390fd5b846001600160a01b0316826001600160a01b03161161038f5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e617475726573206f7264657200000000000000006044820152606401610325565b819450808661039e9190610fe0565b6001600160a01b0383165f90815260026020526040902054855191975090859061ffff86169081106103d2576103d2610f75565b602002602001018181525050505080806103eb90610ff3565b91505061025e565b5060038054610403906002611013565b61040d919061102a565b83111561041f57935061048192505050565b610427610812565b83111561043957935061048192505050565b60405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e74207369676e6174757265732077656967687400006044820152606401610325565b9a9950505050505050505050565b610497610a22565b6104a05f610a4e565b565b6104aa610a22565b5f6104b7828401846110a3565b6003549091505f5b82518161ffff1610156107cb575f838261ffff16815181106104e3576104e3610f75565b60200260200101515f015190505f848361ffff168151811061050757610507610f75565b60200260200101516020015190505f858461ffff168151811061052c5761052c610f75565b6020026020010151604001519050825f036105895760405162461bcd60e51b815260206004820152601860248201527f76616c696461746f722069642063616e6e6f74206265203000000000000000006044820152606401610325565b6004548310610657576001600160a01b0382165f90815260026020526040902054156105f35760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b610606610601846001610fe0565b600455565b816004848154811061061a5761061a610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918416815260029091526040902083905561078f565b5f6004848154811061066b5761066b610f75565b5f9182526020808320909101546001600160a01b0316808352600190915260409091205490915061069c908761117f565b9550826001600160a01b0316816001600160a01b03161461078d576001600160a01b0383165f90815260026020526040902054156107185760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b6001600160a01b0381165f9081526001602090815260408083208390556002909152812055600480548491908690811061075457610754610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591851681526002909152604090208490555b505b6001600160a01b0382165f9081526001602052604090208190556107b38186610fe0565b945050505080806107c390610ff3565b9150506104bf565b50600355505050565b6004545f906107e59060019061117f565b905090565b600481815481106107f9575f80fd5b5f918252602090912001546001600160a01b0316905081565b600380545f918290610825836002611013565b61082f919061102a565b90505f606461083f846037611013565b610849919061102a565b90505f61085760038561102a565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108905750909392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ed573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109119190611192565b9050805f03610924575091949350505050565b5f61092f824261117f565b905062069780811161094657509295945050505050565b62093a8081116109765761096b8585610962620697808561117f565b6202a300610a9d565b965050505050505090565b62eff100811161098b57509195945050505050565b62f92b8081116109b05761096b84846109a762eff1008561117f565b62093a80610a9d565b509095945050505050565b6109c3610a22565b6001600160a01b0381166109ec57604051631e4fbdf760e01b81525f6004820152602401610325565b6109f581610a4e565b50565b5f5f5f5f610a068686610ad4565b925092509250610a168282610b1d565b50909150505b92915050565b5f546001600160a01b031633146104a05760405163118cdaa760e01b8152336004820152602401610325565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f80610aa9858761117f565b905082610ab68583611013565b610ac0919061102a565b610aca908761117f565b9695505050505050565b5f5f5f8351604103610b0b576020840151604085015160608601515f1a610afd88828585610bd9565b955095509550505050610b16565b505081515f91506002905b9250925092565b5f826003811115610b3057610b306111a9565b03610b39575050565b6001826003811115610b4d57610b4d6111a9565b03610b6b5760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610b7f57610b7f6111a9565b03610ba05760405163fce698f760e01b815260048101829052602401610325565b6003826003811115610bb457610bb46111a9565b03610bd5576040516335e2f38360e21b815260048101829052602401610325565b5050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610c1257505f91506003905082610c97565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c63573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610c8e57505f925060019150829050610c97565b92505f91508190505b9450945094915050565b80356001600160a01b0381168114610cb7575f5ffd5b919050565b5f60208284031215610ccc575f5ffd5b610cd582610ca1565b9392505050565b5f5f83601f840112610cec575f5ffd5b50813567ffffffffffffffff811115610d03575f5ffd5b602083019150836020828501011115610d1a575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f5f6101008b8d031215610d3b575f5ffd5b8a35995060208b0135985060408b0135975060608b013567ffffffffffffffff811115610d66575f5ffd5b610d728d828e01610cdc565b9098509650610d85905060808c01610ca1565b9450610d9360a08c01610ca1565b9350610da160c08c01610ca1565b925060e08b013567ffffffffffffffff811115610dbc575f5ffd5b8b015f80601f83018f13610dce575f5ffd5b50813567ffffffffffffffff811115610de5575f5ffd5b6020830191508e60208260051b8501011115610dff575f5ffd5b8194508093505050509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b818110156109b0578351835260209384019390920191600101610e30565b5f5f60208385031215610e5f575f5ffd5b823567ffffffffffffffff811115610e75575f5ffd5b610e8185828601610cdc565b90969095509350505050565b5f60208284031215610e9d575f5ffd5b5035919050565b60ff60f81b8c60f81b16815260ff60f81b8b60f81b1660018201526bffffffffffffffffffffffff198a60601b166002820152886016820152876036820152866056820152848660768301375f858201607681015f81526bffffffffffffffffffffffff198760601b16815250610f2f608a82018660601b6bffffffffffffffffffffffff19169052565b610f4d609e82018560601b6bffffffffffffffffffffffff19169052565b60b2019d9c50505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112610f9e575f5ffd5b83018035915067ffffffffffffffff821115610fb8575f5ffd5b602001915036819003821315610d1a575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610a1c57610a1c610fcc565b5f61ffff821661ffff810361100a5761100a610fcc565b60010192915050565b8082028115828204841417610a1c57610a1c610fcc565b5f8261104457634e487b7160e01b5f52601260045260245ffd5b500490565b6040516060810167ffffffffffffffff8111828210171561106c5761106c610f61565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561109b5761109b610f61565b604052919050565b5f602082840312156110b3575f5ffd5b813567ffffffffffffffff8111156110c9575f5ffd5b8201601f810184136110d9575f5ffd5b803567ffffffffffffffff8111156110f3576110f3610f61565b61110260208260051b01611072565b80828252602082019150602060608402850101925086831115611123575f5ffd5b6020840193505b82841015610aca5760608488031215611141575f5ffd5b611149611049565b8435815261115960208601610ca1565b60208281019190915260408681013590830152908352606090940193919091019061112a565b81810381811115610a1c57610a1c610fcc565b5f602082840312156111a2575f5ffd5b5051919050565b634e487b7160e01b5f52602160045260245ffdfea264697066735822122055b6f6e6e7753f8b136b96964e379491bbb5143ccb5b7498768042c740de200b64736f6c634300081b0033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080957d62c7cc252e5dd2f8691a9afb3087f88fa1
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806396c82e571161006e57806396c82e5714610173578063a08d64ae1461017c578063a6ca5a8814610184578063af020388146101a3578063c26c12eb146101b6578063f2fde38b146101be575f5ffd5b8063076d27f5146100b55780630a6f1fe8146100f95780634d8d3d8c14610126578063715018a61461014657806387bdb56d146101505780638da5cb5b14610163575b5f5ffd5b6100dc7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b610118610107366004610cbc565b60026020525f908152604090205481565b6040519081526020016100f0565b610139610134366004610d21565b6101d1565b6040516100f09190610e17565b61014e61048f565b005b61014e61015e366004610e4e565b6104a2565b5f546001600160a01b03166100dc565b61011860035481565b6101186107d4565b610118610192366004610cbc565b60016020525f908152604090205481565b6100dc6101b1366004610e8d565b6107ea565b610118610812565b61014e6101cc366004610cbc565b6109bb565b60605f60195f338e8e8e8e8e8e8e8e6040516020016101fa9b9a99989796959493929190610ea4565b60408051601f19818403018152919052805160209091012090505f80808567ffffffffffffffff81111561023057610230610f61565b604051908082528060200260200182016040528015610259578160200160208202803683370190505b5090505f5b61ffff81168711156103f3575f6102d0868a8a8561ffff1681811061028557610285610f75565b90506020028101906102979190610f89565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f892505050565b6001600160a01b0381165f908152600160205260409020549091508061032e5760405162461bcd60e51b815260206004820152600e60248201526d24b73b30b634b21039b4b3b732b960911b60448201526064015b60405180910390fd5b846001600160a01b0316826001600160a01b03161161038f5760405162461bcd60e51b815260206004820152601860248201527f496e76616c6964207369676e617475726573206f7264657200000000000000006044820152606401610325565b819450808661039e9190610fe0565b6001600160a01b0383165f90815260026020526040902054855191975090859061ffff86169081106103d2576103d2610f75565b602002602001018181525050505080806103eb90610ff3565b91505061025e565b5060038054610403906002611013565b61040d919061102a565b83111561041f57935061048192505050565b610427610812565b83111561043957935061048192505050565b60405162461bcd60e51b815260206004820152601e60248201527f496e73756666696369656e74207369676e6174757265732077656967687400006044820152606401610325565b9a9950505050505050505050565b610497610a22565b6104a05f610a4e565b565b6104aa610a22565b5f6104b7828401846110a3565b6003549091505f5b82518161ffff1610156107cb575f838261ffff16815181106104e3576104e3610f75565b60200260200101515f015190505f848361ffff168151811061050757610507610f75565b60200260200101516020015190505f858461ffff168151811061052c5761052c610f75565b6020026020010151604001519050825f036105895760405162461bcd60e51b815260206004820152601860248201527f76616c696461746f722069642063616e6e6f74206265203000000000000000006044820152606401610325565b6004548310610657576001600160a01b0382165f90815260026020526040902054156105f35760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b610606610601846001610fe0565b600455565b816004848154811061061a5761061a610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b03948516179055918416815260029091526040902083905561078f565b5f6004848154811061066b5761066b610f75565b5f9182526020808320909101546001600160a01b0316808352600190915260409091205490915061069c908761117f565b9550826001600160a01b0316816001600160a01b03161461078d576001600160a01b0383165f90815260026020526040902054156107185760405162461bcd60e51b815260206004820152601960248201527873657474696e67206475706c6963617465206164647265737360381b6044820152606401610325565b6001600160a01b0381165f9081526001602090815260408083208390556002909152812055600480548491908690811061075457610754610f75565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591851681526002909152604090208490555b505b6001600160a01b0382165f9081526001602052604090208190556107b38186610fe0565b945050505080806107c390610ff3565b9150506104bf565b50600355505050565b6004545f906107e59060019061117f565b905090565b600481815481106107f9575f80fd5b5f918252602090912001546001600160a01b0316905081565b600380545f918290610825836002611013565b61082f919061102a565b90505f606461083f846037611013565b610849919061102a565b90505f61085760038561102a565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108905750909392505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c8f33c916040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108ed573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109119190611192565b9050805f03610924575091949350505050565b5f61092f824261117f565b905062069780811161094657509295945050505050565b62093a8081116109765761096b8585610962620697808561117f565b6202a300610a9d565b965050505050505090565b62eff100811161098b57509195945050505050565b62f92b8081116109b05761096b84846109a762eff1008561117f565b62093a80610a9d565b509095945050505050565b6109c3610a22565b6001600160a01b0381166109ec57604051631e4fbdf760e01b81525f6004820152602401610325565b6109f581610a4e565b50565b5f5f5f5f610a068686610ad4565b925092509250610a168282610b1d565b50909150505b92915050565b5f546001600160a01b031633146104a05760405163118cdaa760e01b8152336004820152602401610325565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f80610aa9858761117f565b905082610ab68583611013565b610ac0919061102a565b610aca908761117f565b9695505050505050565b5f5f5f8351604103610b0b576020840151604085015160608601515f1a610afd88828585610bd9565b955095509550505050610b16565b505081515f91506002905b9250925092565b5f826003811115610b3057610b306111a9565b03610b39575050565b6001826003811115610b4d57610b4d6111a9565b03610b6b5760405163f645eedf60e01b815260040160405180910390fd5b6002826003811115610b7f57610b7f6111a9565b03610ba05760405163fce698f760e01b815260048101829052602401610325565b6003826003811115610bb457610bb46111a9565b03610bd5576040516335e2f38360e21b815260048101829052602401610325565b5050565b5f80807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115610c1257505f91506003905082610c97565b604080515f808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa158015610c63573d5f5f3e3d5ffd5b5050604051601f1901519150506001600160a01b038116610c8e57505f925060019150829050610c97565b92505f91508190505b9450945094915050565b80356001600160a01b0381168114610cb7575f5ffd5b919050565b5f60208284031215610ccc575f5ffd5b610cd582610ca1565b9392505050565b5f5f83601f840112610cec575f5ffd5b50813567ffffffffffffffff811115610d03575f5ffd5b602083019150836020828501011115610d1a575f5ffd5b9250929050565b5f5f5f5f5f5f5f5f5f5f6101008b8d031215610d3b575f5ffd5b8a35995060208b0135985060408b0135975060608b013567ffffffffffffffff811115610d66575f5ffd5b610d728d828e01610cdc565b9098509650610d85905060808c01610ca1565b9450610d9360a08c01610ca1565b9350610da160c08c01610ca1565b925060e08b013567ffffffffffffffff811115610dbc575f5ffd5b8b015f80601f83018f13610dce575f5ffd5b50813567ffffffffffffffff811115610de5575f5ffd5b6020830191508e60208260051b8501011115610dff575f5ffd5b8194508093505050509295989b9194979a5092959850565b602080825282518282018190525f918401906040840190835b818110156109b0578351835260209384019390920191600101610e30565b5f5f60208385031215610e5f575f5ffd5b823567ffffffffffffffff811115610e75575f5ffd5b610e8185828601610cdc565b90969095509350505050565b5f60208284031215610e9d575f5ffd5b5035919050565b60ff60f81b8c60f81b16815260ff60f81b8b60f81b1660018201526bffffffffffffffffffffffff198a60601b166002820152886016820152876036820152866056820152848660768301375f858201607681015f81526bffffffffffffffffffffffff198760601b16815250610f2f608a82018660601b6bffffffffffffffffffffffff19169052565b610f4d609e82018560601b6bffffffffffffffffffffffff19169052565b60b2019d9c50505050505050505050505050565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52603260045260245ffd5b5f5f8335601e19843603018112610f9e575f5ffd5b83018035915067ffffffffffffffff821115610fb8575f5ffd5b602001915036819003821315610d1a575f5ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610a1c57610a1c610fcc565b5f61ffff821661ffff810361100a5761100a610fcc565b60010192915050565b8082028115828204841417610a1c57610a1c610fcc565b5f8261104457634e487b7160e01b5f52601260045260245ffd5b500490565b6040516060810167ffffffffffffffff8111828210171561106c5761106c610f61565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561109b5761109b610f61565b604052919050565b5f602082840312156110b3575f5ffd5b813567ffffffffffffffff8111156110c9575f5ffd5b8201601f810184136110d9575f5ffd5b803567ffffffffffffffff8111156110f3576110f3610f61565b61110260208260051b01611072565b80828252602082019150602060608402850101925086831115611123575f5ffd5b6020840193505b82841015610aca5760608488031215611141575f5ffd5b611149611049565b8435815261115960208601610ca1565b60208281019190915260408681013590830152908352606090940193919091019061112a565b81810381811115610a1c57610a1c610fcc565b5f602082840312156111a2575f5ffd5b5051919050565b634e487b7160e01b5f52602160045260245ffdfea264697066735822122055b6f6e6e7753f8b136b96964e379491bbb5143ccb5b7498768042c740de200b64736f6c634300081b0033
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
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.