Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x4F8B2dd49D958b6ac3e5f4705Bf1a9aDA5Bc4446
Balance 0 ETH
Nonce 1
Code Size 3260 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3260 bytes
0x608060405234801561001057600080fd5b50600436106100e05760003560e01c806379ba50971161008757806379ba5097146102555780638d4e40831461025d578063a230c52414610265578063ac4577711461028b578063c38c581314610293578063ce757d29146102b9578063d6354e15146102d3578063eeb72866146102db576100e0565b80631627540c146100e5578063164636f91461010d5780631785f53c1461013357806324d7806c146101595780632f54bf6e146101935780634bb278f3146101b9578063504f7f6f146101c15780636a93856714610238575b600080fd5b61010b600480360360208110156100fb57600080fd5b50356001600160a01b0316610358565b005b61010b6004803603602081101561012357600080fd5b50356001600160a01b031661040c565b61010b6004803603602081101561014957600080fd5b50356001600160a01b03166105ab565b61017f6004803603602081101561016f57600080fd5b50356001600160a01b031661066e565b604080519115158252519081900360200190f35b61017f600480360360208110156101a957600080fd5b50356001600160a01b031661068c565b61010b6106a0565b61010b600480360360408110156101d757600080fd5b813591908101906040810160208201356401000000008111156101f957600080fd5b82018360208201111561020b57600080fd5b8035906020019184600183028401116401000000008311171561022d57600080fd5b5090925090506106f6565b61017f6004803603602081101561024e57600080fd5b503561093f565b61010b610950565b61017f6109e0565b61017f6004803603602081101561027b57600080fd5b50356001600160a01b03166109e9565b61010b6109fe565b61010b600480360360208110156102a957600080fd5b50356001600160a01b0316610b22565b6102c1610b9d565b60408051918252519081900360200190f35b61017f610ba3565b6102e3610bac565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561031d578181015183820152602001610305565b50505050905090810190601f16801561034a5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103613361068c565b61039f576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b6103a88161068c565b156103ea576040805162461bcd60e51b815260206004820152600d60248201526c20a62922a0a22cafa7aba722a960991b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6104146109e0565b15610452576040805162461bcd60e51b815260206004820152600960248201526811925390531256915160ba1b604482015290519081900360640190fd5b61045b3361066e565b610499576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa0a226a4a760b11b604482015290519081900360640190fd5b6001600160a01b0381166104e5576040805162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa6a2a6a122a960911b604482015290519081900360640190fd5b6001600160a01b03811660009081526007602052604090205460ff1615610544576040805162461bcd60e51b815260206004820152600e60248201526d20a62922a0a22cafa6a2a6a122a960911b604482015290519081900360640190fd5b6001600160a01b038116600081815260076020908152604091829020805460ff19166001908117909155600880549091019055815192835290517fd35a6cc813c47c11ff9f41f7fe9d463b32db9be612b7f78e9ba6336deb4c59009281900390910190a150565b6105b43361068c565b6105f2576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b6105fb8161068c565b1561064d576040805162461bcd60e51b815260206004820181905260248201527f4f574e45525f43414e4e4f545f42455f52454d4f5645445f41535f41444d494e604482015290519081900360640190fd5b6001600160a01b03166000908152600260205260409020805460ff19169055565b6001600160a01b031660009081526002602052604090205460ff1690565b6000546001600160a01b0391821691161490565b6106a93361066e565b6106e7576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa0a226a4a760b11b604482015290519081900360640190fd5b6003805460ff19166001179055565b60065460410281101561073a5760405162461bcd60e51b8152600401808060200182810382526021815260200180610c426021913960400191505060405180910390fd5b60008060005b60065481101561092e57600061078d86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250889250610bcc915050565b905060006107d487878080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050602088019050610bcc565b905060008787876040018181106107e757fe5b9050013560f81c60f81b60f81c9050604186019550600060018a83868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa158015610858573d6000803e3d6000fd5b505060408051601f1901516001600160a01b03811660009081526007602052919091205490925060ff1690506108bf5760405162461bcd60e51b8152600401808060200182810382526024815260200180610c636024913960400191505060405180910390fd5b856001600160a01b0316816001600160a01b03161161091d576040805162461bcd60e51b81526020600482015260156024820152744e4f4e5f534f525445445f5349474e41545552455360581b604482015290519081900360640190fd5b945050600190920191506107409050565b5061093885610bd4565b5050505050565b600061094a82610c07565b92915050565b6001546001600160a01b031633146109a1576040805162461bcd60e51b815260206004820152600f60248201526e4e4f545f415f43414e44494441544560881b604482015290519081900360640190fd5b60018054600080546001600160a01b039092166001600160a01b0319928316811782558152600260205260409020805460ff1916831790558154169055565b60035460ff1690565b60076020526000908152604090205460ff1681565b610a066109e0565b15610a44576040805162461bcd60e51b815260206004820152600960248201526811925390531256915160ba1b604482015290519081900360640190fd5b610a4d3361066e565b610a8b576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa0a226a4a760b11b604482015290519081900360640190fd5b60085460065410610ae3576040805162461bcd60e51b815260206004820152601c60248201527f544f4f5f4d414e595f52455155495245445f5349474e41545552455300000000604482015290519081900360640190fd5b600680546001019081905560408051918252517fb340b320a255ba339d0b9e3f0682e884743efd5ef8f7b2c6601bb227cf3548429181900360200190a1565b610b2b3361068c565b610b69576040805162461bcd60e51b815260206004820152600a60248201526927a7262cafa7aba722a960b11b604482015290519081900360640190fd5b610b728161066e565b610b9a576001600160a01b0381166000908152600260205260409020805460ff191660011790555b50565b60065481565b60055460ff1690565b6060604051806060016040528060258152602001610c1d60259139905090565b016020015190565b6000818152600460205260409020805460ff1916600117905560055460ff16610b9a576005805460ff1916600117905550565b60009081526004602052604090205460ff169056fe537461726b576172655f46696e616c697a61626c65436f6d6d69747465655f323032325f31494e56414c49445f415641494c4142494c4954595f50524f4f465f4c454e475448415641494c4142494c4954595f50524f5645525f4e4f545f494e5f434f4d4d4954544545a264697066735822122051d1745380c4e6a4024ac1702a326ef702e52c031e1c0c7365b70578ba08d72e64736f6c634300060c0033

Verified Source Code Partial Match

Compiler: v0.6.12+commit.27d51765 EVM: istanbul Optimization: Yes (100 runs)
Identity.sol 25 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

interface Identity {
    /*
      Allows a caller, typically another contract,
      to ensure that the provided address is of the expected type and version.
    */
    function identify() external pure returns (string memory);
}
Committee.sol 99 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "FactRegistry.sol";
import "IAvailabilityVerifier.sol";
import "Identity.sol";

contract Committee is FactRegistry, IAvailabilityVerifier, Identity {
    uint256 constant SIGNATURE_LENGTH = 32 * 2 + 1; // r(32) + s(32) +  v(1).
    uint256 public signaturesRequired;
    mapping(address => bool) public isMember;

    /// @dev Contract constructor sets initial members and required number of signatures.
    /// @param committeeMembers List of committee members.
    /// @param numSignaturesRequired Number of required signatures.
    constructor(address[] memory committeeMembers, uint256 numSignaturesRequired) public {
        require(numSignaturesRequired <= committeeMembers.length, "TOO_MANY_REQUIRED_SIGNATURES");
        for (uint256 idx = 0; idx < committeeMembers.length; idx++) {
            require(
                !isMember[committeeMembers[idx]] && (committeeMembers[idx] != address(0)),
                "NON_UNIQUE_COMMITTEE_MEMBERS"
            );
            isMember[committeeMembers[idx]] = true;
        }
        signaturesRequired = numSignaturesRequired;
    }

    function identify() external pure virtual override returns (string memory) {
        return "StarkWare_Committee_2019_1";
    }

    /// @dev Verifies the availability proof. Reverts if invalid.
    /// An availability proof should have a form of a concatenation of ec-signatures by signatories.
    /// Signatures should be sorted by signatory address ascendingly.
    /// Signatures should be 65 bytes long. r(32) + s(32) + v(1).
    /// There should be at least the number of required signatures as defined in this contract
    /// and all signatures provided should be from signatories.
    ///
    /// See :sol:mod:`AvailabilityVerifiers` for more information on when this is used.
    ///
    /// @param claimHash The hash of the claim the committee is signing on.
    /// The format is keccak256(abi.encodePacked(
    ///    newValidiumVaultRoot, validiumTreeHeight, newOrderRoot, orderTreeHeight sequenceNumber))
    /// @param availabilityProofs Concatenated ec signatures by committee members.
    function verifyAvailabilityProof(bytes32 claimHash, bytes calldata availabilityProofs)
        external
        override
    {
        require(
            availabilityProofs.length >= signaturesRequired * SIGNATURE_LENGTH,
            "INVALID_AVAILABILITY_PROOF_LENGTH"
        );

        uint256 offset = 0;
        address prevRecoveredAddress = address(0);
        for (uint256 proofIdx = 0; proofIdx < signaturesRequired; proofIdx++) {
            bytes32 r = bytesToBytes32(availabilityProofs, offset);
            bytes32 s = bytesToBytes32(availabilityProofs, offset + 32);
            uint8 v = uint8(availabilityProofs[offset + 64]);
            offset += SIGNATURE_LENGTH;
            address recovered = ecrecover(claimHash, v, r, s);
            // Signatures should be sorted off-chain before submitting to enable cheap uniqueness
            // check on-chain.
            require(isMember[recovered], "AVAILABILITY_PROVER_NOT_IN_COMMITTEE");
            require(recovered > prevRecoveredAddress, "NON_SORTED_SIGNATURES");
            prevRecoveredAddress = recovered;
        }
        registerFact(claimHash);
    }

    function bytesToBytes32(bytes memory array, uint256 offset)
        private
        pure
        returns (bytes32 result)
    {
        // Arrays are prefixed by a 256 bit length parameter.
        uint256 actualOffset = offset + 32;

        // Read the bytes32 from array memory.
        assembly {
            result := mload(add(array, actualOffset))
        }
    }
}
Finalizable.sol 39 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "SimpleAdminable.sol";

/**
  A simple base class for finalizable contracts.
*/
abstract contract Finalizable is SimpleAdminable {
    bool finalized;

    function isFinalized() public view returns (bool) {
        return finalized;
    }

    modifier notFinalized() {
        require(!isFinalized(), "FINALIZED");
        _;
    }

    function finalize() external onlyAdmin {
        finalized = true;
    }
}
FactRegistry.sol 61 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "IQueryableFactRegistry.sol";

contract FactRegistry is IQueryableFactRegistry {
    // Mapping: fact hash -> true.
    mapping(bytes32 => bool) private verifiedFact;

    // Indicates whether the Fact Registry has at least one fact registered.
    bool anyFactRegistered;

    /*
      Checks if a fact has been verified.
    */
    function isValid(bytes32 fact) external view override returns (bool) {
        return _factCheck(fact);
    }

    /*
      This is an internal method to check if the fact is already registered.
      In current implementation of FactRegistry it's identical to isValid().
      But the check is against the local fact registry,
      So for a derived referral fact registry, it's not the same.
    */
    function _factCheck(bytes32 fact) internal view returns (bool) {
        return verifiedFact[fact];
    }

    function registerFact(bytes32 factHash) internal {
        // This function stores the fact hash in the mapping.
        verifiedFact[factHash] = true;

        // Mark first time off.
        if (!anyFactRegistered) {
            anyFactRegistered = true;
        }
    }

    /*
      Indicates whether at least one fact was registered.
    */
    function hasRegisteredFact() external view override returns (bool) {
        return anyFactRegistered;
    }
}
IFactRegistry.sol 39 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

/*
  The Fact Registry design pattern is a way to separate cryptographic verification from the
  business logic of the contract flow.

  A fact registry holds a hash table of verified "facts" which are represented by a hash of claims
  that the registry hash check and found valid. This table may be queried by accessing the
  isValid() function of the registry with a given hash.

  In addition, each fact registry exposes a registry specific function for submitting new claims
  together with their proofs. The information submitted varies from one registry to the other
  depending of the type of fact requiring verification.

  For further reading on the Fact Registry design pattern see this
  `StarkWare blog post <https://medium.com/starkware/the-fact-registry-a64aafb598b6>`_.
*/
interface IFactRegistry {
    /*
      Returns true if the given fact was previously registered in the contract.
    */
    function isValid(bytes32 fact) external view returns (bool);
}
SimpleAdminable.sol 71 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

abstract contract SimpleAdminable {
    address owner;
    address ownerCandidate;
    mapping(address => bool) admins;

    constructor() internal {
        owner = msg.sender;
        admins[msg.sender] = true;
    }

    // Admin/Owner Modifiers.
    modifier onlyOwner() {
        require(isOwner(msg.sender), "ONLY_OWNER");
        _;
    }

    function isOwner(address testedAddress) public view returns (bool) {
        return owner == testedAddress;
    }

    modifier onlyAdmin() {
        require(isAdmin(msg.sender), "ONLY_ADMIN");
        _;
    }

    function isAdmin(address testedAddress) public view returns (bool) {
        return admins[testedAddress];
    }

    function registerAdmin(address newAdmin) external onlyOwner {
        if (!isAdmin(newAdmin)) {
            admins[newAdmin] = true;
        }
    }

    function removeAdmin(address removedAdmin) external onlyOwner {
        require(!isOwner(removedAdmin), "OWNER_CANNOT_BE_REMOVED_AS_ADMIN");
        delete admins[removedAdmin];
    }

    function nominateNewOwner(address newOwner) external onlyOwner {
        require(!isOwner(newOwner), "ALREADY_OWNER");
        ownerCandidate = newOwner;
    }

    function acceptOwnership() external {
        // Previous owner is still an admin.
        require(msg.sender == ownerCandidate, "NOT_A_CANDIDATE");
        owner = ownerCandidate;
        admins[ownerCandidate] = true;
        ownerCandidate = address(0x0);
    }
}
FinalizableCommittee.sol 56 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "Finalizable.sol";
import "Committee.sol";

/**
  A finalizable version of Committee.
  Until finalized, it allows adding new members and incrementing the number of required signers.
*/
contract FinalizableCommittee is Finalizable, Committee {
    event RequiredSignersIncrement(uint256 newRequiredSigners);
    event NewMemberAdded(address newMember);

    uint256 private _memberCount;

    constructor(address[] memory committeeMembers, uint256 numSignaturesRequired)
        public
        Committee(committeeMembers, numSignaturesRequired)
    {
        _memberCount = committeeMembers.length;
    }

    function incrementRequiredSigners() external notFinalized onlyAdmin {
        require(signaturesRequired < _memberCount, "TOO_MANY_REQUIRED_SIGNATURES");
        signaturesRequired += 1;
        emit RequiredSignersIncrement(signaturesRequired);
    }

    function addCommitteeMemeber(address newMember) external notFinalized onlyAdmin {
        require(newMember != address(0x0), "INVALID_MEMBER");
        require(!isMember[newMember], "ALREADY_MEMBER");
        isMember[newMember] = true;
        _memberCount += 1;
        emit NewMemberAdded(newMember);
    }

    function identify() external pure override returns (string memory) {
        return "StarkWare_FinalizableCommittee_2022_1";
    }
}
IAvailabilityVerifier.sol 24 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

interface IAvailabilityVerifier {
    /*
      Verifies the availability proof. Reverts if invalid.
    */
    function verifyAvailabilityProof(bytes32 claimHash, bytes calldata availabilityProofs) external;
}
IQueryableFactRegistry.sol 30 lines
/*
  Copyright 2019-2022 StarkWare Industries Ltd.

  Licensed under the Apache License, Version 2.0 (the "License").
  You may not use this file except in compliance with the License.
  You may obtain a copy of the License at

  https://www.starkware.co/open-source-license/

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions
  and limitations under the License.
*/
// SPDX-License-Identifier: Apache-2.0.
pragma solidity ^0.6.12;

import "IFactRegistry.sol";

/*
  Extends the IFactRegistry interface with a query method that indicates
  whether the fact registry has successfully registered any fact or is still empty of such facts.
*/
interface IQueryableFactRegistry is IFactRegistry {
    /*
      Returns true if at least one fact has been registered.
    */
    function hasRegisteredFact() external view returns (bool);
}

Read Contract

hasRegisteredFact 0xd6354e15 → bool
identify 0xeeb72866 → string
isAdmin 0x24d7806c → bool
isFinalized 0x8d4e4083 → bool
isMember 0xa230c524 → bool
isOwner 0x2f54bf6e → bool
isValid 0x6a938567 → bool
signaturesRequired 0xce757d29 → uint256

Write Contract 8 functions

These functions modify contract state and require a wallet transaction to execute.

acceptOwnership 0x79ba5097
No parameters
addCommitteeMemeber 0x164636f9
address newMember
finalize 0x4bb278f3
No parameters
incrementRequiredSigners 0xac457771
No parameters
nominateNewOwner 0x1627540c
address newOwner
registerAdmin 0xc38c5813
address newAdmin
removeAdmin 0x1785f53c
address removedAdmin
verifyAvailabilityProof 0x504f7f6f
bytes32 claimHash
bytes availabilityProofs

Recent Transactions

No transactions found for this address