, Twitter/Github: @mudgen
-* EIP-2535 Diamonds
-/******************************************************************************/
-
-// NOTE:
-// To see the various things in this file in their proper directory structure
-// please download the zip archive version of this reference implementation.
-// The zip archive also includes a deployment script and tests.
-
-interface IDiamond {
- enum FacetCutAction {Add, Replace, Remove}
- // Add=0, Replace=1, Remove=2
-
- struct FacetCut {
- address facetAddress;
- FacetCutAction action;
- bytes4[] functionSelectors;
- }
-
- event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
-}
-
-interface IDiamondCut is IDiamond {
- /// @notice Add/replace/remove any number of functions and optionally execute
- /// a function with delegatecall
- /// @param _diamondCut Contains the facet addresses and function selectors
- /// @param _init The address of the contract or facet to execute _calldata
- /// @param _calldata A function call, including function selector and arguments
- /// _calldata is executed with delegatecall on _init
- function diamondCut(
- FacetCut[] calldata _diamondCut,
- address _init,
- bytes calldata _calldata
- ) external;
-}
-
-///////////////////////////////////////////////
-// LibDiamond
-// LibDiamond defines the diamond storage that is used by this reference
-// implementation.
-// LibDiamond contains internal functions and no external functions.
-// LibDiamond internal functions are used by DiamondCutFacet,
-// DiamondLoupeFacet and the diamond proxy contract (the Diamond contract).
-
-error NoSelectorsGivenToAdd();
-error NotContractOwner(address _user, address _contractOwner);
-error NoSelectorsProvidedForFacetForCut(address _facetAddress);
-error CannotAddSelectorsToZeroAddress(bytes4[] _selectors);
-error NoBytecodeAtAddress(address _contractAddress, string _message);
-error IncorrectFacetCutAction(uint8 _action);
-error CannotAddFunctionToDiamondThatAlreadyExists(bytes4 _selector);
-error CannotReplaceFunctionsFromFacetWithZeroAddress(bytes4[] _selectors);
-error CannotReplaceImmutableFunction(bytes4 _selector);
-error CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(bytes4 _selector);
-error CannotReplaceFunctionThatDoesNotExists(bytes4 _selector);
-error RemoveFacetAddressMustBeZeroAddress(address _facetAddress);
-error CannotRemoveFunctionThatDoesNotExist(bytes4 _selector);
-error CannotRemoveImmutableFunction(bytes4 _selector);
-error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);
-
-library LibDiamond {
- bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage");
-
- struct FacetAddressAndSelectorPosition {
- address facetAddress;
- uint16 selectorPosition;
- }
-
- struct DiamondStorage {
- // function selector => facet address and selector position in selectors array
- mapping(bytes4 => FacetAddressAndSelectorPosition) facetAddressAndSelectorPosition;
- bytes4[] selectors;
- mapping(bytes4 => bool) supportedInterfaces;
- // owner of the contract
- address contractOwner;
- }
-
- function diamondStorage() internal pure returns (DiamondStorage storage ds) {
- bytes32 position = DIAMOND_STORAGE_POSITION;
- assembly {
- ds.slot := position
- }
- }
-
- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
-
- function setContractOwner(address _newOwner) internal {
- DiamondStorage storage ds = diamondStorage();
- address previousOwner = ds.contractOwner;
- ds.contractOwner = _newOwner;
- emit OwnershipTransferred(previousOwner, _newOwner);
- }
-
- function contractOwner() internal view returns (address contractOwner_) {
- contractOwner_ = diamondStorage().contractOwner;
- }
-
- function enforceIsContractOwner() internal view {
- if(msg.sender != diamondStorage().contractOwner) {
- revert NotContractOwner(msg.sender, diamondStorage().contractOwner);
- }
- }
-
- event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata);
-
- // Internal function version of diamondCut
- function diamondCut(
- IDiamondCut.FacetCut[] memory _diamondCut,
- address _init,
- bytes memory _calldata
- ) internal {
- for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
- bytes4[] memory functionSelectors = _diamondCut[facetIndex].functionSelectors;
- address facetAddress = _diamondCut[facetIndex].facetAddress;
- if(functionSelectors.length == 0) {
- revert NoSelectorsProvidedForFacetForCut(facetAddress);
- }
- IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
- if (action == IDiamond.FacetCutAction.Add) {
- addFunctions(facetAddress, functionSelectors);
- } else if (action == IDiamond.FacetCutAction.Replace) {
- replaceFunctions(facetAddress, functionSelectors);
- } else if (action == IDiamond.FacetCutAction.Remove) {
- removeFunctions(facetAddress, functionSelectors);
- } else {
- revert IncorrectFacetCutAction(uint8(action));
- }
- }
- emit DiamondCut(_diamondCut, _init, _calldata);
- initializeDiamondCut(_init, _calldata);
- }
-
- function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
- if(_facetAddress == address(0)) {
- revert CannotAddSelectorsToZeroAddress(_functionSelectors);
- }
- DiamondStorage storage ds = diamondStorage();
- uint16 selectorCount = uint16(ds.selectors.length);
- enforceHasContractCode(_facetAddress, "LibDiamondCut: Add facet has no code");
- for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
- bytes4 selector = _functionSelectors[selectorIndex];
- address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress;
- if(oldFacetAddress != address(0)) {
- revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
- }
- ds.facetAddressAndSelectorPosition[selector] = FacetAddressAndSelectorPosition(_facetAddress, selectorCount);
- ds.selectors.push(selector);
- selectorCount++;
- }
- }
-
- function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
- DiamondStorage storage ds = diamondStorage();
- if(_facetAddress == address(0)) {
- revert CannotReplaceFunctionsFromFacetWithZeroAddress(_functionSelectors);
- }
- enforceHasContractCode(_facetAddress, "LibDiamondCut: Replace facet has no code");
- for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
- bytes4 selector = _functionSelectors[selectorIndex];
- address oldFacetAddress = ds.facetAddressAndSelectorPosition[selector].facetAddress;
- // can't replace immutable functions -- functions defined directly in the diamond in this case
- if(oldFacetAddress == address(this)) {
- revert CannotReplaceImmutableFunction(selector);
- }
- if(oldFacetAddress == _facetAddress) {
- revert CannotReplaceFunctionWithTheSameFunctionFromTheSameFacet(selector);
- }
- if(oldFacetAddress == address(0)) {
- revert CannotReplaceFunctionThatDoesNotExists(selector);
- }
- // replace old facet address
- ds.facetAddressAndSelectorPosition[selector].facetAddress = _facetAddress;
- }
- }
-
- function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
- DiamondStorage storage ds = diamondStorage();
- uint256 selectorCount = ds.selectors.length;
- if(_facetAddress != address(0)) {
- revert RemoveFacetAddressMustBeZeroAddress(_facetAddress);
- }
- for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
- bytes4 selector = _functionSelectors[selectorIndex];
- FacetAddressAndSelectorPosition memory oldFacetAddressAndSelectorPosition = ds.facetAddressAndSelectorPosition[selector];
- if(oldFacetAddressAndSelectorPosition.facetAddress == address(0)) {
- revert CannotRemoveFunctionThatDoesNotExist(selector);
- }
-
-
- // can't remove immutable functions -- functions defined directly in the diamond
- if(oldFacetAddressAndSelectorPosition.facetAddress == address(this)) {
- revert CannotRemoveImmutableFunction(selector);
- }
- // replace selector with last selector
- selectorCount--;
- if (oldFacetAddressAndSelectorPosition.selectorPosition != selectorCount) {
- bytes4 lastSelector = ds.selectors[selectorCount];
- ds.selectors[oldFacetAddressAndSelectorPosition.selectorPosition] = lastSelector;
- ds.facetAddressAndSelectorPosition[lastSelector].selectorPosition = oldFacetAddressAndSelectorPosition.selectorPosition;
- }
- // delete last selector
- ds.selectors.pop();
- delete ds.facetAddressAndSelectorPosition[selector];
- }
- }
-
- function initializeDiamondCut(address _init, bytes memory _calldata) internal {
- if (_init == address(0)) {
- return;
- }
- enforceHasContractCode(_init, "LibDiamondCut: _init address has no code");
- (bool success, bytes memory error) = _init.delegatecall(_calldata);
- if (!success) {
- if (error.length > 0) {
- // bubble up error
- /// @solidity memory-safe-assembly
- assembly {
- let returndata_size := mload(error)
- revert(add(32, error), returndata_size)
- }
- } else {
- revert InitializationFunctionReverted(_init, _calldata);
- }
- }
- }
-
- function enforceHasContractCode(address _contract, string memory _errorMessage) internal view {
- uint256 contractSize;
- assembly {
- contractSize := extcodesize(_contract)
- }
- if(contractSize == 0) {
- revert NoBytecodeAtAddress(_contract, _errorMessage);
- }
- }
-}
-
-///////////////////////////////////////////////
-// These facets are added to the diamond.
-///////////////////////////////////////////////
-
-contract DiamondCutFacet is IDiamondCut {
- /// @notice Add/replace/remove any number of functions and optionally execute
- /// a function with delegatecall
- /// @param _diamondCut Contains the facet addresses and function selectors
- /// @param _init The address of the contract or facet to execute _calldata
- /// @param _calldata A function call, including function selector and arguments
- /// _calldata is executed with delegatecall on _init
- function diamondCut(
- FacetCut[] calldata _diamondCut,
- address _init,
- bytes calldata _calldata
- ) external override {
- LibDiamond.enforceIsContractOwner();
- LibDiamond.diamondCut(_diamondCut, _init, _calldata);
- }
-}
-
-// The functions in DiamondLoupeFacet MUST be added to a diamond.
-// The EIP-2535 Diamond standard requires these functions.
-
-interface IERC165 {
- /// @notice Query if a contract implements an interface
- /// @param interfaceId The interface identifier, as specified in ERC-165
- /// @dev Interface identification is specified in ERC-165. This function
- /// uses less than 30,000 gas.
- /// @return `true` if the contract implements `interfaceID` and
- /// `interfaceID` is not 0xffffffff, `false` otherwise
- function supportsInterface(bytes4 interfaceId) external view returns (bool);
-}
-
-// A loupe is a small magnifying glass used to look at diamonds.
-// These functions look at diamonds
-interface IDiamondLoupe {
- /// These functions are expected to be called frequently
- /// by tools.
-
- struct Facet {
- address facetAddress;
- bytes4[] functionSelectors;
- }
-
- /// @notice Gets all facet addresses and their four byte function selectors.
- /// @return facets_ Facet
- function facets() external view returns (Facet[] memory facets_);
-
- /// @notice Gets all the function selectors supported by a specific facet.
- /// @param _facet The facet address.
- /// @return facetFunctionSelectors_
- function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);
-
- /// @notice Get all the facet addresses used by a diamond.
- /// @return facetAddresses_
- function facetAddresses() external view returns (address[] memory facetAddresses_);
-
- /// @notice Gets the facet that supports the given selector.
- /// @dev If facet is not found return address(0).
- /// @param _functionSelector The function selector.
- /// @return facetAddress_ The facet address.
- function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
-}
-
-contract DiamondLoupeFacet is IDiamondLoupe, IERC165 {
- // Diamond Loupe Functions
- ////////////////////////////////////////////////////////////////////
- /// These functions are expected to be called frequently by tools.
- //
- // struct Facet {
- // address facetAddress;
- // bytes4[] functionSelectors;
- // }
- /// @notice Gets all facets and their selectors.
- /// @return facets_ Facet
- function facets() external override view returns (Facet[] memory facets_) {
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- uint256 selectorCount = ds.selectors.length;
- // create an array set to the maximum size possible
- facets_ = new Facet[](selectorCount);
- // create an array for counting the number of selectors for each facet
- uint16[] memory numFacetSelectors = new uint16[](selectorCount);
- // total number of facets
- uint256 numFacets;
- // loop through function selectors
- for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
- bytes4 selector = ds.selectors[selectorIndex];
- address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;
- bool continueLoop = false;
- // find the functionSelectors array for selector and add selector to it
- for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
- if (facets_[facetIndex].facetAddress == facetAddress_) {
- facets_[facetIndex].functionSelectors[numFacetSelectors[facetIndex]] = selector;
- numFacetSelectors[facetIndex]++;
- continueLoop = true;
- break;
- }
- }
- // if functionSelectors array exists for selector then continue loop
- if (continueLoop) {
- continueLoop = false;
- continue;
- }
- // create a new functionSelectors array for selector
- facets_[numFacets].facetAddress = facetAddress_;
- facets_[numFacets].functionSelectors = new bytes4[](selectorCount);
- facets_[numFacets].functionSelectors[0] = selector;
- numFacetSelectors[numFacets] = 1;
- numFacets++;
- }
- for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
- uint256 numSelectors = numFacetSelectors[facetIndex];
- bytes4[] memory selectors = facets_[facetIndex].functionSelectors;
- // setting the number of selectors
- assembly {
- mstore(selectors, numSelectors)
- }
- }
- // setting the number of facets
- assembly {
- mstore(facets_, numFacets)
- }
- }
-
- /// @notice Gets all the function selectors supported by a specific facet.
- /// @param _facet The facet address.
- /// @return _facetFunctionSelectors The selectors associated with a facet address.
- function facetFunctionSelectors(address _facet) external override view returns (bytes4[] memory _facetFunctionSelectors) {
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- uint256 selectorCount = ds.selectors.length;
- uint256 numSelectors;
- _facetFunctionSelectors = new bytes4[](selectorCount);
- // loop through function selectors
- for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
- bytes4 selector = ds.selectors[selectorIndex];
- address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;
- if (_facet == facetAddress_) {
- _facetFunctionSelectors[numSelectors] = selector;
- numSelectors++;
- }
- }
- // Set the number of selectors in the array
- assembly {
- mstore(_facetFunctionSelectors, numSelectors)
- }
- }
-
- /// @notice Get all the facet addresses used by a diamond.
- /// @return facetAddresses_
- function facetAddresses() external override view returns (address[] memory facetAddresses_) {
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- uint256 selectorCount = ds.selectors.length;
- // create an array set to the maximum size possible
- facetAddresses_ = new address[](selectorCount);
- uint256 numFacets;
- // loop through function selectors
- for (uint256 selectorIndex; selectorIndex < selectorCount; selectorIndex++) {
- bytes4 selector = ds.selectors[selectorIndex];
- address facetAddress_ = ds.facetAddressAndSelectorPosition[selector].facetAddress;
- bool continueLoop = false;
- // see if we have collected the address already and break out of loop if we have
- for (uint256 facetIndex; facetIndex < numFacets; facetIndex++) {
- if (facetAddress_ == facetAddresses_[facetIndex]) {
- continueLoop = true;
- break;
- }
- }
- // continue loop if we already have the address
- if (continueLoop) {
- continueLoop = false;
- continue;
- }
- // include address
- facetAddresses_[numFacets] = facetAddress_;
- numFacets++;
- }
- // Set the number of facet addresses in the array
- assembly {
- mstore(facetAddresses_, numFacets)
- }
- }
-
- /// @notice Gets the facet address that supports the given selector.
- /// @dev If facet is not found return address(0).
- /// @param _functionSelector The function selector.
- /// @return facetAddress_ The facet address.
- function facetAddress(bytes4 _functionSelector) external override view returns (address facetAddress_) {
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- facetAddress_ = ds.facetAddressAndSelectorPosition[_functionSelector].facetAddress;
- }
-
- // This implements ERC-165.
- function supportsInterface(bytes4 _interfaceId) external override view returns (bool) {
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- return ds.supportedInterfaces[_interfaceId];
- }
-}
-
-/// @title ERC-173 Contract Ownership Standard
-/// Note: the ERC-165 identifier for this interface is 0x7f5828d0
-/* is ERC165 */
-interface IERC173 {
- /// @dev This emits when ownership of a contract changes.
- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
-
- /// @notice Get the address of the owner
- /// @return owner_ The address of the owner.
- function owner() external view returns (address owner_);
-
- /// @notice Set the address of the new owner of the contract
- /// @dev Set _newOwner to address(0) to renounce any ownership.
- /// @param _newOwner The address of the new owner of the contract
- function transferOwnership(address _newOwner) external;
-}
-
-contract OwnershipFacet is IERC173 {
- function transferOwnership(address _newOwner) external override {
- LibDiamond.enforceIsContractOwner();
- LibDiamond.setContractOwner(_newOwner);
- }
-
- function owner() external override view returns (address owner_) {
- owner_ = LibDiamond.contractOwner();
- }
-}
-///////////////////////////////////////////////
-
-///////////////////////////////////////////////
-// DiamondInit
-// This contract and function are used to initialize state variables and/or do other actions
-// when the `diamondCut` function is called.
-// It is expected that this contract is customized if you want to deploy your diamond
-// with data from a deployment script. Use the init function to initialize state variables
-// of your diamond. Add parameters to the init funciton if you need to.
-// DiamondInit can be used during deployment or for upgrades.
-
-// Adding parameters to the `init` or other functions you add here can make a single deployed
-// DiamondInit contract reusable accross upgrades, and can be used for multiple diamonds.
-
-contract DiamondInit {
-
- // You can add parameters to this function in order to pass in
- // data to set your own state variables
- function init() external {
- // adding ERC165 data
- LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
- ds.supportedInterfaces[type(IERC165).interfaceId] = true;
- ds.supportedInterfaces[type(IDiamondCut).interfaceId] = true;
- ds.supportedInterfaces[type(IDiamondLoupe).interfaceId] = true;
- ds.supportedInterfaces[type(IERC173).interfaceId] = true;
-
- // add your own state variables
- // EIP-2535 specifies that the `diamondCut` function takes two optional
- // arguments: address _init and bytes calldata _calldata
- // These arguments are used to execute an arbitrary function using delegatecall
- // in order to set state variables in the diamond during deployment or an upgrade
- // More info in the EIP2535 Diamonds standard.
- }
-}
-
-///////////////////////////////////////////////
-// DiamondMultiInit
-// This version of DiamondInit can be used to execute multiple initialization functions.
-// It is expected that this contract is customized if you want to deploy or upgrade your diamond with it.
-
-error AddressAndCalldataLengthDoNotMatch(uint256 _addressesLength, uint256 _calldataLength);
-
-contract DiamondMultiInit {
-
- // This function is provided in the third parameter of the `diamondCut` function.
- // The `diamondCut` function executes this function to execute multiple initializer functions for a single upgrade.
-
- function multiInit(address[] calldata _addresses, bytes[] calldata _calldata) external {
- if(_addresses.length != _calldata.length) {
- revert AddressAndCalldataLengthDoNotMatch(_addresses.length, _calldata.length);
- }
- for(uint i; i < _addresses.length; i++) {
- LibDiamond.initializeDiamondCut(_addresses[i], _calldata[i]);
- }
- }
-}
-
-
-///////////////////////////////////////////////
-// Diamond
-// The diamond proxy contract.
-
-
-// When no function exists for function called
-error FunctionNotFound(bytes4 _functionSelector);
-
-// This is used in diamond constructor
-// more arguments are added to this struct
-// this avoids stack too deep errors
-struct DiamondArgs {
- address owner;
- address init;
- bytes initCalldata;
-}
-
-contract Diamond {
-
- // Remember to add the loupe functions from DiamondLoupeFacet to the diamond.
- // The loupe functions are required by the EIP2535 Diamonds standard
-
- constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable {
- LibDiamond.setContractOwner(_args.owner);
- LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata);
-
- // Code can be added here to perform actions and set state variables.
- }
-
- // Find facet for function that is called and execute the
- // function if a facet is found and return any value.
- fallback() external payable {
- LibDiamond.DiamondStorage storage ds;
- bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
- // get diamond storage
- assembly {
- ds.slot := position
- }
- // get facet from function selector
- address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress;
- if(facet == address(0)) {
- revert FunctionNotFound(msg.sig);
- }
- // Execute external function from facet using delegatecall and return any value.
- assembly {
- // copy function selector and any arguments
- calldatacopy(0, 0, calldatasize())
- // execute function call using the facet
- let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
- // get any return value
- returndatacopy(0, 0, returndatasize())
- // return any return value or error back to the caller
- switch result
- case 0 {
- revert(0, returndatasize())
- }
- default {
- return(0, returndatasize())
- }
- }
- }
-
- receive() external payable {}
-}
diff --git a/assets/eip-2535/reference/EIP2535-Diamonds-Reference-Implementation.zip b/assets/eip-2535/reference/EIP2535-Diamonds-Reference-Implementation.zip
deleted file mode 100644
index 9be228e..0000000
Binary files a/assets/eip-2535/reference/EIP2535-Diamonds-Reference-Implementation.zip and /dev/null differ
diff --git a/assets/eip-2535/storage-examples/AppStorage.sol b/assets/eip-2535/storage-examples/AppStorage.sol
deleted file mode 100644
index 69ca46e..0000000
--- a/assets/eip-2535/storage-examples/AppStorage.sol
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-// Diamond Storage is particularly good for isolating or compartmenting state variables to specific
-// facets or functionality. This is great for creating modular facets that can be understood as their
-// own units and be added to diamonds. A diamond with a lot of functionality is well organized and
-// understandable if each of its facets can be understood in isolation. Diamond Storage helps make that
-// possible.
-
-// However, you may want to share state variables specific to your application with facets that are specific
-// to your application. It can get somewhat tedious to call a `diamondStorage()` function in every function
-// that you want to access state variables.
-
-// `AppStorage` is a specialized version of Diamond Storage. It is a more convenient way to access
-// application specific state variables that are shared among facets.
-
-// The pattern works in the following way:
-
-// 1. Define a struct called AppStorage that contains all the state variables specific to your application
-// and that you plan to share with different facets. Store AppStorage in a file. Any of your facets can
-// now import this file to access the state variables.
-
-struct AppStorage {
- uint256 secondVar;
- uint256 firstVar;
- uint256 lastVar;
- // add other state variables ...
-}
-
-
-// 2. In a facet that imports the AppStorage struct declare an AppStorage state variable called `s`.
-// This should be the only state variable declared in the facet.
-
-// 3. In your facet you can now access all the state variables in AppStorage by prepending state variables
-// with `s.`. Here is example code:
-
-
-// import { AppStorage } from "./LibAppStorage.sol";
-
-contract AFacet {
- AppStorage internal s;
-
- function sumVariables() external {
- s.lastVar = s.firstVar + s.secondVar;
- }
-
- function getFirsVar() external view returns (uint256) {
- return s.firstVar;
- }
-
- function setLastVar(uint256 _newValue) external {
- s.lastVar = _newValue;
- }
-}
-
-// Sharing AppStorage in another facet:
-
-// import { AppStorage } from "./LibAppStorage.sol";
-
-contract SomeOtherFacet {
- AppStorage internal s;
-
- function getLargerVar() external view returns (uint256) {
- uint256 firstVar = s.firstVar;
- uint256 secondVar = s.secondVar;
- if(firstVar > secondVar) {
- return firstVar;
- }
- else {
- return secondVar;
- }
- }
-}
-
-// Using the 's.' prefix to access AppStorage is a nice convention because it makes state variables
-// concise, easy to access, and it distinguishes state variables from local variables and prevents
-// name clashes/shadowing with local variables and function names. It helps identify and make
-// explicit state variables in a convenient and concise way. AppStorage can be used in regualar
-// contracts as well as proxy contracts, diamonds, implementation contracts, Solidity libraries and
-// facets.
-
-// Since `AppStorage s` is the first and only state variable declared in facets its position in
-// contract storage is `0`. This fact can be used to access AppStorage in Solidity libraries using
-// diamond storage access. Here's an example of that:
-
-library LibAppStorage {
- function appStorage() internal pure returns (AppStorage storage ds) {
- assembly { ds.slot := 0 }
- }
-
- function someFunction() internal {
- AppStorage storage s = appStorage();
- s.firstVar = 8;
- //... do more stuff
- }
-}
-
-// `AppStorage s` can be declared as the one and only state variable in facets or it can be declared in a
-// contract that facets inherit.
-
-// AppStorage won't work if state variables are declared outside of AppStorage and outside of Diamond Storage.
-// It is a common error for a facet to inherit a contract that declares state variables outside AppStorage and
-// Diamond Storage. This causes a misalignment of state variables.
-
-// One downside is that state variables can't be declared public in structs so getter functions can't
-// automatically be created this way. But it can be nice to make your own getter functions for
-// state variables because it is explicit.
-
-// The rules for upgrading AppStorage are the same for Diamond Storage. These rules can be found at
-// the end of the file ./DiamondStorage.sol
\ No newline at end of file
diff --git a/assets/eip-2535/storage-examples/DiamondStorage.sol b/assets/eip-2535/storage-examples/DiamondStorage.sol
deleted file mode 100644
index b6fe022..0000000
--- a/assets/eip-2535/storage-examples/DiamondStorage.sol
+++ /dev/null
@@ -1,156 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-// Diamond storage is a contract storage strategy that is used in proxy contracts and diamonds.
-
-// It greatly simplifies organizing and using state variables in proxy contracts and diamonds.
-
-// Diamond storage relies on Solidity structs that contain sets of state variables.
-
-// A struct can be defined with state variables and then used in a particular position in contract
-// storage. The position can be determined by a hash of a unique string or other data. The string
-// acts like a namespace for the struct. For example a diamond storage string for a struct could
-// be 'com.mycompany.projectx.mystruct'. That will look familiar to you if you have used programming
-// languages that use namespaces.
-
-// Namespaces are used in some programming languages to package data and code together as separate
-// reusable units. Diamond storage packages sets of state variables as separate, reusable data units
-// in contract storage.
-
-// Let's look at a simple example of diamond storage:
-
-library LibERC721 {
- bytes32 constant ERC721_POSITION = keccak256("erc721.storage");
-
- // Instead of using a hash of a string other schemes can be used to create positions in contract storage.
- // Here is a scheme that could be used:
- //
- // bytes32 constant ERC721_POSITION =
- // keccak256(abi.encodePacked(
- // ERC721.interfaceId,
- // ERC721.name
- // ));
-
- struct ERC721Storage {
- // tokenId => owner
- mapping (uint256 => address) tokenIdToOwner;
- // owner => count of tokens owned
- mapping (address => uint256) ownerToNFTokenCount;
-
- string name;
- string symbol;
- }
-
- // Return ERC721 storage struct for reading and writing
- function getStorage() internal pure returns (ERC721Storage storage storageStruct) {
- bytes32 position = ERC721_POSITION;
- assembly {
- storageStruct.slot := position
- }
- }
-
- event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
-
- // This is a very simplified implementation.
- // It does not include all necessary validation of input.
- // It is used to show diamond storage.
- function transferFrom(address _from, address _to, uint256 _tokenId) internal {
- ERC721Storage storage erc721Storage = LibERC721.getStorage();
- address tokenOwner = erc721Storage.tokenIdToOwner[_tokenId];
- require(tokenOwner == _from);
- erc721Storage.tokenIdToOwner[_tokenId] = _to;
- erc721Storage.ownerToNFTokenCount[_from]--;
- erc721Storage.ownerToNFTokenCount[_to]++;
- emit Transfer(_from, _to, _tokenId);
- }
-}
-
-// Note that this is not a full or correct ERC721 implementation.
-// This is an example of using diamond storage.
-
-// Note that the ERC721.name and ERC721.symbol storage variables would probably be set
-// in an `init` function at deployment time or during an upgrade.
-
-
-// Shows use of LibERC721 and diamond storage
-contract ERC721Facet {
-
- function name() external view returns (string memory name_) {
- name_ = LibERC721.getStorage().name;
- }
-
- function symbol() external view returns (string memory symbol_) {
- symbol_ = LibERC721.getStorage().symbol;
- }
-
- function transferFrom(address _from, address _to, uint256 _tokenId) external {
- LibERC721.transferFrom(_from, _to, _tokenId);
- }
-
-}
-
-// Here we show how we can share state variables and internal functions between facets by
-// using Solidity libraries. Sharing internal functions between facets can also be done by
-// inheriting contracts that contain internal functions.
-contract ERC721BatchTransferFacet {
-
- function batchTransferFrom(address _from, address _to, uint256[] calldata _tokenIds) external {
- for(uint256 i; i < _tokenIds.length; i++) {
- LibERC721.transferFrom(_from, _to, _tokenIds[i]);
- }
- }
-}
-
-// HOW TO UPGRADE DIAMOND STORAGE
-//--------------------------------------------
-
-// It is important not to corrupt state variables during an upgrade. It is easy to handle state
-// variables correctly in upgrades.
-
-// Here's some things that can be done:
-
-// 1. To add new state variables to an AppStorage struct or a Diamond Storage struct, add them
-// to the end of the struct.
-
-// 2. New state variables can be added to the ends of structs that are stored in mappings.
-
-// 3. The names of state variables can be changed, but that might be confusing if different
-// facets are using different names for the same storage locations.
-
-// Do not do the following:
-
-// 1. If you are using AppStorage then do not declare and use state variables outside the
-// AppStorage struct. Except Diamond Storage can be used. Diamond Storage and AppStorage
-// can be used together.
-
-// 2. Do not add new state variables to the beginning or middle of structs. Doing this
-// makes the new state variable overwrite existing state variable data and all state
-// variables after the new state variable reference the wrong storage location.
-
-// 3. Do not put structs directly in structs unless you don’t plan on ever adding more state
-// variables to the inner structs. You won't be able to add new state variables to inner
-// structs in upgrades.
-
-// 4. Do not add new state variables to structs that are used in arrays.
-
-// 5. When using Diamond Storage do not use the same namespace string for different structs.
-// This is obvious. Two different structs at the same location will overwrite each other.
-
-// 6. Do not allow any facet to be able to call `selfdestruct`. This is easy. Simply don’t
-// allow the `selfdestruct` command to exist in any facet source code and don’t allow
-// that command to be called via a delegatecall. Because `selfdestruct` could delete a
-// facet that is used by a diamond, or `selfdestruct` could be used to delete a diamond
-// proxy contract.
-
-// A trick to use inner structs and still enable them to be extended is to put them in mappings.
-// A struct stored in a mapping can be extended in upgrades. You could use a value like 0 defined
-// with a constant like INNER_STRUCT. Put your structs in mappings and then access them with the
-// INNER_STRUCT constant. Example: MyStruct storage mystruct = storage.mystruct[INNER_STRUCT];
-
-// Note that any Solidity data type can be used in Diamond Storage or AppStorage structs. It is
-// just that structs directly in structs and structs that are used in arrays can’t be extended
-// with more state variables in the future. That could be fine in some cases.
-
-// These rules will make sense if you understand how Solidity assigns storage locations to state
-// variables. I recommend reading and understanding this section of the Solidity documentation:
-// 'Layout of State Variables in Storage'
diff --git a/assets/eip-2537/bench_vectors.md b/assets/eip-2537/bench_vectors.md
deleted file mode 100644
index 2d4a0c0..0000000
--- a/assets/eip-2537/bench_vectors.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Set of test vectors to perform benchmarking of EIP-2537
-
-## Inlined vectors
-
-Here one can find inputs (encoded with ABI from the main spec spec) that can be considered "worst cases" for "double-and-add" multiplication algorithm, and also some cases for pairing call. Those are purely for convenience of initial benchmarking of the full ABI without manual test generation.
-
-```
-G1 addition example input =
-0000000000000000000000000000000012196c5a43d69224d8713389285f26b98f86ee910ab3dd668e413738282003cc5b7357af9a7af54bb713d62255e80f560000000000000000000000000000000006ba8102bfbeea4416b710c73e8cce3032c31c6269c44906f8ac4f7874ce99fb17559992486528963884ce429a992fee000000000000000000000000000000000001101098f5c39893765766af4512a0c74e1bb89bc7e6fdf14e3e7337d257cc0f94658179d83320b99f31ff94cd2bac0000000000000000000000000000000003e1a9f9f44ca2cdab4f43a1a3ee3470fdf90b2fc228eb3b709fcd72f014838ac82a6d797aeefed9a0804b22ed1ce8f7
-G2 addition example input =
-0000000000000000000000000000000018c0ada6351b70661f053365deae56910798bd2ace6e2bf6ba4192d1a229967f6af6ca1c9a8a11ebc0a232344ee0f6d6000000000000000000000000000000000cc70a587f4652039d8117b6103858adcd9728f6aebe230578389a62da0042b7623b1c0436734f463cfdd187d20903240000000000000000000000000000000009f50bd7beedb23328818f9ffdafdb6da6a4dd80c5a9048ab8b154df3cad938ccede829f1156f769d9e149791e8e0cd900000000000000000000000000000000079ba50d2511631b20b6d6f3841e616e9d11b68ec3368cd60129d9d4787ab56c4e9145a38927e51c9cd6271d493d938800000000000000000000000000000000192fa5d8732ff9f38e0b1cf12eadfd2608f0c7a39aced7746837833ae253bb57ef9c0d98a4b69eeb2950901917e99d1e0000000000000000000000000000000009aeb10c372b5ef1010675c6a4762fda33636489c23b581c75220589afbc0cc46249f921eea02dd1b761e036ffdbae220000000000000000000000000000000002d225447600d49f932b9dd3ca1e6959697aa603e74d8666681a2dca8160c3857668ae074440366619eb8920256c4e4a00000000000000000000000000000000174882cdd3551e0ce6178861ff83e195fecbcffd53a67b6f10b4431e423e28a480327febe70276036f60bb9c99cf7633
-G1 mul double and add worst case =
-0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-G2 mul double and add worst case =
-00000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79beffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-Pairing case for 2 pairs =
-0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be
-Pairing case for 4 pairs =
-0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be
-Pairing case for 6 pairs =
-0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb80000000000000000000000000000000013e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e000000000000000000000000000000000ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801000000000000000000000000000000000606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be
-```
diff --git a/assets/eip-2537/field_to_curve.md b/assets/eip-2537/field_to_curve.md
deleted file mode 100644
index 94a9ebf..0000000
--- a/assets/eip-2537/field_to_curve.md
+++ /dev/null
@@ -1,245 +0,0 @@
-# Field element to curve point mapping used by EIP 2537
-
-For a BLS12-381 implemented by EIP-2537 a short Weierstrass curve equation y^2 = x^3 + A * x + B has a property that a product AB = 0, so to implement a mapping function two step algorithms is performed:
-- Field element is mapped to a some other curve with AB != 0
-- Isogeny is applied to one to one map a point of this other curve to a point on BLS12-381
-- Cofactor is cleared for a point now on BLS12-381
-
-Below we describe generic algorithms for mapping and isogeny application, and later on give concrete parameters for the algorithms
-
-## Helper function to clear a cofactor
-
-Later on we use a helper function to clear a cofactor of the curve point. It's implemented as
-
-~~~
- clear_cofactor(P) := h_eff * P
-~~~
-
-where values of h_eff are given below in parameters sections
-
-## Simplified SWU for AB != 0
-
-The function map\_to\_curve\_simple\_swu(u) implements a simplification
-of the Shallue-van de Woestijne-Ulas mapping described by Brier et
-al., which they call the "simplified SWU" map. Wahby and Boneh generalize and optimize this mapping.
-
-Preconditions: A Weierstrass curve y^2 = g(x) x^3 + A * x + B where A != 0 and B != 0.
-
-Constants:
-
-- A and B, the parameters of the Weierstrass curve.
-
-- Z, an element of F meeting the below criteria.
- The criteria are:
- 1. Z is non-square in F,
- 2. Z != -1 in F,
- 3. the polynomial g(x) - Z is irreducible over F, and
- 4. g(B / (Z * A)) is square in F.
-
-Sign of y: Inputs u and -u give the same x-coordinate.
-Thus, we set sgn0(y) == sgn0(u).
-
-Exceptions: The exceptional cases are values of u such that
-Z^2 * u^4 + Z * u^2 == 0. This includes u == 0, and may include
-other values depending on Z. Implementations must detect
-this case and set x1 = B / (Z * A), which guarantees that g(x1)
-is square by the condition on Z given above.
-
-Operations:
-
-~~~
-1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
-2. x1 = (-B / A) * (1 + tv1)
-3. If tv1 == 0, set x1 = B / (Z * A)
-4. gx1 = x1^3 + A * x1 + B
-5. x2 = Z * u^2 * x1
-6. gx2 = x2^3 + A * x2 + B
-7. If is_square(gx1), set x = x1 and y = sqrt(gx1)
-8. Else set x = x2 and y = sqrt(gx2)
-9. If sgn0(u) != sgn0(y), set y = -y
-10. return (x, y)
-~~~
-
-## Simplified SWU for AB == 0
-
-Wahby and Boneh show how to adapt the simplified SWU mapping to
-Weierstrass curves having A == 0 or B == 0, which the mapping of
-simple SWU does not support.
-
-This method requires finding another elliptic curve E' given by the equation
-
-~~~
- y'^2 = g'(x') = x'^3 + A' * x' + B'
-~~~
-
-that is isogenous to E and has A' != 0 and B' != 0.
-This isogeny defines a map iso\_map(x', y') given by a pair of rational functions.
-iso\_map takes as input a point on E' and produces as output a point on E.
-
-Once E' and iso\_map are identified, this mapping works as follows: on input
-u, first apply the simplified SWU mapping to get a point on E', then apply
-the isogeny map to that point to get a point on E.
-
-Note that iso\_map is a group homomorphism, meaning that point addition
-commutes with iso\_map.
-Thus, when using this mapping in the hash\_to\_curve construction of {{roadmap}},
-one can effect a small optimization by first mapping u0 and u1 to E', adding
-the resulting points on E', and then applying iso\_map to the sum.
-This gives the same result while requiring only one evaluation of iso\_map.
-
-Preconditions: An elliptic curve E' with A' != 0 and B' != 0 that is
-isogenous to the target curve E with isogeny map iso\_map from
-E' to E.
-
-So the full mapping algorithm looks as:
-
-- map\_to\_curve\_simple\_swu is the simple SWU mapping to E'
-- iso\_map is the isogeny map from E' to E
-
-Sign of y: for this map, the sign is determined by map\_to\_curve\_simple\_swu.
-No further sign adjustments are necessary.
-
-Exceptions: map\_to\_curve\_simple\_swu handles its exceptional cases.
-Exceptional cases of iso\_map are inputs that cause the denominator of
-either rational function to evaluate to zero; such cases MUST return the
-identity point on E.
-
-## Full algorithm restated
-
-~~~
-1. (x', y') = map_to_curve_simple_swu(u) # (x', y') is on E'
-2. (x, y) = iso_map(x', y') # (x, y) is on E
-3. (x, y) = clear_cofactor((x, y)) # clears cofactor for point (x, y) on E
-4. return (x, y)
-~~~
-
-## Parameters for EIP-2537
-
-### Fp-to-G1 mapping
-
-
-- Z: 11
-- E': y'^2 = x'^3 + A' * x' + B', where
- - A' = 0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d
- - B' = 0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0
-- h\_eff: 0xd201000000010001
-
-The 11-isogeny map from (x', y') on E' to (x, y) on E is given by the following rational functions:
-
-- x = x\_num / x\_den, where
- - x\_num = k\_(1,11) * x'^11 + k\_(1,10) * x'^10 + k\_(1,9) * x'^9 + ... + k\_(1,0)
- - x\_den = x'^10 + k\_(2,9) * x'^9 + k\_(2,8) * x'^8 + ... + k\_(2,0)
-
-- y = y' * y\_num / y\_den, where
- - y\_num = k\_(3,15) * x'^15 + k\_(3,14) * x'^14 + k\_(3,13) * x'^13 + ... + k\_(3,0)
- - y\_den = x'^15 + k\_(4,14) * x'^14 + k\_(4,13) * x'^13 + ... + k\_(4,0)
-
-The constants used to compute x\_num are as follows:
-
-- k\_(1,0) = 0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7
-- k\_(1,1) = 0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb
-- k\_(1,2) = 0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0
-- k\_(1,3) = 0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861
-- k\_(1,4) = 0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9
-- k\_(1,5) = 0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983
-- k\_(1,6) = 0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84
-- k\_(1,7) = 0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e
-- k\_(1,8) = 0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317
-- k\_(1,9) = 0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e
-- k\_(1,10) = 0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b
-- k\_(1,11) = 0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229
-
-The constants used to compute x\_den are as follows:
-
-- k\_(2,0) = 0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c
-- k\_(2,1) = 0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff
-- k\_(2,2) = 0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19
-- k\_(2,3) = 0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8
-- k\_(2,4) = 0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e
-- k\_(2,5) = 0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5
-- k\_(2,6) = 0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a
-- k\_(2,7) = 0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e
-- k\_(2,8) = 0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641
-- k\_(2,9) = 0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a
-
-The constants used to compute y\_num are as follows:
-
-- k\_(3,0) = 0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33
-- k\_(3,1) = 0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696
-- k\_(3,2) = 0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6
-- k\_(3,3) = 0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb
-- k\_(3,4) = 0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb
-- k\_(3,5) = 0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0
-- k\_(3,6) = 0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2
-- k\_(3,7) = 0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29
-- k\_(3,8) = 0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587
-- k\_(3,9) = 0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30
-- k\_(3,10) = 0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132
-- k\_(3,11) = 0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e
-- k\_(3,12) = 0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8
-- k\_(3,13) = 0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133
-- k\_(3,14) = 0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b
-- k\_(3,15) = 0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604
-
-The constants used to compute y\_den are as follows:
-
-- k\_(4,0) = 0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1
-- k\_(4,1) = 0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d
-- k\_(4,2) = 0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2
-- k\_(4,3) = 0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416
-- k\_(4,4) = 0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d
-- k\_(4,5) = 0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac
-- k\_(4,6) = 0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c
-- k\_(4,7) = 0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9
-- k\_(4,8) = 0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a
-- k\_(4,9) = 0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55
-- k\_(4,10) = 0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8
-- k\_(4,11) = 0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092
-- k\_(4,12) = 0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc
-- k\_(4,13) = 0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7
-- k\_(4,14) = 0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f
-
-### Fp2-to-G2 mapping
-
-Symbol `I` means a non-residue used to make an extension field Fp2
-
-- Z: -(2 + I)
-- E': y'^2 = x'^3 + A' * x' + B', where
- - A' = 240 * I
- - B' = 1012 * (1 + I)
-- h\_eff: 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551
-
-The 3-isogeny map from (x', y') on E' to (x, y) on E is given by the following rational functions:
-
-- x = x\_num / x\_den, where
- - x\_num = k\_(1,3) * x'^3 + k\_(1,2) * x'^2 + k\_(1,1) * x' + k\_(1,0)
- - x\_den = x'^2 + k\_(2,1) * x' + k\_(2,0)
-
-- y = y' * y\_num / y\_den, where
- - y\_num = k\_(3,3) * x'^3 + k\_(3,2) * x'^2 + k\_(3,1) * x' + k\_(3,0)
- - y\_den = x'^3 + k\_(4,2) * x'^2 + k\_(4,1) * x' + k\_(4,0)
-
-The constants used to compute x\_num are as follows:
-
-- k\_(1,0) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 + 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6 * I
-- k\_(1,1) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a * I
-- k\_(1,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d * I
-- k\_(1,3) = 0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1
-
-The constants used to compute x\_den are as follows:
-
-- k\_(2,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63 * I
-- k\_(2,1) = 0xc + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f * I
-
-The constants used to compute y\_num are as follows:
-
-- k\_(3,0) = 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 + 0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706 * I
-- k\_(3,1) = 0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be * I
-- k\_(3,2) = 0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c + 0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f * I
-- k\_(3,3) = 0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10
-
-The constants used to compute y\_den are as follows:
-
-- k\_(4,0) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb * I
-- k\_(4,1) = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3 * I
-- k\_(4,2) = 0x12 + 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99 * I
\ No newline at end of file
diff --git a/assets/eip-2565/Complexity_Regression.png b/assets/eip-2565/Complexity_Regression.png
deleted file mode 100644
index 059671b..0000000
Binary files a/assets/eip-2565/Complexity_Regression.png and /dev/null differ
diff --git a/assets/eip-2565/GQuad_Change.png b/assets/eip-2565/GQuad_Change.png
deleted file mode 100644
index 53bb641..0000000
Binary files a/assets/eip-2565/GQuad_Change.png and /dev/null differ
diff --git a/assets/eip-2615/concept.png b/assets/eip-2615/concept.png
deleted file mode 100644
index 3198468..0000000
Binary files a/assets/eip-2615/concept.png and /dev/null differ
diff --git a/assets/eip-2615/mortgage-sequential.jpg b/assets/eip-2615/mortgage-sequential.jpg
deleted file mode 100644
index 738c8f4..0000000
Binary files a/assets/eip-2615/mortgage-sequential.jpg and /dev/null differ
diff --git a/assets/eip-2615/rental-sequential.jpg b/assets/eip-2615/rental-sequential.jpg
deleted file mode 100644
index 462f655..0000000
Binary files a/assets/eip-2615/rental-sequential.jpg and /dev/null differ
diff --git a/assets/eip-2678/package.spec.json b/assets/eip-2678/package.spec.json
deleted file mode 100644
index f78790e..0000000
--- a/assets/eip-2678/package.spec.json
+++ /dev/null
@@ -1,483 +0,0 @@
-{
- "title": "Package Manifest",
- "description": "EthPM Manifest Specification",
- "type": "object",
- "required": [
- "manifest"
- ],
- "version": "3",
- "not": {
- "required": ["manifest_version"]
- },
- "properties": {
- "manifest": {
- "type": "string",
- "title": "Manifest",
- "description": "EthPM Manifest Version",
- "default": "ethpm/3",
- "enum": ["ethpm/3"]
- },
- "name": {
- "$ref": "#/definitions/PackageName"
- },
- "version": {
- "title": "Package Version",
- "description": "The version of the package that this release is for",
- "type": "string"
- },
- "meta": {
- "$ref": "#/definitions/PackageMeta"
- },
- "sources": {
- "title": "Sources",
- "description": "The source files included in this release",
- "type": "object",
- "patternProperties": {
- ".*": {
- "$ref": "#/definitions/Source"
- }
- }
- },
- "compilers": {
- "title": "Compilers",
- "description": "The compiler versions used in this release",
- "type": "array",
- "items": {
- "$ref": "#/definitions/CompilerInformation"
- }
- },
- "contractTypes": {
- "title": "Contract Types",
- "description": "The contract types included in this release",
- "type": "object",
- "propertyNames": {
- "$ref": "#/definitions/ContractTypeName"
- },
- "patternProperties": {
- "": {
- "$ref": "#/definitions/ContractType"
- }
- }
- },
- "deployments": {
- "title": "Deployments",
- "description": "The deployed contract instances in this release",
- "type": "object",
- "propertyNames": {
- "$ref": "#/definitions/BlockchainURI"
- },
- "patternProperties": {
- "": {
- "$ref": "#/definitions/Deployment"
- }
- }
- },
- "buildDependencies": {
- "title": "Build Dependencies",
- "type": "object",
- "propertyNames": {
- "$ref": "#/definitions/PackageName"
- },
- "patternProperties": {
- "": {
- "$ref": "#/definitions/ContentURI"
- }
- }
- }
- },
- "definitions": {
- "Source": {
- "title": "Source",
- "description": "Information about a source file included in this package",
- "type": "object",
- "anyOf": [
- {"required": ["content"]},
- {"required": ["urls"]}
- ],
- "properties": {
- "checksum": {
- "$ref": "#/definitions/ChecksumObject"
- },
- "urls": {
- "title": "URLs",
- "description": "Array of urls that resolve to the source file",
- "type": "array",
- "items": {
- "$ref": "#/definitions/ContentURI"
- }
- },
- "content": {
- "title": "Inlined source code",
- "type": "string"
- },
- "installPath": {
- "title": "Target file path to install source file",
- "type": "string",
- "pattern": "^\\.\\/.*$"
- },
- "type": {
- "title": "Type",
- "description": "File type of this source",
- "type": "string"
- },
- "license": {
- "title": "License",
- "description": "The license associated with the source file",
- "type": "string"
- }
- }
- },
- "PackageMeta": {
- "title": "Package Meta",
- "description": "Metadata about the package",
- "type": "object",
- "properties": {
- "authors": {
- "title": "Authors",
- "description": "Authors of this package",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "license": {
- "title": "License",
- "description": "The license that this package and its source are released under",
- "type": "string"
- },
- "description": {
- "title": "Description",
- "description": "Description of this package",
- "type": "string"
- },
- "keywords": {
- "title": "Keywords",
- "description": "Keywords that apply to this package",
- "type": "array",
- "items": {
- "type": "string"
- }
- },
- "links": {
- "title": "Links",
- "descriptions": "URIs for resources related to this package",
- "type": "object",
- "additionalProperties": {
- "type": "string",
- "format": "uri"
- }
- }
- }
- },
- "PackageName": {
- "title": "Package Name",
- "description": "The name of the package that this release is for",
- "type": "string",
- "pattern": "^[a-z][-a-z0-9]{0,255}$"
- },
- "ContractType": {
- "title": "Contract Type",
- "description": "Data for a contract type included in this package",
- "type": "object",
- "properties":{
- "contractName": {
- "$ref": "#/definitions/ContractTypeName"
- },
- "sourceId": {
- "title": "Source ID",
- "description": "The source ID that corresponds to this contract type",
- "type": "string"
- },
- "deploymentBytecode": {
- "$ref": "#/definitions/BytecodeObject"
- },
- "runtimeBytecode": {
- "$ref": "#/definitions/BytecodeObject"
- },
- "abi": {
- "title": "ABI",
- "description": "The ABI for this contract type",
- "type": "array"
- },
- "devdoc": {
- "title": "Devdoc",
- "description": "The dev-doc for this contract",
- "type": "object"
- },
- "userdoc": {
- "title": "Userdoc",
- "description": "The user-doc for this contract",
- "type": "object"
- }
- }
- },
- "ContractInstance": {
- "title": "Contract Instance",
- "description": "Data for a deployed instance of a contract",
- "type": "object",
- "required": [
- "contractType",
- "address"
- ],
- "properties": {
- "contractType": {
- "anyOf": [
- {"$ref": "#/definitions/ContractTypeName"},
- {"$ref": "#/definitions/NestedContractTypeName"}
- ]
- },
- "address": {
- "$ref": "#/definitions/Address"
- },
- "transaction": {
- "$ref": "#/definitions/TransactionHash"
- },
- "block": {
- "$ref": "#/definitions/BlockHash"
- },
- "runtimeBytecode": {
- "$ref": "#/definitions/BytecodeObject"
- },
- "linkDependencies": {
- "title": "Link Dependencies",
- "description": "The values for the link references found within this contract instances runtime bytecode",
- "type": "array",
- "items": {
- "$ref": "#/definitions/LinkValue"
- }
- }
- }
- },
- "ContractTypeName": {
- "title": "Contract Type Name",
- "description": "The name of the contract type",
- "type": "string",
- "pattern": "^(?:[a-z][-a-z0-9]{0,255}\\:)?[a-zA-Z_$][-a-zA-Z0-9_$]{0,255}(?:[-a-zA-Z0-9]{1,256}])?$"
- },
- "ByteString": {
- "title": "Byte String",
- "description": "0x-prefixed hexadecimal string representing bytes",
- "type": "string",
- "pattern": "^0x([0-9a-fA-F]{2})*$"
- },
- "BytecodeObject": {
- "title": "Bytecode Object",
- "type": "object",
- "anyOf": [
- {"required": ["bytecode"]},
- {"required": ["linkDependencies"]}
- ],
- "properties": {
- "bytecode": {
- "$ref": "#/definitions/ByteString"
- },
- "linkReferences": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/LinkReference"
- }
- },
- "linkDependencies": {
- "type": "array",
- "items": {
- "$ref": "#/definitions/LinkValue"
- }
- }
- }
- },
- "ChecksumObject": {
- "title": "Checksum Object",
- "description": "Checksum information about the contents of a source file",
- "type": "object",
- "required": [
- "hash",
- "algorithm"
- ],
- "properties": {
- "hash": {
- "type": "string"
- },
- "algorithm": {
- "type": "string"
- }
- }
- },
- "LinkReference": {
- "title": "Link Reference",
- "description": "A defined location in some bytecode which requires linking",
- "type": "object",
- "required": [
- "offsets",
- "length",
- "name"
- ],
- "properties": {
- "offsets": {
- "type": "array",
- "items": {
- "type": "integer",
- "minimum": 0
- }
- },
- "length": {
- "type": "integer",
- "minimum": 1
- },
- "name": {
- "anyOf": [
- {"$ref": "#/definitions/ContractTypeName"},
- {"$ref": "#/definitions/NestedContractTypeName"}
- ]
- }
- }
- },
- "LinkValue": {
- "title": "Link Value",
- "description": "A value for an individual link reference in a contract's bytecode",
- "type": "object",
- "required": [
- "offsets",
- "type",
- "value"
- ],
- "properties": {
- "offsets": {
- "type": "array",
- "items": {
- "type": "integer",
- "minimum": 0
- }
- },
- "type": {
- "description": "The type of link value",
- "type": "string"
- },
- "value": {
- "description": "The value for the link reference"
- }
- },
- "oneOf": [{
- "properties": {
- "type": {
- "enum": ["literal"]
- },
- "value": {
- "$ref": "#/definitions/ByteString"
- }
- }
- }, {
- "properties": {
- "type": {
- "enum": ["reference"]
- },
- "value": {
- "anyOf": [
- {"$ref": "#/definitions/ContractInstanceName"},
- {"$ref": "#/definitions/NestedContractInstanceName"}
- ]
- }
- }
- }]
- },
- "ContractInstanceName": {
- "title": "Contract Instance Name",
- "description": "The name of the deployed contract instance",
- "type": "string",
- "pattern": "^[a-zA-Z_$][-a-zA-Z0-9_$]{0,255}(?:[-a-zA-Z0-9]{1,256})?$"
- },
- "Deployment": {
- "title": "Deployment",
- "type": "object",
- "propertyNames": {
- "$ref": "#/definitions/ContractInstanceName"
- },
- "patternProperties": {
- "": {
- "$ref": "#/definitions/ContractInstance"
- }
- }
- },
- "NestedContractTypeName": {
- "title": "Nested Contract Type Name",
- "description": "Name of a nested contract type from somewhere down the dependency tree",
- "type": "string",
- "pattern": "^(?:[a-z][-a-z0-9]{0,255}\\:)+[a-zA-Z_$][-a-zA-Z0-9_$]{0,255}(?:[-a-zA-Z0-9]{1,256})?$"
- },
- "NestedContractInstanceName": {
- "title": "Nested Contract Instance Name",
- "description": "Name of a nested contract instance from somewhere down the dependency tree",
- "type": "string",
- "pattern": "^(?:[a-z][-a-z0-9]{0,255}\\:)+[a-zA-Z_$][-a-zA-Z0-9_$]{0,255}(?:[-a-zA-Z0-9]{1,256})?$"
- },
- "CompilerInformation": {
- "title": "Compiler Information",
- "description": "Information about the software that was used to compile a contract type or deployment",
- "type": "object",
- "required": [
- "name",
- "version"
- ],
- "properties": {
- "name": {
- "description": "The name of the compiler",
- "type": "string"
- },
- "version": {
- "description": "The version string for the compiler",
- "type": "string"
- },
- "settings": {
- "description": "The settings used for compilation",
- "type": "object"
- },
- "contractTypes": {
- "description": "The contract types that targeted this compiler.",
- "type": "array",
- "items": {
- "$ref": "#/definitions/ContractTypeName"
- }
- }
- }
- },
- "Address": {
- "title": "Address",
- "description": "A 0x-prefixed Ethereum address",
- "allOf": [
- { "$ref": "#/definitions/ByteString" },
- { "minLength": 42, "maxLength": 42 }
- ]
- },
- "TransactionHash": {
- "title": "Transaction Hash",
- "description": "A 0x-prefixed Ethereum transaction hash",
- "allOf": [
- { "$ref": "#/definitions/ByteString" },
- { "minLength": 66, "maxLength": 66 }
- ]
- },
- "BlockHash": {
- "title": "Block Hash",
- "description": "An Ethereum block hash",
- "allOf": [
- { "$ref": "#/definitions/ByteString" },
- { "minLength": 66, "maxLength": 66 }
- ]
- },
- "ContentURI": {
- "title": "Content URI",
- "description": "An content addressable URI",
- "type": "string",
- "format": "uri"
- },
- "BlockchainURI": {
- "title": "Blockchain URI",
- "description": "An BIP122 URI",
- "type": "string",
- "pattern": "^blockchain\\://[0-9a-fA-F]{64}\\/block\\/[0-9a-fA-F]{64}$"
- }
- },
- "dependencies": {
- "name": ["version"],
- "version": ["name"]
- }
-}
diff --git a/assets/eip-2680/sha256-384-512.pdf b/assets/eip-2680/sha256-384-512.pdf
deleted file mode 100644
index 0524e81..0000000
Binary files a/assets/eip-2680/sha256-384-512.pdf and /dev/null differ
diff --git a/assets/eip-2771/example-flow.png b/assets/eip-2771/example-flow.png
deleted file mode 100644
index b122417..0000000
Binary files a/assets/eip-2771/example-flow.png and /dev/null differ
diff --git a/assets/eip-2848/presentation.pdf b/assets/eip-2848/presentation.pdf
deleted file mode 100644
index 99446f4..0000000
Binary files a/assets/eip-2848/presentation.pdf and /dev/null differ
diff --git a/assets/eip-2917/erc-reward-formula.png b/assets/eip-2917/erc-reward-formula.png
deleted file mode 100644
index a50f387..0000000
Binary files a/assets/eip-2917/erc-reward-formula.png and /dev/null differ
diff --git a/assets/eip-2980/Finma-ICO-Guidelines.pdf b/assets/eip-2980/Finma-ICO-Guidelines.pdf
deleted file mode 100644
index 2c8ba8d..0000000
Binary files a/assets/eip-2980/Finma-ICO-Guidelines.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-AMLA.pdf b/assets/eip-2980/Swiss-Confederation-AMLA.pdf
deleted file mode 100644
index 831c89c..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-AMLA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-BA.pdf b/assets/eip-2980/Swiss-Confederation-BA.pdf
deleted file mode 100644
index 231a551..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-BA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-CISA.pdf b/assets/eip-2980/Swiss-Confederation-CISA.pdf
deleted file mode 100644
index 3f87003..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-CISA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-FINIA.pdf b/assets/eip-2980/Swiss-Confederation-FINIA.pdf
deleted file mode 100644
index e070984..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-FINIA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-FINSA.pdf b/assets/eip-2980/Swiss-Confederation-FINSA.pdf
deleted file mode 100644
index 154aec3..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-FINSA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-FMIA.pdf b/assets/eip-2980/Swiss-Confederation-FMIA.pdf
deleted file mode 100644
index 959c239..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-FMIA.pdf and /dev/null differ
diff --git a/assets/eip-2980/Swiss-Confederation-SESTA.pdf b/assets/eip-2980/Swiss-Confederation-SESTA.pdf
deleted file mode 100644
index b83062d..0000000
Binary files a/assets/eip-2980/Swiss-Confederation-SESTA.pdf and /dev/null differ
diff --git a/assets/eip-2982/2982-issuance.png b/assets/eip-2982/2982-issuance.png
deleted file mode 100644
index 9534a86..0000000
Binary files a/assets/eip-2982/2982-issuance.png and /dev/null differ
diff --git a/assets/eip-2982/arxiv-1710.09437-Casper-the-Friendly-Finality-Gadget.pdf b/assets/eip-2982/arxiv-1710.09437-Casper-the-Friendly-Finality-Gadget.pdf
deleted file mode 100644
index 9c67edb..0000000
Binary files a/assets/eip-2982/arxiv-1710.09437-Casper-the-Friendly-Finality-Gadget.pdf and /dev/null differ
diff --git a/assets/eip-2982/arxiv-1809.09044-Fraud-and-Data-Availability-Proofs--Maximising-Light-Client-Security-and-Scaling-Blockchains-with-Dishonest-Majorities.pdf b/assets/eip-2982/arxiv-1809.09044-Fraud-and-Data-Availability-Proofs--Maximising-Light-Client-Security-and-Scaling-Blockchains-with-Dishonest-Majorities.pdf
deleted file mode 100644
index 7f57657..0000000
Binary files a/assets/eip-2982/arxiv-1809.09044-Fraud-and-Data-Availability-Proofs--Maximising-Light-Client-Security-and-Scaling-Blockchains-with-Dishonest-Majorities.pdf and /dev/null differ
diff --git a/assets/eip-2982/arxiv-2003.03052-Combining-GHOST-and-Casper.pdf b/assets/eip-2982/arxiv-2003.03052-Combining-GHOST-and-Casper.pdf
deleted file mode 100644
index 24d6e69..0000000
Binary files a/assets/eip-2982/arxiv-2003.03052-Combining-GHOST-and-Casper.pdf and /dev/null differ
diff --git a/assets/eip-2982/ef-Discouragement-Attacks.pdf b/assets/eip-2982/ef-Discouragement-Attacks.pdf
deleted file mode 100644
index 8dad60a..0000000
Binary files a/assets/eip-2982/ef-Discouragement-Attacks.pdf and /dev/null differ
diff --git a/assets/eip-2982/iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf b/assets/eip-2982/iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf
deleted file mode 100644
index 31cbeef..0000000
Binary files a/assets/eip-2982/iacr-2015-702-Demystifying-Incentives-in-the-Consensus-Computer.pdf and /dev/null differ
diff --git a/assets/eip-3005/meta-txs-directly-to-token-smart-contract.png b/assets/eip-3005/meta-txs-directly-to-token-smart-contract.png
deleted file mode 100644
index 2c792f1..0000000
Binary files a/assets/eip-3005/meta-txs-directly-to-token-smart-contract.png and /dev/null differ
diff --git a/assets/eip-3068/2012-685_Square_Root_Even_Ext.pdf b/assets/eip-3068/2012-685_Square_Root_Even_Ext.pdf
deleted file mode 100644
index 077e093..0000000
Binary files a/assets/eip-3068/2012-685_Square_Root_Even_Ext.pdf and /dev/null differ
diff --git a/assets/eip-3068/2015-1027_exTNFS.pdf b/assets/eip-3068/2015-1027_exTNFS.pdf
deleted file mode 100644
index a121ddb..0000000
Binary files a/assets/eip-3068/2015-1027_exTNFS.pdf and /dev/null differ
diff --git a/assets/eip-3068/2016-1102_Assessing_NFS_Advances.pdf b/assets/eip-3068/2016-1102_Assessing_NFS_Advances.pdf
deleted file mode 100644
index 2b42969..0000000
Binary files a/assets/eip-3068/2016-1102_Assessing_NFS_Advances.pdf and /dev/null differ
diff --git a/assets/eip-3068/2017-334.pdf b/assets/eip-3068/2017-334.pdf
deleted file mode 100644
index 297ded4..0000000
Binary files a/assets/eip-3068/2017-334.pdf and /dev/null differ
diff --git a/assets/eip-3068/2019-403_BLS12_H2C.pdf b/assets/eip-3068/2019-403_BLS12_H2C.pdf
deleted file mode 100644
index 99a6ace..0000000
Binary files a/assets/eip-3068/2019-403_BLS12_H2C.pdf and /dev/null differ
diff --git a/assets/eip-3068/latincrypt12.pdf b/assets/eip-3068/latincrypt12.pdf
deleted file mode 100644
index 11ebc47..0000000
Binary files a/assets/eip-3068/latincrypt12.pdf and /dev/null differ
diff --git a/assets/eip-3068/madnet.pdf b/assets/eip-3068/madnet.pdf
deleted file mode 100644
index 5185154..0000000
Binary files a/assets/eip-3068/madnet.pdf and /dev/null differ
diff --git a/assets/eip-3068/weilsigs.pdf b/assets/eip-3068/weilsigs.pdf
deleted file mode 100644
index 125c14f..0000000
Binary files a/assets/eip-3068/weilsigs.pdf and /dev/null differ
diff --git a/assets/eip-3074/auth-msg-multi-call.png b/assets/eip-3074/auth-msg-multi-call.png
deleted file mode 100644
index 55da835..0000000
Binary files a/assets/eip-3074/auth-msg-multi-call.png and /dev/null differ
diff --git a/assets/eip-3074/auth-msg.png b/assets/eip-3074/auth-msg.png
deleted file mode 100644
index 2fc38d6..0000000
Binary files a/assets/eip-3074/auth-msg.png and /dev/null differ
diff --git a/assets/eip-3102/sibling.svg b/assets/eip-3102/sibling.svg
deleted file mode 100644
index f670dc1..0000000
--- a/assets/eip-3102/sibling.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-root ... 4 2 2 root ... 5 8 8 root ... 8 Delete 100... root ... 7 Viewer does not support full SVG 1.1
\ No newline at end of file
diff --git a/assets/eip-3267/contracts/BaseBidOnAddresses.sol b/assets/eip-3267/contracts/BaseBidOnAddresses.sol
deleted file mode 100644
index ca69346..0000000
--- a/assets/eip-3267/contracts/BaseBidOnAddresses.sol
+++ /dev/null
@@ -1,131 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
-import { ABDKMath64x64 } from "abdk-libraries-solidity/ABDKMath64x64.sol";
-import { BaseLock } from "./BaseLock.sol";
-
-/// @title Bidding on Ethereum addresses
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-/// This allows anyone claim conditional tokens in order for him to transfer money from the future.
-/// See `docs/future-money.rst`.
-abstract contract BaseBidOnAddresses is BaseLock {
- using ABDKMath64x64 for int128;
- using SafeMath for uint256;
-
- /// A condition score was stored in the chain by an oracle.
- /// @param oracleId The oracle ID.
- /// @param condition The conditional (customer addresses).
- /// @param numerator The relative score provided by the oracle.
- event ReportedNumerator(
- uint64 indexed oracleId,
- uint256 indexed condition,
- uint256 numerator
- );
-
- /// Some condition scores were stored in the chain by an oracle.
- /// @param oracleId The oracle ID.
- /// @param conditions The conditionals (customer addresses).
- /// @param numerators The relative scores provided by the oracle.
- event ReportedNumeratorsBatch(
- uint64 indexed oracleId,
- uint64[] indexed conditions,
- uint256[] numerators
- );
-
- // Whether an oracle finished its work.
- mapping(uint64 => bool) private oracleFinishedMap;
- // Mapping (oracleId => (condition => numerator)) for payout numerators.
- mapping(uint64 => mapping(uint256 => uint256)) private payoutNumeratorsMap;
- // Mapping (oracleId => denominator) for payout denominators.
- mapping(uint256 => uint) private payoutDenominatorMap;
-
- /// Constructor.
- /// @param _uri Our ERC-1155 tokens description URI.
- constructor(string memory _uri) BaseLock(_uri) { }
-
- /// Retrieve the last stored payout numerator (relative score of a condition).
- /// @param _oracleId The oracle ID.
- /// @param _condition The condition (the original receiver of a conditional token).
- /// The result can't change if the oracle has finished.
- function payoutNumerator(uint64 _oracleId, uint256 _condition) public view returns (uint256) {
- return payoutNumeratorsMap[_oracleId][_condition];
- }
-
- /// Retrieve the last stored payout denominator (the sum of all numerators of the oracle).
- /// @param _oracleId The oracle ID.
- /// The result can't change if the oracle has finished.
- function payoutDenominator(uint64 _oracleId) public view returns (uint256) {
- return payoutDenominatorMap[_oracleId];
- }
-
- /// Called by the oracle owner for reporting results of conditions.
- /// @param _oracleId The oracle ID.
- /// @param _condition The condition.
- /// @param _numerator The relative score of the condition.
- /// Note: We could make oracles easily verificable by a hash of all the data, but
- /// - It may need allowing to set a numerator only once.
- /// - It may be not necessary because future technology will allow to aggregate blockchains.
- function reportNumerator(uint64 _oracleId, uint256 _condition, uint256 _numerator) external
- _isOracle(_oracleId)
- _oracleNotFinished(_oracleId) // otherwise an oracle can break data consistency
- {
- _updateNumerator(_oracleId, _numerator, _condition);
- emit ReportedNumerator(_oracleId, _condition, _numerator);
- }
-
- /// Called by the oracle owner for reporting results of several conditions.
- /// @param _oracleId The oracle ID.
- /// @param _conditions The conditions.
- /// @param _numerators The relative scores of the condition.
- function reportNumeratorsBatch(uint64 _oracleId, uint64[] calldata _conditions, uint256[] calldata _numerators) external
- _isOracle(_oracleId)
- _oracleNotFinished(_oracleId) // otherwise an oracle can break data consistency
- {
- require(_conditions.length == _numerators.length, "Length mismatch.");
- for (uint _i = 0; _i < _conditions.length; ++_i) {
- _updateNumerator(_oracleId, _numerators[_i], _conditions[_i]);
- }
- emit ReportedNumeratorsBatch(_oracleId, _conditions, _numerators);
- }
-
- /// Need to be called after all numerators were reported.
- /// @param _oracleId The oracle ID.
- ///
- /// You should set grace period end time before calling this method.
- ///
- /// TODO: Maybe it makes sense to allow to set finish time in a point of the future?
- function finishOracle(uint64 _oracleId) external
- _isOracle(_oracleId)
- {
- oracleFinishedMap[_oracleId] = true;
- emit OracleFinished(_oracleId);
- }
-
- /// Check if an oracle has finished.
- /// @param _oracleId The oracle ID.
- /// @return `true` if it has finished.
- function isOracleFinished(uint64 _oracleId) public view override returns (bool) {
- return oracleFinishedMap[_oracleId];
- }
-
- function _updateNumerator(uint64 _oracleId, uint256 _numerator, uint256 _condition) private {
- payoutDenominatorMap[_oracleId] = payoutDenominatorMap[_oracleId].add(_numerator).sub(payoutNumeratorsMap[_oracleId][_condition]);
- payoutNumeratorsMap[_oracleId][_condition] = _numerator;
- }
-
- // Virtuals //
-
- function _calcRewardShare(uint64 _oracleId, uint256 _condition) internal virtual override view returns (int128) {
- uint256 _numerator = payoutNumeratorsMap[_oracleId][_condition];
- uint256 _denominator = payoutDenominatorMap[_oracleId];
- return ABDKMath64x64.divu(_numerator, _denominator);
- }
-
- // Modifiers //
-
- modifier _oracleNotFinished(uint64 _oracleId) {
- require(!isOracleFinished(_oracleId), "Oracle is finished.");
- _;
- }
-}
diff --git a/assets/eip-3267/contracts/BaseLock.sol b/assets/eip-3267/contracts/BaseLock.sol
deleted file mode 100644
index 7e45627..0000000
--- a/assets/eip-3267/contracts/BaseLock.sol
+++ /dev/null
@@ -1,510 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
-import { ABDKMath64x64 } from "abdk-libraries-solidity/ABDKMath64x64.sol";
-import { ERC1155WithTotals } from "./ERC1155/ERC1155WithTotals.sol";
-import { ERC1155Holder } from "@openzeppelin/contracts/token/ERC1155/ERC1155Holder.sol";
-import { IERC1155 } from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-import { ERC721Holder } from "@openzeppelin/contracts/token/ERC721/ERC721Holder.sol";
-
-/// @title A base class to lock collaterals and distribute them proportional to an oracle result.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-///
-/// One can also donate/bequest a smart wallet (explain how).
-///
-/// We have two kinds of ERC-1155 token IDs:
-/// - conditional tokens: numbers < 2**64
-/// - a combination of a collateral contract address and collateral token ID
-/// (a counter of donated amount of collateral tokens, don't confuse with collateral tokens themselves)
-///
-/// Inheriting from here don't forget to create `createOracle()` external method.
-abstract contract BaseLock is
- ERC1155WithTotals,
- ERC1155Holder, // You are recommended to use `donate()` function instead.
- ERC721Holder // It can be used through an ERC-1155 wrapper.
-{
- using ABDKMath64x64 for int128;
- using SafeMath for uint256;
-
- /// Emitted when an oracle is created.
- /// @param oracleId The ID of the created oracle.
- event OracleCreated(uint64 oracleId);
-
- /// Emitted when an oracle owner is set.
- /// @param oracleOwner Who created an oracle
- /// @param oracleId The ID of the oracle.
- event OracleOwnerChanged(address indexed oracleOwner, uint64 indexed oracleId);
-
- /// Emitted when an oracle owner is set.
- /// @param sender Who created the condition
- /// @param customer The owner of the condition.
- /// @param condition The created condition ID.
- event ConditionCreated(address indexed sender, address indexed customer, uint256 indexed condition);
-
- /// Emitted when a collateral is donated.
- /// @param collateralContractAddress The ERC-1155 contract of the donated token.
- /// @param collateralTokenId The ERC-1155 ID of the donated token.
- /// @param sender Who donated.
- /// @param amount The amount donated.
- /// @param to Whose account the donation is assigned to.
- /// @param data Additional transaction data.
- event DonateCollateral(
- IERC1155 indexed collateralContractAddress,
- uint256 indexed collateralTokenId,
- address indexed sender,
- uint256 amount,
- address to,
- bytes data
- );
-
- /// Emitted when an oracle is marked as having finished its work.
- /// @param oracleId The oracle ID.
- event OracleFinished(uint64 indexed oracleId);
-
- /// Emitted when collateral is withdrawn.
- /// @param contractAddress The ERC-1155 contract of the collateral token.
- /// @param collateralTokenId The ERC-1155 token ID of the collateral.
- /// @param oracleId The oracle ID for which withdrawal is done.
- /// @param user Who has withdrawn.
- /// @param amount The amount withdrawn.
- event CollateralWithdrawn(
- IERC1155 indexed contractAddress,
- uint256 indexed collateralTokenId,
- uint64 indexed oracleId,
- address user,
- uint256 amount
- );
-
- // Next ID.
- uint64 public maxOracleId; // It doesn't really need to be public.
- uint64 public maxConditionId; // It doesn't really need to be public.
-
- // Mapping (oracleId => oracle owner).
- mapping(uint64 => address) private oracleOwnersMap;
- // Mapping (oracleId => time) the max time for first withdrawal.
- mapping(uint64 => uint) private gracePeriodEnds;
- // The user lost the right to transfer conditional tokens: (user => (conditionalToken => bool)).
- mapping(address => mapping(uint256 => bool)) private userUsedRedeemMap;
- // Mapping (token => (original user => amount)) used to calculate withdrawal of collateral amounts.
- mapping(uint256 => mapping(address => uint256)) public lastCollateralBalanceFirstRoundMap;
- // Mapping (token => (original user => amount)) used to calculate withdrawal of collateral amounts.
- mapping(uint256 => mapping(address => uint256)) public lastCollateralBalanceSecondRoundMap;
- /// Mapping (oracleId => amount user withdrew in first round) (see `docs/Calculations.md`).
- mapping(uint64 => uint256) public usersWithdrewInFirstRound;
-
- // Mapping (condition ID => original account)
- mapping(uint256 => address) public conditionOwners;
-
- /// Constructor.
- /// @param _uri Our ERC-1155 tokens description URI.
- constructor(string memory _uri) ERC1155WithTotals(_uri) {
- _registerInterface(
- BaseLock(0).onERC1155Received.selector ^
- BaseLock(0).onERC1155BatchReceived.selector ^
- BaseLock(0).onERC721Received.selector
- );
- }
-
- /// This function makes no sense, because it would produce a condition with zero tokens.
- // function createCondition() public returns (uint64) {
- // return _createCondition();
- // }
-
- /// Modify the owner of an oracle.
- /// @param _newOracleOwner New owner.
- /// @param _oracleId The oracle whose owner to change.
- function changeOracleOwner(address _newOracleOwner, uint64 _oracleId) public _isOracle(_oracleId) {
- oracleOwnersMap[_oracleId] = _newOracleOwner;
- emit OracleOwnerChanged(_newOracleOwner, _oracleId);
- }
-
- /// Set the end time of the grace period.
- ///
- /// The first withdrawal can be done *only* during the grace period.
- /// The second withdrawal can be done after the end of the grace period and only if the first withdrawal was done.
- ///
- /// The intention of the grace period is to check which of users are active ("alive").
- function updateGracePeriodEnds(uint64 _oracleId, uint _time) public _isOracle(_oracleId) {
- gracePeriodEnds[_oracleId] = _time;
- }
-
- /// Donate funds in an ERC-1155 token.
- ///
- /// First, the collateral token need to be approved to be spent by this contract from the address `_from`.
- ///
- /// It also mints a token (with a different ID), that counts donations in that token.
- ///
- /// @param _collateralContractAddress The collateral ERC-1155 contract address.
- /// @param _collateralTokenId The collateral ERC-1155 token ID.
- /// @param _oracleId The oracle ID to whose ecosystem to donate to.
- /// @param _amount The amount to donate.
- /// @param _from From whom to take the donation.
- /// @param _to On whose account the donation amount is assigned.
- /// @param _data Additional transaction data.
- function donate(
- IERC1155 _collateralContractAddress,
- uint256 _collateralTokenId,
- uint64 _oracleId,
- uint256 _amount,
- address _from,
- address _to,
- bytes calldata _data) public
- {
- uint _donatedPerOracleCollateralTokenId = _collateralDonatedPerOracleTokenId(_collateralContractAddress, _collateralTokenId, _oracleId);
- _mint(_to, _donatedPerOracleCollateralTokenId, _amount, _data);
- uint _donatedCollateralTokenId = _collateralDonatedTokenId(_collateralContractAddress, _collateralTokenId);
- _mint(_to, _donatedCollateralTokenId, _amount, _data);
- emit DonateCollateral(_collateralContractAddress, _collateralTokenId, _from, _amount, _to, _data);
- _collateralContractAddress.safeTransferFrom(_from, address(this), _collateralTokenId, _amount, _data); // last against reentrancy attack
- }
-
- /// Gather a DeFi profit of a token previous donated to this contact.
- /// @param _collateralContractAddress The collateral ERC-1155 contract address.
- /// @param _collateralTokenId The collateral ERC-1155 token ID.
- /// @param _oracleId The oracle ID to whose ecosystem to donate to.
- /// @param _data Additional transaction data.
- /// TODO: Batch calls in several tokens and/or to several oracles for less gas usage?
- function gatherDeFiProfit(
- IERC1155 _collateralContractAddress,
- uint256 _collateralTokenId,
- uint64 _oracleId,
- bytes calldata _data) external
- {
- uint _donatedPerOracleCollateralTokenId = _collateralDonatedPerOracleTokenId(_collateralContractAddress, _collateralTokenId, _oracleId);
- uint _donatedCollateralTokenId = _collateralDonatedTokenId(_collateralContractAddress, _collateralTokenId);
-
- // We consider an overflow an error and just revert:
- // FIXME: Impossible due to reentrancy vulnerability? (Really? It's a view!)
- uint256 _difference =
- _collateralContractAddress.balanceOf(address(this), _collateralTokenId).sub(
- balanceOf(address(this), _donatedCollateralTokenId));
- uint256 _amount = // rounding down to prevent overflows
- _difference *
- balanceOf(address(this), _donatedPerOracleCollateralTokenId) /
- balanceOf(address(this), _donatedCollateralTokenId);
-
- // Last to avoid reentrancy vulnerability.
- donate(
- _collateralContractAddress,
- _collateralTokenId,
- _oracleId,
- _amount,
- address(this),
- address(this),
- _data);
- }
-
- /// Calculate how much collateral is owed to a user.
- /// @param _collateralContractAddress The ERC-1155 collateral token contract.
- /// @param _collateralTokenId The ERC-1155 collateral token ID.
- /// @param _oracleId From which oracle's "account" to withdraw.
- /// @param _condition The condition (the original receiver of a conditional token).
- /// @param _user The user to which we may owe.
- function collateralOwing(
- IERC1155 _collateralContractAddress,
- uint256 _collateralTokenId,
- uint64 _oracleId,
- uint256 _condition,
- address _user
- ) external view returns(uint256) {
- bool _inFirstRound = _isInFirstRound(_oracleId);
- (, uint256 _donated) =
- _collateralOwingBase(_collateralContractAddress, _collateralTokenId, _oracleId, _condition, _user, _inFirstRound);
- return _donated;
- }
-
- /// Transfer to `msg.sender` the collateral ERC-1155 token.
- ///
- /// The amount transferred is proportional to the score of `_condition` by the oracle.
- /// @param _collateralContractAddress The ERC-1155 collateral token contract.
- /// @param _collateralTokenId The ERC-1155 collateral token ID.
- /// @param _oracleId From which oracle's "account" to withdraw.
- /// @param _condition The condition.
- /// @param _data Additional data.
- ///
- /// Notes:
- /// - It is made impossible to withdraw somebody's other collateral, as otherwise we can't mark non-active
- /// accounts in grace period.
- /// - We can't transfer to somebody other than `msg.sender` because anybody can transfer
- /// (needed for multi-level transfers).
- /// - After this function is called, it becomes impossible to transfer the corresponding conditional token
- /// of `msg.sender` (to prevent its repeated withdrawal).
- function withdrawCollateral(
- IERC1155 _collateralContractAddress,
- uint256 _collateralTokenId,
- uint64 _oracleId,
- uint256 _condition,
- bytes calldata _data) external
- {
- require(isOracleFinished(_oracleId), "too early"); // to prevent the denominator or the numerators change meantime
- bool _inFirstRound = _isInFirstRound(_oracleId);
- userUsedRedeemMap[msg.sender][_condition] = true;
- // _burn(msg.sender, _condition, conditionalBalance); // Burning it would break using the same token for multiple markets.
- (uint _donatedPerOracleCollateralTokenId, uint256 _owingDonated) =
- _collateralOwingBase(_collateralContractAddress, _collateralTokenId, _oracleId, _condition, msg.sender, _inFirstRound);
-
- // Against rounding errors. Not necessary because of rounding down.
- // if(_owing > balanceOf(address(this), _collateralTokenId)) _owing = balanceOf(address(this), _collateralTokenId);
-
- if (_owingDonated != 0) {
- uint256 _newTotal = totalSupply(_donatedPerOracleCollateralTokenId);
- if (_inFirstRound) {
- lastCollateralBalanceFirstRoundMap[_donatedPerOracleCollateralTokenId][msg.sender] = _newTotal;
- } else {
- lastCollateralBalanceSecondRoundMap[_donatedPerOracleCollateralTokenId][msg.sender] = _newTotal;
- }
- }
- if (!_inFirstRound) {
- usersWithdrewInFirstRound[_oracleId] = usersWithdrewInFirstRound[_oracleId].add(_owingDonated);
- }
- // Last to prevent reentrancy attack:
- _collateralContractAddress.safeTransferFrom(address(this), msg.sender, _collateralTokenId, _owingDonated, _data);
- emit CollateralWithdrawn(
- _collateralContractAddress,
- _collateralTokenId,
- _oracleId,
- msg.sender,
- _owingDonated
- );
- }
-
- /// An ERC-1155 function.
- ///
- /// We disallow transfers of conditional tokens after redeem `_to` prevent "gathering" them before redeeming
- /// each oracle.
- function safeTransferFrom(
- address _from,
- address _to,
- uint256 _id,
- uint256 _value,
- bytes calldata _data
- )
- public override
- {
- _checkTransferAllowed(_id, _from);
- _baseSafeTransferFrom(_from, _to, _id, _value, _data);
- }
-
- /// An ERC-1155 function.
- ///
- /// We disallow transfers of conditional tokens after redeem `_to` prevent "gathering" them before redeeming
- /// each oracle.
- function safeBatchTransferFrom(
- address _from,
- address _to,
- uint256[] calldata _ids,
- uint256[] calldata _values,
- bytes calldata _data
- )
- public override
- {
- for(uint _i = 0; _i < _ids.length; ++_i) {
- _checkTransferAllowed(_ids[_i], _from);
- }
- _baseSafeBatchTransferFrom(_from, _to, _ids, _values, _data);
- }
-
- // Getters //
-
- /// Get the oracle owner.
- /// @param _oracleId The oracle ID.
- function oracleOwner(uint64 _oracleId) public view returns (address) {
- return oracleOwnersMap[_oracleId];
- }
-
- /// Is the oracle marked as having finished its work?
- ///
- /// `oracleId` is the oracle ID.
- function isOracleFinished(uint64 /*oracleId*/) public virtual view returns (bool) {
- return true;
- }
-
- /// Are transfers of a conditinal token locked?
- ///
- /// This is used to prevent its repeated withdrawal.
- /// @param _user Querying if locked for this user.
- /// @param _condition The condition (the original receiver of a conditional token).
- function isConditionalLocked(address _user, uint256 _condition) public view returns (bool) {
- return userUsedRedeemMap[_user][_condition];
- }
-
- /// Retrieve the end of the grace period.
- /// @param _oracleId For which oracle.
- function gracePeriodEnd(uint64 _oracleId) public view returns (uint) {
- return gracePeriodEnds[_oracleId];
- }
-
- // Virtual functions //
-
- /// Current address of a user.
- /// @param _originalAddress The original address of the user.
- function originalToCurrentAddress(address _originalAddress) internal virtual returns (address) {
- return _originalAddress;
- }
-
- /// Mint a conditional to a customer.
- function _mintToCustomer(address _customer, uint256 _condition, uint256 _amount, bytes calldata _data)
- internal virtual
- {
- require(conditionOwners[_condition] == _customer, "Other's salary get attempt.");
- _mint(originalToCurrentAddress(_customer), _condition, _amount, _data);
- }
-
- /// Calculate the share of a condition in an oracle's market.
- /// @param _oracleId The oracle ID.
- /// @return Uses `ABDKMath64x64` number ID.
- function _calcRewardShare(uint64 _oracleId, uint256 _condition) internal virtual view returns (int128);
-
- function _calcMultiplier(uint64 _oracleId, uint256 _condition, int128 _oracleShare) internal virtual view returns (int128) {
- int128 _rewardShare = _calcRewardShare(_oracleId, _condition);
- return _oracleShare.mul(_rewardShare);
- }
-
- function _doTransfer(uint256 _id, address _from, address _to, uint256 _value) internal virtual {
- _balances[_id][_from] = _balances[_id][_from].sub(_value);
- _balances[_id][_to] = _value.add(_balances[_id][_to]);
- }
-
- // Internal //
-
- /// Generate the ERC-1155 token ID that counts amount of donations per oracle for a ERC-1155 collateral token.
- /// @param _collateralContractAddress The ERC-1155 contract of the collateral token.
- /// @param _collateralTokenId The ERC-1155 ID of the collateral token.
- /// @param _oracleId The oracle ID.
- /// Note: It does not conflict with other tokens kinds, because the only other one is the uint64 conditional.
- function _collateralDonatedPerOracleTokenId(IERC1155 _collateralContractAddress, uint256 _collateralTokenId, uint64 _oracleId)
- internal pure returns (uint256)
- {
- return uint256(keccak256(abi.encodePacked(_collateralContractAddress, _collateralTokenId, _oracleId)));
- }
-
- /// Generate the ERC-1155 token ID that counts amount of donations for a ERC-1155 collateral token.
- /// @param _collateralContractAddress The ERC-1155 contract of the collateral token.
- /// @param _collateralTokenId The ERC-1155 ID of the collateral token.
- /// Note: It does not conflict with other tokens kinds, because the only other one is the uint64 conditional.
- function _collateralDonatedTokenId(IERC1155 _collateralContractAddress, uint256 _collateralTokenId)
- internal pure returns (uint256)
- {
- return uint256(keccak256(abi.encodePacked(_collateralContractAddress, _collateralTokenId)));
- }
-
- function _checkTransferAllowed(uint256 _id, address _from) internal view {
- require(!userUsedRedeemMap[_from][_id], "You can't trade conditional tokens after redeem.");
- }
-
- function _baseSafeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes memory _data) private {
- require(_to != address(0), "ERC1155: target address must be non-zero");
- require(
- _from == msg.sender || _operatorApprovals[_from][msg.sender] == true,
- "ERC1155: need operator approval for 3rd party transfers."
- );
-
- _doTransfer(_id, _from, _to, _value);
-
- emit TransferSingle(msg.sender, _from, _to, _id, _value);
-
- _doSafeTransferAcceptanceCheck(msg.sender, _from, _to, _id, _value, _data);
- }
-
- function _baseSafeBatchTransferFrom(
- address _from,
- address _to,
- uint256[] memory _ids,
- uint256[] memory _values,
- bytes memory _data
- )
- private
- {
- require(_ids.length == _values.length, "ERC1155: IDs and _values must have same lengths");
- require(_to != address(0), "ERC1155: target address must be non-zero");
- require(
- _from == msg.sender || _operatorApprovals[_from][msg.sender] == true,
- "ERC1155: need operator approval for 3rd party transfers."
- );
-
- for (uint256 _i = 0; _i < _ids.length; ++_i) {
- uint256 _id = _ids[_i];
- uint256 _value = _values[_i];
-
- _doTransfer(_id, _from, _to, _value);
- }
-
- emit TransferBatch(msg.sender, _from, _to, _ids, _values);
-
- _doSafeBatchTransferAcceptanceCheck(msg.sender, _from, _to, _ids, _values, _data);
- }
-
- function _createOracle() internal returns (uint64) {
- uint64 _oracleId = ++maxOracleId;
- oracleOwnersMap[_oracleId] = msg.sender;
- emit OracleCreated(_oracleId);
- emit OracleOwnerChanged(msg.sender, _oracleId);
- return _oracleId;
- }
-
- /// Start with 1, not 0, to avoid glitch with `conditionalTokens` variable.
- ///
- /// TODO: Use uint64 variables instead?
- function _createCondition(address _customer) internal returns (uint256) {
- return _doCreateCondition(_customer);
- }
-
- /// Start with 1, not 0, to avoid glitch with `conditionalTokens` variable.
- ///
- /// TODO: Use uint64 variables instead?
- function _doCreateCondition(address _customer) internal virtual returns (uint256) {
- uint64 _condition = ++maxConditionId;
-
- conditionOwners[_condition] = _customer;
-
- emit ConditionCreated(msg.sender, _customer, _condition);
-
- return _condition;
- }
-
- function _collateralOwingBase(
- IERC1155 _collateralContractAddress,
- uint256 _collateralTokenId,
- uint64 _oracleId,
- uint256 _condition,
- address _user,
- bool _inFirstRound
- )
- private view returns (uint _donatedPerOracleCollateralTokenId, uint256 _donated)
- {
- uint256 _conditionalBalance = balanceOf(_user, _condition);
- uint256 _totalConditionalBalance =
- _inFirstRound ? totalSupply(_condition) : usersWithdrewInFirstRound[_oracleId];
- _donatedPerOracleCollateralTokenId = _collateralDonatedPerOracleTokenId(_collateralContractAddress, _collateralTokenId, _oracleId);
- // Rounded to below for no out-of-funds:
- int128 _oracleShare = ABDKMath64x64.divu(_conditionalBalance, _totalConditionalBalance);
- uint256 _newDividendsDonated =
- totalSupply(_donatedPerOracleCollateralTokenId) -
- (_inFirstRound
- ? lastCollateralBalanceFirstRoundMap[_donatedPerOracleCollateralTokenId][_user]
- : lastCollateralBalanceSecondRoundMap[_donatedPerOracleCollateralTokenId][_user]);
- int128 _multiplier = _calcMultiplier(_oracleId, _condition, _oracleShare);
- _donated = _multiplier.mulu(_newDividendsDonated);
- }
-
- function _isInFirstRound(uint64 _oracleId) internal view returns (bool) {
- return block.timestamp <= gracePeriodEnds[_oracleId];
- }
-
- function _isConditional(uint256 _tokenId) internal pure returns (bool) {
- // Zero 2**-192 probability that tokenId < (1<<64) if it's not a conditional.
- // Note to auditor: It's a hack, check for no errors carefully.
- return _tokenId < (1<<64);
- }
-
- modifier _isOracle(uint64 _oracleId) {
- require(oracleOwnersMap[_oracleId] == msg.sender, "Not the oracle owner.");
- _;
- }
-
- modifier checkIsConditional(uint256 _tokenId) {
- require(_isConditional(_tokenId), "It's not your conditional.");
- _;
- }
-}
diff --git a/assets/eip-3267/contracts/BaseRestorableSalary.sol b/assets/eip-3267/contracts/BaseRestorableSalary.sol
deleted file mode 100644
index d7eac2d..0000000
--- a/assets/eip-3267/contracts/BaseRestorableSalary.sol
+++ /dev/null
@@ -1,174 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "./Salary.sol";
-
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-/// A base class for salary with receiver accounts that can be restored by an "attorney".
-abstract contract BaseRestorableSalary is BaseSalary {
- // INVARIANT: `_originalAddress(newToOldAccount[newAccount]) == _originalAddress(newAccount)`
- // if `newToOldAccount[newAccount] != address(0)` for every `newAccount`
- // INVARIANT: originalAddresses and originalToCurrentAddresses are mutually inverse.
- // That is:
- // - `originalAddresses[originalToCurrentAddresses[x]] == x` if `originalToCurrentAddresses[x] != address(0)`
- // - `originalToCurrentAddresses[originalAddresses[x]] == x` if `originalAddresses[x] != address(0)`
-
- /// Mapping (current address => very first address an account had).
- mapping(address => address) public originalAddresses;
-
- /// Mapping (very first address an account had => current address).
- mapping(address => address) public originalToCurrentAddresses;
-
- // Mapping from old to new account addresses (created after every change of an address).
- mapping(address => address) public newToOldAccount;
-
- /// Constructor.
- /// @param _uri Our ERC-1155 tokens description URI.
- constructor (string memory _uri) BaseSalary(_uri) { }
-
- /// Below copied from https://github.com/vporton/restorable-funds/blob/f6192fd23cad529b84155d52ae202430cd97db23/contracts/RestorableERC1155.sol
-
- /// Give the user the "permission" to move funds from `_oldAccount` to `_newAccount`.
- ///
- /// This function is intended to be called by an attorney or the user to move to a new account.
- /// @param _oldAccount is a current address.
- /// @param _newAccount is a new address.
- function permitRestoreAccount(address _oldAccount, address _newAccount) public {
- if (msg.sender != _oldAccount) {
- checkAllowedRestoreAccount(_oldAccount, _newAccount); // only authorized "attorneys" or attorney DAOs
- }
- _avoidZeroAddressManipulatins(_oldAccount, _newAccount);
- address _orig = _originalAddress(_oldAccount);
-
- // We don't disallow joining several accounts together to consolidate salaries for different projects.
- // require(originalAddresses[_newAccount] == 0, "Account is taken.")
-
- newToOldAccount[_newAccount] = _oldAccount;
- originalAddresses[_newAccount] = _orig;
- originalToCurrentAddresses[_orig] = _newAccount;
- // Auditor: Check that the above invariant hold.
- emit AccountRestored(_oldAccount, _newAccount);
- }
-
- /// Retire the user's "permission" to move funds from `_oldAccount` to `_newAccount`.
- ///
- /// This function is intended to be called by an attorney.
- /// @param _oldAccount is an old current address.
- /// @param _newAccount is a new address.
- /// (In general) it isn't allowed to be called by `msg.sender == _oldAccount`,
- /// because it would allow to keep stealing the salary by hijacked old account.
- function dispermitRestoreAccount(address _oldAccount, address _newAccount) public {
- checkAllowedUnrestoreAccount(_oldAccount, _newAccount); // only authorized "attorneys" or attorney DAOs
- _avoidZeroAddressManipulatins(_oldAccount, _newAccount);
- newToOldAccount[_newAccount] = address(0);
- originalToCurrentAddresses[_oldAccount] = address(0);
- originalAddresses[_newAccount] = address(0);
- // Auditor: Check that the above invariants hold.
- emit AccountUnrestored(_oldAccount, _newAccount);
- }
-
- /// Move the entire balance of a token from an old account to a new account of the same user.
- /// @param _oldAccount Old account.
- /// @param _newAccount New account.
- /// @param _token The ERC-1155 token ID.
- /// This function can be called by the affected user.
- ///
- /// Remark: We don't need to create new tokens like as on a regular transfer,
- /// because it isn't a transfer to a trader.
- function restoreFunds(address _oldAccount, address _newAccount, uint256 _token) public
- checkMovedOwner(_oldAccount, _newAccount)
- {
- uint256 _amount = _balances[_token][_oldAccount];
-
- _balances[_token][_newAccount] = _balances[_token][_oldAccount];
- _balances[_token][_oldAccount] = 0;
-
- emit TransferSingle(_msgSender(), _oldAccount, _newAccount, _token, _amount);
- }
-
- /// Move the entire balance of tokens from an old account to a new account of the same user.
- /// @param _oldAccount Old account.
- /// @param _newAccount New account.
- /// @param _tokens The ERC-1155 token IDs.
- /// This function can be called by the affected user.
- ///
- /// Remark: We don't need to create new tokens like as on a regular transfer,
- /// because it isn't a transfer to a trader.
- function restoreFundsBatch(address _oldAccount, address _newAccount, uint256[] calldata _tokens) public
- checkMovedOwner(_oldAccount, _newAccount)
- {
- uint256[] memory _amounts = new uint256[](_tokens.length);
- for (uint _i = 0; _i < _tokens.length; ++_i) {
- uint256 _token = _tokens[_i];
- uint256 _amount = _balances[_token][_oldAccount];
- _amounts[_i] = _amount;
-
- _balances[_token][_newAccount] = _balances[_token][_oldAccount];
- _balances[_token][_oldAccount] = 0;
- }
-
- emit TransferBatch(_msgSender(), _oldAccount, _newAccount, _tokens, _amounts);
- }
-
- // Internal functions //
-
- function _avoidZeroAddressManipulatins(address _oldAccount, address _newAccount) internal view {
- // To avoid make-rich-quick manipulations with lost funds:
- require(_oldAccount != address(0) && _newAccount != address(0) &&
- originalAddresses[_newAccount] != address(0) && newToOldAccount[_newAccount] != address(0),
- "Trying to get nobody's funds.");
- }
-
- // Virtual functions //
-
- /// Check if `msg.sender` is an attorney allowed to restore a user's account.
- function checkAllowedRestoreAccount(address /*_oldAccount*/, address /*_newAccount*/) public virtual;
-
- /// Check if `msg.sender` is an attorney allowed to unrestore a user's account.
- function checkAllowedUnrestoreAccount(address /*_oldAccount*/, address /*_newAccount*/) public virtual;
-
- /// Find the original address of a given account.
- /// This function is internal, because it can be calculated off-chain.
- /// @param _account The current address.
- function _originalAddress(address _account) internal view virtual returns (address) {
- address _newAddress = originalAddresses[_account];
- return _newAddress != address(0) ? _newAddress : _account;
- }
-
- // Find the current address for an original address.
- // @param _conditional The original address.
- function originalToCurrentAddress(address _customer) internal virtual override returns (address) {
- address current = originalToCurrentAddresses[_customer];
- return current != address(0) ? current : _customer;
- }
-
- // TODO: Is the following function useful to save gas in other contracts?
- // function getCurrent(address _account) public returns (uint256) {
- // address _original = originalAddresses[_account];
- // return _original == 0 ? 0 : originalToCurrentAddress(_original);
- // }
-
- // Modifiers //
-
- /// Check that `_newAccount` is the user that has the right to restore funds from `_oldAccount`.
- ///
- /// We also allow funds restoration by attorneys for convenience of users.
- /// This is not an increased security risk, because a dishonest attorney can anyway transfer money to himself.
- modifier checkMovedOwner(address _oldAccount, address _newAccount) virtual {
- if (_msgSender() != _newAccount) {
- checkAllowedRestoreAccount(_oldAccount, _newAccount); // only authorized "attorneys" or attorney DAOs
- }
-
- for (address _account = _oldAccount; _account != _newAccount; _account = newToOldAccount[_account]) {
- require(_account != address(0), "Not a moved owner");
- }
-
- _;
- }
-
- // Events //
-
- event AccountRestored(address indexed oldAccount, address indexed newAccount);
-
- event AccountUnrestored(address indexed oldAccount, address indexed newAccount);
-}
diff --git a/assets/eip-3267/contracts/BaseSalary.sol b/assets/eip-3267/contracts/BaseSalary.sol
deleted file mode 100644
index a695f53..0000000
--- a/assets/eip-3267/contracts/BaseSalary.sol
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "./BaseBidOnAddresses.sol";
-
-/// @title Base class for a "salary" that is paid one token per second using minted conditionals.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-/// It was considered to allow the DAO to adjust registration date to pay salary retrospectively,
-/// but this seems giving too much rights to the DAO similarly as if it had the right to declare anyone dead.
-///
-/// It would cause this effect: A scientist who is already great may register then his date is moved back
-/// in time and instantly he or she receives a very big sum of money to his account.
-/// If it is done erroneously, there may be no way to move the registration date again forward in time,
-/// because the tokens may be already withdrawn. And it cannot be done in a fully decentralized way because
-/// it needs oracles. So errors are seem inevitable.
-/// On the other hand, somebody malicious may create and register in my system a pool of Ethereum addresses that
-/// individuals can receive from them as if they themselves registered in the past.
-/// So it in some cases (if the registration date is past the contract deployment) this issue is impossible to
-/// mitigate.
-///
-/// The salary is paid in minted tokens groups into "chains":
-/// the original salary token and anyone can replace it by another token, next in the chain.
-contract BaseSalary is BaseBidOnAddresses {
- /// Salary receiver registered.
- /// @param customer The customer address.
- /// @param oracleId The oracle ID for which he registers.
- /// @param data Additional data.
- event CustomerRegistered(
- address indexed customer,
- uint64 indexed oracleId,
- uint256 indexed condition,
- bytes data
- );
-
- /// Salary tokens minted.
- /// @param customer The customer address.
- /// @param oracleId The oracle ID.
- /// @param amount The minted amount.
- /// @param data Additional data.
- event SalaryMinted(
- address indexed customer,
- uint64 indexed oracleId,
- uint256 indexed condition,
- uint256 amount,
- bytes data
- );
-
- /// Salary token recreated (salary recalculation request).
- /// @param customer The customer address.
- /// @param originalCondition The original token ID.
- /// @param newCondition The new token ID.
- event ConditionReCreate(
- address indexed customer,
- uint256 indexed originalCondition,
- uint256 indexed newCondition
- );
-
- // Mapping (condition ID => registration time).
- mapping(uint256 => uint) public conditionCreationDates;
- // Mapping (condition ID => salary block time).
- mapping(uint256 => uint) public lastSalaryDates;
- /// Mapping (condition ID => account) - salary recipients.
- mapping(uint256 => address) public salaryReceivers;
-
- /// Mapping (condition ID => first condition ID in the chain)
- ///
- /// I call _chain_ of conditions the list of conditions resulting from creating and recreating conditions.
- mapping(uint256 => uint256) public firstConditionInChain;
- /// Mapping (first condition ID in the chain => last condition ID in the chain)
- ///
- /// I call _chain_ of conditions the list of conditions resulting from creating and recreating conditions.
- mapping(uint256 => uint256) public firstToLastConditionInChain;
-
- /// Constructor.
- /// @param _uri The ERC-1155 token URI.
- constructor(string memory _uri) BaseBidOnAddresses(_uri) { }
-
- /// Mint a salary token.
- /// @param _oracleId The oracle ID.
- /// @param _condition The condition ID.
- /// @param _data Additional data.
- /// This method can be called only by the salary receiver.
- function mintSalary(uint64 _oracleId, uint256 _condition, bytes calldata _data)
- ensureLastConditionInChain(_condition) external
- {
- uint _lastSalaryDate = lastSalaryDates[_condition];
- require(_lastSalaryDate != 0, "You are not registered.");
- // Note: Even if you withdraw once per 20 years, you will get only 630,720,000 tokens.
- // This number is probably not to big to be displayed well in UIs.
- uint256 _amount = (block.timestamp - _lastSalaryDate) * 10**18; // one token per second
- _mintToCustomer(msg.sender, firstToLastConditionInChain[_condition], _amount, _data);
- lastSalaryDates[_condition] = block.timestamp;
- emit SalaryMinted(msg.sender, _oracleId, _condition, _amount, _data);
- }
-
- /// Make a new condition that replaces the old one.
- ///
- /// In other words, it is a request to recalculate somebody's salary.
- ///
- /// Anyone can request to recalculate anyone's salary.
- ///
- /// It's also useful to punish someone for decreasing his work performance or an evil act.
- /// This is to be called among other when a person dies.
- ///
- /// Recalculation is also forced when a salary receiver transfers away his current salary token.
- /// It is useful to remove a trader's incentive to kill the issuer to reduce the circulating supply.
- ///
- /// Issue to solve later: Should we recommend:
- /// - calling this function on each new project milestone?
- /// - calling this function regularly (e.g. every week)?
- ///
- /// This function also withdraws the old token.
- function recreateCondition(uint256 _condition) public returns (uint256) {
- return _recreateCondition(_condition);
- }
-
- function _doCreateCondition(address _customer) internal virtual override returns (uint256) {
- uint256 _condition = super._doCreateCondition(_customer);
- salaryReceivers[_condition] = _customer;
- conditionCreationDates[_condition] = block.timestamp;
- firstConditionInChain[_condition] = _condition;
- firstToLastConditionInChain[_condition] = _condition;
- return _condition;
- }
-
- /// Make a new condition that replaces the old one.
- /// The same can be done by transferring to yourself 0 tokens, but this method uses less gas.
- ///
- /// We need to create a new condition every time when an outgoimg transfer of a conditional token happens.
- /// Otherwise an investor would gain if he kills a scientist to reduce the circulating supply of his token to increase the price.
- /// Allowing old tokens to be exchangeable for new ones? (Allowing the reverse swap would create killer's gain.)
- /// Additional benefit of this solution: We can have different rewards at different stages of project,
- /// what may be beneficial for early startups funding.
- ///
- /// Problem to be solved later: There should be an advice to switch to a new token at each milestone of a project?
- ///
- /// Anyone can create a ERC-1155 contract that allows to use any of the tokens in the list
- /// by locking any of the tokens in the list as a new "general" token. We should recommend customers not to
- /// use such contracts, because it creates for them the killer exploit.
- ///
- /// If we would exchange the old and new tokens for the same amounts of collaterals, then it would be
- /// effectively the same token and therefore minting more new token would possibly devalue the old one,
- /// thus triggering the killer's exploit again. So we make old and new completely independent.
- ///
- /// Old token is 1:1 converted to the new token.
- ///
- /// Remark: To make easy to exchange the token even if it is recreated, we can make a wrapper or locker
- /// token that uses `firstConditionInChain[]` to aggregate several tokens together.
- /// A similar wrapper (the customer need to `setApprovalForAll()` on it) that uses
- /// `firstToLastConditionInChain[]` can be used to transfer away recreated tokens
- /// even if an evil DAO tries to frontrun the customer by recreating his tokens very often.
- /// TODO: Test that it's possible to create such a locker.
- ///
- /// Note: That wrapper could be carelessly used to create the investor's killing customer incentive
- /// by the customer using it to transfer to an investor. Even if the customer uses it only for
- /// exchanges, an investor can buy at an exchange and be a killer.
- /// To make it safe, it must stop accepting any new tokens after a transfer.
- /// It can determine if a token is new just comparing by `<` operator.
- /// It's strongly recommended that an app that uses this contract provides its own swap/exchange UI
- /// and warns the user not to use arbitrary exchanges as being an incentive to kill the user.
- ///
- /// We allow anybody (not just the account owner or DAO) to recreate a condition, because:
- /// - Exchanges can create a "composite" token that allows to withdraw any of the tokens in the chain
- /// up to a certain period of time (using on-chain `conditionCreationDates`).
- /// - Therefore somebody's token can be withdrawn even if its ID changes arbitrarily often.
- ///
- /// @param _condition The condition ID.
- function _recreateCondition(uint256 _condition)
- internal ensureFirstConditionInChain(_condition) returns (uint256)
- {
- address _customer = salaryReceivers[_condition];
- uint256 _oldCondition = firstToLastConditionInChain[_condition];
- uint256 _newCondition = _doCreateCondition(_customer);
- firstConditionInChain[_newCondition] = _condition;
-
- uint256 _amount = _balances[_oldCondition][_customer];
- _balances[_newCondition][_customer] = _amount;
- _balances[_oldCondition][_customer] = 0;
-
- // TODO: Should we swap two following lines?
- emit TransferSingle(msg.sender, _customer, address(0), _condition, _amount);
- emit TransferSingle(msg.sender, address(0), _customer, _newCondition, _amount);
-
- lastSalaryDates[_newCondition] = lastSalaryDates[_condition];
- // TODO: Should we here set `lastSalaryDates[_condition] = 0` to save storage space? // TODO: It would also eliminate the need to check in mint function.
-
- emit ConditionReCreate(_customer, _condition, _newCondition);
- return _newCondition;
- }
-
- /// Check if it is the first condition in a chain of conditions.
- /// @param _id The condition ID.
- ///
- /// Must be called with `_id != 0`.
- function isFirstConditionInChain(uint256 _id) internal view returns (bool) {
- return firstConditionInChain[_id] == _id;
- }
-
- /// Check if it is the last condition in a chain of conditions.
- /// @param _id The condition ID.
- ///
- /// Must be called with `_id != 0`.
- ///
- /// TODO: Should make this function public?
- function isLastConditionInChain(uint256 _id) internal view returns (bool) {
- return firstToLastConditionInChain[firstConditionInChain[_id]] == _id;
- }
-
- function _doTransfer(uint256 _id, address _from, address _to, uint256 _value) internal virtual override {
- super._doTransfer(_id, _from, _to, _value);
-
- if (_id != 0 && salaryReceivers[_id] == msg.sender) {
- if (isLastConditionInChain(_id)) { // correct because `_id != 0`
- _recreateCondition(_id);
- }
- }
- }
-
- function _registerCustomer(address _customer, uint64 _oracleId, bytes calldata _data)
- virtual internal returns (uint256)
- {
- uint256 _condition = _doCreateCondition(_customer);
- lastSalaryDates[_condition] = block.timestamp;
- emit CustomerRegistered(msg.sender, _oracleId, _condition, _data);
- return _condition;
- }
-
- modifier ensureFirstConditionInChain(uint256 _id) {
- // TODO: Is `_id != 0` check needed?
- require(_isConditional(_id) && _id != 0 && isFirstConditionInChain(_id), "Only for the last salary token.");
- _;
- }
-
- modifier ensureLastConditionInChain(uint256 _id) {
- // TODO: Is `_id != 0` check needed?
- require(_isConditional(_id) && _id != 0 && isLastConditionInChain(_id), "Only for the last salary token.");
- _;
- }
-}
diff --git a/assets/eip-3267/contracts/BidOnAddresses.sol b/assets/eip-3267/contracts/BidOnAddresses.sol
deleted file mode 100644
index ec41e77..0000000
--- a/assets/eip-3267/contracts/BidOnAddresses.sol
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "./BaseBidOnAddresses.sol";
-
-/// @title Bidding on Ethereum addresses
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-/// This allows anyone to claim 1000 conditional tokens in order for him to transfer money from the future.
-/// See `docs/future-money.rst` and anyone to donate.
-///
-/// We have two kinds of ERC-1155 token IDs:
-/// - conditional tokens: numbers < 2**64
-/// - a combination of a collateral contract address and collateral token ID
-/// (a counter of donated amount of collateral tokens, don't confuse with collateral tokens themselves)
-///
-/// In functions of this contact `condition` is always a customer's original address.
-///
-/// We receive funds in ERC-1155, see also https://github.com/vporton/wrap-tokens
-contract BidOnAddresses is BaseBidOnAddresses {
- uint constant INITIAL_CUSTOMER_BALANCE = 1000 * 10**18; // an arbitrarily chosen value
-
- /// Customer registered.
- /// @param sender `msg.sender`.
- /// @param customer The customer address.
- /// @param data Additional data.
- event CustomerRegistered(
- address indexed sender,
- address indexed customer,
- uint256 indexed condition,
- bytes data
- );
-
- /// @param _uri The ERC-1155 token URI.
- constructor(string memory _uri) BaseBidOnAddresses(_uri) {
- _registerInterface(
- BidOnAddresses(0).onERC1155Received.selector ^
- BidOnAddresses(0).onERC1155BatchReceived.selector
- );
- }
-
- /// Anyone can register anyone.
- ///
- /// This can be called both before or after the oracle finish. However registering after the finish is useless.
- ///
- /// We check that `oracleId` exists (we don't want "spammers" to register themselves for a million oracles).
- ///
- /// We allow anyone to register anyone. This is useful for being registered by robots.
- /// At first it seems to be harmful to make somebody a millionaire unwillingly (he then needs a fortress and bodyguards),
- /// but: Salary tokens will be worth real money, only if the registered person publishes his works together
- /// with his Ethereum address. So, he can be made rich against his will only by impersonating him. But if somebody
- /// impersonates him, then they are able to present him richer than he is anyway, so making him vulnerable to
- /// kidnappers anyway. So having somebody registered against his will seems not to be a problem at all
- /// (except that he will see superfluous worthless tokens in Etherscan data of his account.)
- ///
- /// An alternative way would be to make registration gasless but requiring a registrant signature.
- /// This is not very good, probably:
- /// - It requires to install MetaMask.
- /// - It bothers the person to sign something, when he could just be hesitant to get what he needs.
- /// - It somehow complicates this contract.
- /// @param _customer The address of the customer. // TODO: current or original
- /// @param _oracleId The oracle ID.
- /// @param _data Additional data.
- function registerCustomer(address _customer, uint64 _oracleId, bytes calldata _data) external {
- require(_oracleId <= maxOracleId, "Oracle doesn't exist.");
- uint256 _condition = _createCondition(_customer);
- _mintToCustomer(_customer, _condition, INITIAL_CUSTOMER_BALANCE, _data);
- emit CustomerRegistered(msg.sender, _customer, _condition, _data);
- }
-}
diff --git a/assets/eip-3267/contracts/DAOInterface.sol b/assets/eip-3267/contracts/DAOInterface.sol
deleted file mode 100644
index c2f15ef..0000000
--- a/assets/eip-3267/contracts/DAOInterface.sol
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-
-/// @notice The "DAO plugin" interface.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-interface DAOInterface {
- /// Check if `msg.sender` is an attorney allowed to restore a given account.
- function checkAllowedRestoreAccount(address _oldAccount, address _newAccount) external;
-
- /// Check if `msg.sender` is an attorney allowed to unrestore a given account.
- function checkAllowedUnrestoreAccount(address _oldAccount, address _newAccount) external;
-}
diff --git a/assets/eip-3267/contracts/DefaultDAOInterface.sol b/assets/eip-3267/contracts/DefaultDAOInterface.sol
deleted file mode 100644
index 1551455..0000000
--- a/assets/eip-3267/contracts/DefaultDAOInterface.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "./DAOInterface.sol";
-
-/// @notice "Default" contract for `DAOInterface`.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-contract DefaultDAOInterface is DAOInterface {
- function checkAllowedRestoreAccount(address /*_oldAccount*/, address /*_newAccount*/) external pure override {
- revert("unimplemented");
- }
-
- function checkAllowedUnrestoreAccount(address /*_oldAccount*/, address /*_newAccount*/) external pure override {
- revert("unimplemented");
- }
-}
diff --git a/assets/eip-3267/contracts/ERC1155/ERC1155.sol b/assets/eip-3267/contracts/ERC1155/ERC1155.sol
deleted file mode 100644
index d7f2af5..0000000
--- a/assets/eip-3267/contracts/ERC1155/ERC1155.sol
+++ /dev/null
@@ -1,414 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity >=0.6.0 <0.8.0;
-
-import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-import "@openzeppelin/contracts/token/ERC1155/IERC1155MetadataURI.sol";
-import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
-import "@openzeppelin/contracts/GSN/Context.sol";
-import "@openzeppelin/contracts/introspection/ERC165.sol";
-import "@openzeppelin/contracts/math/SafeMath.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-
-/**
- *
- * @dev Implementation of the basic standard multi-token.
- * See https://eips.ethereum.org/EIPS/eip-1155
- * Originally based on code by Enjin: https://github.com/enjin/erc-1155
- *
- * _Available since v3.1._
- */
-contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
- using SafeMath for uint256;
- using Address for address;
-
- // Mapping from token ID to account balances
- mapping (uint256 => mapping(address => uint256)) internal _balances;
-
- // Mapping from account to operator approvals
- mapping (address => mapping(address => bool)) internal _operatorApprovals;
-
- // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
- string private _uri;
-
- /*
- * bytes4(keccak256('balanceOf(address,uint256)')) == 0x00fdd58e
- * bytes4(keccak256('balanceOfBatch(address[],uint256[])')) == 0x4e1273f4
- * bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
- * bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
- * bytes4(keccak256('safeTransferFrom(address,address,uint256,uint256,bytes)')) == 0xf242432a
- * bytes4(keccak256('safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)')) == 0x2eb2c2d6
- *
- * => 0x00fdd58e ^ 0x4e1273f4 ^ 0xa22cb465 ^
- * 0xe985e9c5 ^ 0xf242432a ^ 0x2eb2c2d6 == 0xd9b67a26
- */
- bytes4 private constant _INTERFACE_ID_ERC1155 = 0xd9b67a26;
-
- /*
- * bytes4(keccak256('uri(uint256)')) == 0x0e89341c
- */
- bytes4 private constant _INTERFACE_ID_ERC1155_METADATA_URI = 0x0e89341c;
-
- /**
- * @dev See {_setURI}.
- */
- constructor (string memory uri_) {
- _setURI(uri_);
-
- // register the supported interfaces to conform to ERC1155 via ERC165
- _registerInterface(_INTERFACE_ID_ERC1155);
-
- // register the supported interfaces to conform to ERC1155MetadataURI via ERC165
- _registerInterface(_INTERFACE_ID_ERC1155_METADATA_URI);
- }
-
- /**
- * @dev See {IERC1155MetadataURI-uri}.
- *
- * This implementation returns the same URI for *all* token types. It relies
- * on the token type ID substitution mechanism
- * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
- *
- * Clients calling this function must replace the `\{id\}` substring with the
- * actual token type ID.
- */
- function uri(uint256) external view override returns (string memory) {
- return _uri;
- }
-
- /**
- * @dev See {IERC1155-balanceOf}.
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- */
- function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
- require(account != address(0), "ERC1155: balance query for the zero address");
- return _balances[id][account];
- }
-
- /**
- * @dev See {IERC1155-balanceOfBatch}.
- *
- * Requirements:
- *
- * - `accounts` and `ids` must have the same length.
- */
- function balanceOfBatch(
- address[] memory accounts,
- uint256[] memory ids
- )
- public
- view
- virtual
- override
- returns (uint256[] memory)
- {
- require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");
-
- uint256[] memory batchBalances = new uint256[](accounts.length);
-
- for (uint256 i = 0; i < accounts.length; ++i) {
- require(accounts[i] != address(0), "ERC1155: batch balance query for the zero address");
- batchBalances[i] = _balances[ids[i]][accounts[i]];
- }
-
- return batchBalances;
- }
-
- /**
- * @dev See {IERC1155-setApprovalForAll}.
- */
- function setApprovalForAll(address operator, bool approved) public virtual override {
- require(_msgSender() != operator, "ERC1155: setting approval status for self");
-
- _operatorApprovals[_msgSender()][operator] = approved;
- emit ApprovalForAll(_msgSender(), operator, approved);
- }
-
- /**
- * @dev See {IERC1155-isApprovedForAll}.
- */
- function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
- return _operatorApprovals[account][operator];
- }
-
- /**
- * @dev See {IERC1155-safeTransferFrom}.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- )
- public
- virtual
- override
- {
- require(to != address(0), "ERC1155: transfer to the zero address");
- require(
- from == _msgSender() || isApprovedForAll(from, _msgSender()),
- "ERC1155: caller is not owner nor approved"
- );
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);
-
- _balances[id][from] = _balances[id][from].sub(amount, "ERC1155: insufficient balance for transfer");
- _balances[id][to] = _balances[id][to].add(amount);
-
- emit TransferSingle(operator, from, to, id, amount);
-
- _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
- }
-
- /**
- * @dev See {IERC1155-safeBatchTransferFrom}.
- */
- function safeBatchTransferFrom(
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- )
- public
- virtual
- override
- {
- require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
- require(to != address(0), "ERC1155: transfer to the zero address");
- require(
- from == _msgSender() || isApprovedForAll(from, _msgSender()),
- "ERC1155: transfer caller is not owner nor approved"
- );
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, from, to, ids, amounts, data);
-
- for (uint256 i = 0; i < ids.length; ++i) {
- uint256 id = ids[i];
- uint256 amount = amounts[i];
-
- _balances[id][from] = _balances[id][from].sub(
- amount,
- "ERC1155: insufficient balance for transfer"
- );
- _balances[id][to] = _balances[id][to].add(amount);
- }
-
- emit TransferBatch(operator, from, to, ids, amounts);
-
- _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
- }
-
- /**
- * @dev Sets a new URI for all token types, by relying on the token type ID
- * substitution mechanism
- * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
- *
- * By this mechanism, any occurrence of the `\{id\}` substring in either the
- * URI or any of the amounts in the JSON file at said URI will be replaced by
- * clients with the token type ID.
- *
- * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
- * interpreted by clients as
- * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
- * for token type ID 0x4cce0.
- *
- * See {uri}.
- *
- * Because these URIs cannot be meaningfully represented by the {URI} event,
- * this function emits no events.
- */
- function _setURI(string memory newuri) internal virtual {
- _uri = newuri;
- }
-
- /**
- * @dev Creates `amount` tokens of token type `id`, and assigns them to `account`.
- *
- * Emits a {TransferSingle} event.
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
- * acceptance magic value.
- */
- function _mint(address account, uint256 id, uint256 amount, bytes memory data) internal virtual {
- require(account != address(0), "ERC1155: mint to the zero address");
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, address(0), account, _asSingletonArray(id), _asSingletonArray(amount), data);
-
- _balances[id][account] = _balances[id][account].add(amount);
- emit TransferSingle(operator, address(0), account, id, amount);
-
- _doSafeTransferAcceptanceCheck(operator, address(0), account, id, amount, data);
- }
-
- /**
- * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
- *
- * Requirements:
- *
- * - `ids` and `amounts` must have the same length.
- * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
- * acceptance magic value.
- */
- function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual {
- require(to != address(0), "ERC1155: mint to the zero address");
- require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);
-
- for (uint i = 0; i < ids.length; i++) {
- _balances[ids[i]][to] = amounts[i].add(_balances[ids[i]][to]);
- }
-
- emit TransferBatch(operator, address(0), to, ids, amounts);
-
- _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
- }
-
- /**
- * @dev Destroys `amount` tokens of token type `id` from `account`
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- * - `account` must have at least `amount` tokens of token type `id`.
- */
- function _burn(address account, uint256 id, uint256 amount) internal virtual {
- require(account != address(0), "ERC1155: burn from the zero address");
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, account, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");
-
- _balances[id][account] = _balances[id][account].sub(
- amount,
- "ERC1155: burn amount exceeds balance"
- );
-
- emit TransferSingle(operator, account, address(0), id, amount);
- }
-
- /**
- * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
- *
- * Requirements:
- *
- * - `ids` and `amounts` must have the same length.
- */
- function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual {
- require(account != address(0), "ERC1155: burn from the zero address");
- require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
-
- address operator = _msgSender();
-
- _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
-
- for (uint i = 0; i < ids.length; i++) {
- _balances[ids[i]][account] = _balances[ids[i]][account].sub(
- amounts[i],
- "ERC1155: burn amount exceeds balance"
- );
- }
-
- emit TransferBatch(operator, account, address(0), ids, amounts);
- }
-
- /**
- * @dev Hook that is called before any token transfer. This includes minting
- * and burning, as well as batched variants.
- *
- * The same hook is called on both single and batched variants. For single
- * transfers, the length of the `id` and `amount` arrays will be 1.
- *
- * Calling conditions (for each `id` and `amount` pair):
- *
- * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * of token type `id` will be transferred to `to`.
- * - When `from` is zero, `amount` tokens of token type `id` will be minted
- * for `to`.
- * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
- * will be burned.
- * - `from` and `to` are never both zero.
- * - `ids` and `amounts` have the same, non-zero length.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _beforeTokenTransfer(
- address operator,
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- )
- internal virtual
- { }
-
- function _doSafeTransferAcceptanceCheck(
- address operator,
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- )
- internal
- {
- if (to.isContract()) {
- try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
- if (response != IERC1155Receiver(to).onERC1155Received.selector) {
- revert("ERC1155: ERC1155Receiver rejected tokens");
- }
- } catch Error(string memory reason) {
- revert(reason);
- } catch {
- revert("ERC1155: transfer to non ERC1155Receiver implementer");
- }
- }
- }
-
- function _doSafeBatchTransferAcceptanceCheck(
- address operator,
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- )
- internal
- {
- if (to.isContract()) {
- try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (bytes4 response) {
- if (response != IERC1155Receiver(to).onERC1155BatchReceived.selector) {
- revert("ERC1155: ERC1155Receiver rejected tokens");
- }
- } catch Error(string memory reason) {
- revert(reason);
- } catch {
- revert("ERC1155: transfer to non ERC1155Receiver implementer");
- }
- }
- }
-
- function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
- uint256[] memory array = new uint256[](1);
- array[0] = element;
-
- return array;
- }
-}
diff --git a/assets/eip-3267/contracts/ERC1155/ERC1155TokenReceiver.sol b/assets/eip-3267/contracts/ERC1155/ERC1155TokenReceiver.sol
deleted file mode 100644
index 9832abc..0000000
--- a/assets/eip-3267/contracts/ERC1155/ERC1155TokenReceiver.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-
-import "./IERC1155TokenReceiver.sol";
-import "@openzeppelin/contracts/introspection/ERC165.sol";
-
-abstract contract ERC1155TokenReceiver is ERC165, IERC1155TokenReceiver {
- constructor() {
- _registerInterface(
- ERC1155TokenReceiver(0).onERC1155Received.selector ^
- ERC1155TokenReceiver(0).onERC1155BatchReceived.selector
- );
- }
-}
diff --git a/assets/eip-3267/contracts/ERC1155/ERC1155WithTotals.sol b/assets/eip-3267/contracts/ERC1155/ERC1155WithTotals.sol
deleted file mode 100644
index 407356f..0000000
--- a/assets/eip-3267/contracts/ERC1155/ERC1155WithTotals.sol
+++ /dev/null
@@ -1,100 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "@openzeppelin/contracts/math/SafeMath.sol";
-import { ERC1155 } from "./ERC1155.sol";
-
-/// @title A base contract for an ERC-1155 contract with calculation of totals.
-abstract contract ERC1155WithTotals is ERC1155 {
- using SafeMath for uint256;
-
- // Mapping (token => total).
- mapping(uint256 => uint256) private totalBalances;
-
- /// Construct a token contract with given description URI.
- /// @param uri_ Description URI.
- constructor (string memory uri_) ERC1155(uri_) { }
-
- // Overrides //
-
- // Need also update totals - commented out
- // function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual override {
- // return super._mintBatch(_originalAddress(to), ids, amounts, data);
- // }
-
- // Need also update totals - commented out
- // function _burnBatch(address account, uint256[] memory ids, uint256[] memory amounts) internal virtual override {
- // return super._burnBatch(_originalAddress(account), ids, amounts);
- // }
-
- /// Total supply of a token (conforms to `IERC1155Views`).
- /// @param id Token ID.
- /// @return Total supply.
- function totalSupply(uint256 id) public view returns (uint256) {
- return totalBalances[id];
- }
-
- /// Mint a token.
- /// @param to Whom to mint to.
- /// @param id Token ID.
- /// @param value Amount to mint.
- /// @param data Additional data.
- function _mint(address to, uint256 id, uint256 value, bytes memory data) internal override {
- require(to != address(0), "ERC1155: mint to the zero address");
-
- _doMint(to, id, value);
- emit TransferSingle(msg.sender, address(0), to, id, value);
-
- _doSafeTransferAcceptanceCheck(msg.sender, address(0), to, id, value, data);
- }
-
- /// Mint zero or more tokens.
- /// @param to Whom to mint to.
- /// @param ids Token IDs.
- /// @param values Amounts to mint.
- /// @param data Additional data.
- function _batchMint(address to, uint256[] memory ids, uint256[] memory values, bytes memory data) internal {
- require(to != address(0), "ERC1155: batch mint to the zero address");
- require(ids.length == values.length, "ERC1155: IDs and values must have same lengths");
-
- for(uint i = 0; i < ids.length; i++) {
- _doMint(to, ids[i], values[i]);
- }
-
- emit TransferBatch(msg.sender, address(0), to, ids, values);
-
- _doSafeBatchTransferAcceptanceCheck(msg.sender, address(0), to, ids, values, data);
- }
-
- /// Burn a token.
- /// @param owner Whose tokens to burn.
- /// @param id Token ID.
- /// @param value Amount to mint.
- function _burn(address owner, uint256 id, uint256 value) internal override {
- _doBurn(owner, id, value);
- emit TransferSingle(msg.sender, owner, address(0), id, value);
- }
-
- /// Burn zero or more tokens.
- /// @param owner Whose tokens to burn.
- /// @param ids Token IDs.
- /// @param values Amounts to mint.
- function _batchBurn(address owner, uint256[] memory ids, uint256[] memory values) internal {
- require(ids.length == values.length, "ERC1155: IDs and values must have same lengths");
-
- for(uint i = 0; i < ids.length; i++) {
- _doBurn(owner, ids[i], values[i]);
- }
-
- emit TransferBatch(msg.sender, owner, address(0), ids, values);
- }
-
- function _doMint(address to, uint256 id, uint256 value) private {
- totalBalances[id] = totalBalances[id].add(value);
- _balances[id][to] = _balances[id][to] + value; // The previous didn't overflow, therefore this doesn't overflow.
- }
-
- function _doBurn(address from, uint256 id, uint256 value) private {
- _balances[id][from] = _balances[id][from].sub(value);
- totalBalances[id] = totalBalances[id] - value; // The previous didn't overflow, therefore this doesn't overflow.
- }
-}
\ No newline at end of file
diff --git a/assets/eip-3267/contracts/ERC1155/IERC1155.sol b/assets/eip-3267/contracts/ERC1155/IERC1155.sol
deleted file mode 100644
index e763657..0000000
--- a/assets/eip-3267/contracts/ERC1155/IERC1155.sol
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-
-import "@openzeppelin/contracts/introspection/IERC165.sol";
-
-/**
- @title ERC-1155 Multi Token Standard basic interface
- @dev See https://eips.ethereum.org/EIPS/eip-1155
- */
-abstract contract IERC1155 is IERC165 {
- event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
-
- event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values);
-
- event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
-
- event URI(string value, uint256 indexed id);
-
- function balanceOf(address owner, uint256 id) public view virtual returns (uint256);
-
- function balanceOfBatch(address[] memory owners, uint256[] memory ids) public view virtual returns (uint256[] memory);
-
- function setApprovalForAll(address operator, bool approved) external virtual;
-
- function isApprovedForAll(address owner, address operator) external view virtual returns (bool);
-
- function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external virtual;
-
- function safeBatchTransferFrom(address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data) external virtual;
-}
diff --git a/assets/eip-3267/contracts/ERC1155/IERC1155TokenReceiver.sol b/assets/eip-3267/contracts/ERC1155/IERC1155TokenReceiver.sol
deleted file mode 100644
index 044260a..0000000
--- a/assets/eip-3267/contracts/ERC1155/IERC1155TokenReceiver.sol
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-
-import "@openzeppelin/contracts/introspection/IERC165.sol";
-
-/**
- @title ERC-1155 Multi Token Receiver Interface
- @dev See https://eips.ethereum.org/EIPS/eip-1155
-*/
-abstract contract IERC1155TokenReceiver is IERC165 {
-
- /**
- @dev Handles the receipt of a single ERC1155 token type. This function is
- called at the end of a `safeTransferFrom` after the balance has been updated.
- To accept the transfer, this must return
- `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
- (i.e. 0xf23a6e61, or its own function selector).
- @param operator The address which initiated the transfer (i.e. msg.sender)
- @param from The address which previously owned the token
- @param id The ID of the token being transferred
- @param value The amount of tokens being transferred
- @param data Additional data with no specified format
- @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
- */
- function onERC1155Received(
- address operator,
- address from,
- uint256 id,
- uint256 value,
- bytes calldata data
- )
- external virtual
- returns(bytes4);
-
- /**
- @dev Handles the receipt of a multiple ERC1155 token types. This function
- is called at the end of a `safeBatchTransferFrom` after the balances have
- been updated. To accept the transfer(s), this must return
- `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
- (i.e. 0xbc197c81, or its own function selector).
- @param operator The address which initiated the batch transfer (i.e. msg.sender)
- @param from The address which previously owned the token
- @param ids An array containing ids of each token being transferred (order and length must match values array)
- @param values An array containing amounts of each token being transferred (order and length must match ids array)
- @param data Additional data with no specified format
- @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
- */
- function onERC1155BatchReceived(
- address operator,
- address from,
- uint256[] calldata ids,
- uint256[] calldata values,
- bytes calldata data
- )
- external virtual
- returns(bytes4);
-}
diff --git a/assets/eip-3267/contracts/ERC1155/README.md b/assets/eip-3267/contracts/ERC1155/README.md
deleted file mode 100644
index 8f69c42..0000000
--- a/assets/eip-3267/contracts/ERC1155/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-sections:
- - title: Core
- contracts:
- - IERC1155
- - ERC1155
- - IERC1155TokenReceiver
----
-
-This set of interfaces and contracts are all related to the [ERC1155 Multi Token Standard](https://eips.ethereum.org/EIPS/eip-1155).
-
-The EIP consists of two interfaces which fulfill different roles, found here as `IERC1155` and `IERC1155TokenReceiver`. Only `IERC1155` is required for a contract to be ERC1155 compliant. The basic functionality is implemented in `ERC1155`.
diff --git a/assets/eip-3267/contracts/README.md b/assets/eip-3267/contracts/README.md
deleted file mode 100644
index 47e04b2..0000000
--- a/assets/eip-3267/contracts/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-This directory contains contract sources for EIP 3267 draft.
-
-The audit of the contracts was paid for, now it is in progress.
-(There are some FIXME/TODO comments for the auditors.)
-
-The contracts are to be compiled with Solidity 0.7.6.
-
-Dependencies (Node.js packages):
-
-- @openzeppelin/contracts 3.3.0
-- abdk-libraries-solidity 2.4.0
-
-The contracts to be deployed are:
-- SalaryWithDAO
-- DefaultDAOInterface
-
-The sources:
-- [ERC1155/ERC1155.sol](./ERC1155/ERC1155.sol)
-- [ERC1155/ERC1155TokenReceiver.sol](./ERC1155/ERC1155TokenReceiver.sol)
-- [ERC1155/ERC1155WithTotals.sol](./ERC1155/ERC1155WithTotals.sol)
-- [ERC1155/IERC1155.sol](./ERC1155/IERC1155.sol)
-- [ERC1155/IERC1155TokenReceiver.sol](./ERC1155/IERC1155TokenReceiver.sol)
-- [BaseBidOnAddresses.sol](./BaseBidOnAddresses.sol)
-- [BaseLock.sol](./BaseLock.sol)
-- [BaseRestorableSalary.sol](./BaseRestorableSalary.sol)
-- [BaseSalary.sol](./BaseSalary.sol)
-- [BidOnAddresses.sol](./BidOnAddresses.sol)
-- [DAOInterface.sol](./DAOInterface.sol)
-- [DefaultDAOInterface.sol](./DefaultDAOInterface.sol)
-- [Salary.sol](./Salary.sol)
-- [SalaryWithDAO.sol](./SalaryWithDAO.sol)
diff --git a/assets/eip-3267/contracts/Salary.sol b/assets/eip-3267/contracts/Salary.sol
deleted file mode 100644
index 83d4808..0000000
--- a/assets/eip-3267/contracts/Salary.sol
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import "./BaseSalary.sol";
-
-/// @title "Salary" that is paid one token per second using minted conditionals.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-contract Salary is BaseSalary {
- /// @param _uri The ERC-1155 token URI.
- constructor(string memory _uri) BaseSalary(_uri) { }
-
- /// Register a salary recipient.
- ///
- /// Can be called both before or after the oracle finish. However registering after the finish is useless.
- ///
- /// Anyone can register anyone (useful for robots registering a person).
- ///
- /// Registering another person is giving him money against his will (forcing to hire bodyguards, etc.),
- /// but if one does not want, he can just not associate this address with his identity in his publications.
- /// @param _customer The original address.
- /// @param _oracleId The oracle ID.
- /// @param _data The current data.
- function registerCustomer(address _customer, uint64 _oracleId, bytes calldata _data)
- virtual public returns (uint256)
- {
- return _registerCustomer(_customer, _oracleId, _data);
- }
-}
\ No newline at end of file
diff --git a/assets/eip-3267/contracts/SalaryWithDAO.sol b/assets/eip-3267/contracts/SalaryWithDAO.sol
deleted file mode 100644
index cbe2110..0000000
--- a/assets/eip-3267/contracts/SalaryWithDAO.sol
+++ /dev/null
@@ -1,126 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.7.1;
-import { ABDKMath64x64 } from "abdk-libraries-solidity/ABDKMath64x64.sol";
-import "./BaseRestorableSalary.sol";
-import "./DAOInterface.sol";
-
-/// Salary system with a "DAO" that can assign attorneys to restore lost Ethereum accounts.
-/// @author Victor Porton
-/// @notice Not audited, not enough tested.
-contract SalaryWithDAO is BaseRestorableSalary {
- using ABDKMath64x64 for int128;
-
- /// The DAO interface.
- DAOInterface public daoPlugin;
-
- /// When set to true, your account can't be moved to new address (by the DAO).
- ///
- /// By default new users are not under DAO control to avoid front-running of resigning control
- /// by an evil DAO.
- ///
- /// Mapping (current address => under control)
- mapping (address => bool) public underDAOControl;
-
- /// Mapping (current address => account has at least one salary).
- mapping (address => bool) public accountHasSalary;
-
- // DAO share will be zero to prevent theft by voters and because it can be done instead by future voting.
- // int128 public daoShare = int128(0).div(1); // zero by default
-
- /// Constructor.
- /// @param _daoPlugin The DAO interface.
- /// @param _uri The ERC-1155 token URI.
- constructor(DAOInterface _daoPlugin, string memory _uri)
- BaseRestorableSalary(_uri)
- {
- daoPlugin = _daoPlugin;
- }
-
- /// Create an oracle for caclcualting salary amounts.
- function createOracle() external returns (uint64) {
- return _createOracle();
- }
-
- /// Register a salary recipient.
- ///
- /// Can be called both before or after the oracle finish. However registering after the finish is useless.
- ///
- /// Anyone can register anyone (useful for robots registering a person).
- ///
- /// Registering another person is giving him money against his will (forcing to hire bodyguards, etc.),
- /// but if one does not want, he can just not associate this address with his identity in his publications.
- /// @param _customer The original address.
- /// @param _oracleId The oracle ID.
- /// @param _underDAOControl If the registered address will be under DAO control.
- /// @param _data The current data.
- function registerCustomer(address _customer, uint64 _oracleId, bool _underDAOControl, bytes calldata _data)
- virtual public returns (uint256)
- {
- address _orig = _originalAddress(_customer);
- // Auditor: Check that this value is set to false, when (and if) necessary.
- accountHasSalary[_customer] = true;
- underDAOControl[_customer] = _underDAOControl; // We don't trigger and event to reduce gas usage.
- return super._registerCustomer(_orig, _oracleId, _data);
- }
-
- /// A user can agree for DAO control. Then his account can be restored by DAO for the expense
- /// of the DAO assigned personnel or software being able to steal his funds.
- ///
- /// Be exteremely careful calling this method: If you refuse and lose your key, your funds are lost!
- ///
- /// Fishers may trick one to resign mistakenly. However, it's no much worse than just fishing for
- /// withdrawing the salary token, because a user could just register anew and notify traders/oracles
- /// that it's the same person.
- function setDAOControl(bool _underControl) public {
- address _orig = _originalAddress(msg.sender);
- require(accountHasSalary[_orig], "Cannot resign account receiving a salary.");
- underDAOControl[_orig] = _underControl; // We don't trigger and event to reduce gas usage.
- }
-
- /// The DAO can replace itself.
- function setDAO(DAOInterface _daoPlugin) public onlyDAO {
- daoPlugin = _daoPlugin;
- }
-
- /// Set the token URI.
- function setURI(string memory _newuri) public onlyDAO {
- _setURI(_newuri);
- }
-
- // Overrides ///
-
- function checkAllowedRestoreAccount(address _oldAccount, address _newAccount)
- public virtual override isUnderDAOControl(_oldAccount)
- {
- daoPlugin.checkAllowedRestoreAccount(_oldAccount, _newAccount);
- }
-
- /// Allow the user to unrestore by himself?
- /// We won't not allow it to `_oldAccount` because it may be a stolen private key.
- /// We could allow it to `_newAccount`, but this makes no much sense, because
- /// it would only prevent the user to do a theft by himself, let only DAO could be allowed to do.
- function checkAllowedUnrestoreAccount(address _oldAccount, address _newAccount)
- public virtual override isUnderDAOControl(_oldAccount)
- {
- daoPlugin.checkAllowedUnrestoreAccount(_oldAccount, _newAccount);
- }
-
- // Internal //
-
- function _isDAO() internal view returns (bool) {
- return msg.sender == address(daoPlugin);
- }
-
- // Modifiers //
-
- modifier onlyDAO() {
- require(_isDAO(), "Only DAO can do.");
- _;
- }
-
- /// @param _customer The current address.
- modifier isUnderDAOControl(address _customer) {
- require(underDAOControl[_customer], "Not under DAO control.");
- _;
- }
-}
diff --git a/assets/eip-3267/science-salaries.pdf b/assets/eip-3267/science-salaries.pdf
deleted file mode 100644
index a6a243c..0000000
Binary files a/assets/eip-3267/science-salaries.pdf and /dev/null differ
diff --git a/assets/eip-3448/MetaProxyFactory.sol b/assets/eip-3448/MetaProxyFactory.sol
deleted file mode 100644
index e7c3679..0000000
--- a/assets/eip-3448/MetaProxyFactory.sol
+++ /dev/null
@@ -1,92 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity >=0.7.6;
-
-contract MetaProxyFactory {
- /// @dev Creates a new proxy for `targetContract` with metadata from calldata.
- /// Copies everything from calldata except the first 4 bytes.
- /// @return addr A non-zero address if successful.
- function _metaProxyFromCalldata (address targetContract) internal returns (address addr) {
- // the following assembly code (init code + contract code) constructs a metaproxy.
- assembly {
- // load free memory pointer as per solidity convention
- let start := mload(64)
- // copy
- let ptr := start
- // deploy code (11 bytes) + first part of the proxy (21 bytes)
- mstore(ptr, 0x600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73)
- ptr := add(ptr, 32)
-
- // store the address of the contract to be called
- mstore(ptr, shl(96, targetContract))
- // 20 bytes
- ptr := add(ptr, 20)
-
- // the remaining proxy code...
- mstore(ptr, 0x5af43d3d93803e603457fd5bf300000000000000000000000000000000000000)
- // ...13 bytes
- ptr := add(ptr, 13)
-
- // now calculdate the size and copy the metadata
- // - 4 bytes function signature
- let size := sub(calldatasize(), 4)
- // copy
- calldatacopy(ptr, 4, size)
- ptr := add(ptr, size)
- // store the size of the metadata at the end of the bytecode
- mstore(ptr, size)
- ptr := add(ptr, 32)
-
- // The size is deploy code + contract code + calldatasize - 4 + 32.
- addr := create(0, start, sub(ptr, start))
- }
- }
-
- /// @dev Creates a proxy for `targetContract` with metadata from `metadata`.
- /// @return A non-zero address if successful.
- function _metaProxyFromBytes (address targetContract, bytes memory metadata) internal returns (address) {
- uint256 ptr;
- assembly {
- ptr := add(metadata, 32)
- }
- return _metaProxyFromMemory(targetContract, ptr, metadata.length);
- }
-
- /// @dev Creates a new proxy for `targetContract` with metadata from memory starting at `offset` and `length` bytes.
- /// @return addr A non-zero address if successful.
- function _metaProxyFromMemory (address targetContract, uint256 offset, uint256 length) internal returns (address addr) {
- // the following assembly code (init code + contract code) constructs a metaproxy.
- assembly {
- // load free memory pointer as per solidity convention
- let start := mload(64)
- // keep a copy
- let ptr := start
- // deploy code (11 bytes) + first part of the proxy (21 bytes)
- mstore(ptr, 0x600b380380600b3d393df3363d3d373d3d3d3d60368038038091363936013d73)
- ptr := add(ptr, 32)
-
- // store the address of the contract to be called
- mstore(ptr, shl(96, targetContract))
- // 20 bytes
- ptr := add(ptr, 20)
-
- // the remaining proxy code...
- mstore(ptr, 0x5af43d3d93803e603457fd5bf300000000000000000000000000000000000000)
- // ...13 bytes
- ptr := add(ptr, 13)
-
- // copy the metadata
- {
- for { let i := 0 } lt(i, length) { i := add(i, 32) } {
- mstore(add(ptr, i), mload(add(offset, i)))
- }
- }
- ptr := add(ptr, length)
- // store the size of the metadata at the end of the bytecode
- mstore(ptr, length)
- ptr := add(ptr, 32)
-
- // The size is deploy code + contract code + calldatasize - 4 + 32.
- addr := create(0, start, sub(ptr, start))
- }
- }
-}
diff --git a/assets/eip-3448/MetaProxyTest.sol b/assets/eip-3448/MetaProxyTest.sol
deleted file mode 100644
index dd17554..0000000
--- a/assets/eip-3448/MetaProxyTest.sol
+++ /dev/null
@@ -1,190 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity >=0.7.6;
-
-import './MetaProxyFactory.sol';
-
-/// @notice This contract includes test cases for the MetaProxy standard.
-contract MetaProxyTest is MetaProxyFactory {
- uint256 public someValue;
-
- event SomeEvent(
- address a,
- uint256 b,
- uint256[] c
- );
- event SomeData(bytes data);
-
- /// @notice One-time initializer.
- function init () external payable {
- require(someValue == 0);
-
- (, uint256 b, ) = MetaProxyTest(this).getMetadataViaCall();
- require(b > 0);
- someValue = b;
- }
-
- /// @notice MetaProxy construction via abi encoded bytes.
- /// Arguments are reversed for testing purposes.
- function createFromBytes (
- uint256[] calldata c,
- uint256 b,
- address a
- ) external payable returns (address proxy) {
- // creates a new proxy where the metadata is the result of abi.encode()
- proxy = MetaProxyFactory._metaProxyFromBytes(address(this), abi.encode(a, b, c));
- require(proxy != address(0));
- // optional one-time setup, a constructor() substitute
- MetaProxyTest(proxy).init{ value: msg.value }();
- }
-
- /// @notice MetaProxy construction via calldata.
- function createFromCalldata (
- address a,
- uint256 b,
- uint256[] calldata c
- ) external payable returns (address proxy) {
- // creates a new proxy where the metadata is everything after the 4th byte from calldata.
- proxy = MetaProxyFactory._metaProxyFromCalldata(address(this));
- require(proxy != address(0));
- // optional one-time setup, a constructor() substitute
- MetaProxyTest(proxy).init{ value: msg.value }();
- }
-
- /// @notice Returns the metadata of this (MetaProxy) contract.
- /// Only relevant with contracts created via the MetaProxy standard.
- /// @dev This function is aimed to be invoked with- & without a call.
- function getMetadataWithoutCall () public pure returns (
- address a,
- uint256 b,
- uint256[] memory c
- ) {
- bytes memory data;
- assembly {
- let posOfMetadataSize := sub(calldatasize(), 32)
- let size := calldataload(posOfMetadataSize)
- let dataPtr := sub(posOfMetadataSize, size)
- data := mload(64)
- // increment free memory pointer by metadata size + 32 bytes (length)
- mstore(64, add(data, add(size, 32)))
- mstore(data, size)
- let memPtr := add(data, 32)
- calldatacopy(memPtr, dataPtr, size)
- }
- return abi.decode(data, (address, uint256, uint256[]));
- }
-
- /// @notice Returns the metadata of this (MetaProxy) contract.
- /// Only relevant with contracts created via the MetaProxy standard.
- /// @dev This function is aimed to to be invoked via a call.
- function getMetadataViaCall () public pure returns (
- address a,
- uint256 b,
- uint256[] memory c
- ) {
- assembly {
- let posOfMetadataSize := sub(calldatasize(), 32)
- let size := calldataload(posOfMetadataSize)
- let dataPtr := sub(posOfMetadataSize, size)
- calldatacopy(0, dataPtr, size)
- return(0, size)
- }
- }
-
- /// @notice Runs all test cases
- function testAll () external payable {
- (address a, uint256 b, uint256[] memory c) = abc();
- MetaProxyTest self = MetaProxyTest(address(this));
-
- {
- address proxy = self.createFromCalldata(a, b, c);
- testProxy(proxy);
- }
- {
- address proxy = self.createFromBytes(c, b, a);
- testProxy(proxy);
- }
- }
-
- function abc () public returns (address a, uint256 b, uint256[] memory c) {
- a = address(this);
- b = 0xc0ffe;
- c = new uint256[](9);
- }
-
- function testProxy (address _proxy) public {
- require(_proxy != address(0));
-
- (address a, uint256 b, uint256[] memory c) = abc();
- MetaProxyTest proxy = MetaProxyTest(_proxy);
-
- {
- (address x, uint256 y, uint256[] memory z) = proxy.getMetadataViaCall();
- require(a == x && b == y && keccak256(abi.encode(c)) == keccak256(abi.encode(z)));
- }
- {
- (address x, uint256 y, uint256[] memory z) = proxy.getMetadataWithoutCall();
- require(a == x && b == y && keccak256(abi.encode(c)) == keccak256(abi.encode(z)));
- }
-
- require(proxy.someValue() == b);
- require(proxy.testReturnSingle() == b);
-
- bytes memory _bytes = hex'68656c6c6f20776f726c64';
- (uint256 x, uint256[] memory y) = proxy.testReturnMulti(_bytes, uint160(address(this)) + b);
- require(x == b);
- require(y.length == c.length);
-
- (bool success, bytes memory returnData) = _proxy.call(abi.encodeWithSignature('testRevert(string)', _bytes));
- require(success == false);
- require(keccak256(returnData) == keccak256(abi.encodeWithSignature('Error(string)', _bytes)));
- }
-
- function testReturnSingle () public returns (uint256) {
- (
- address a,
- uint256 b,
- uint256[] memory c
- ) = MetaProxyTest(this).getMetadataViaCall();
-
- require(a == msg.sender);
- require(b == someValue);
- require(c.length == 9);
-
- emit SomeEvent(a, b, c);
-
- return b;
- }
-
- function testReturnMulti (bytes memory data, uint256 xyz) public returns (uint256, uint256[] memory) {
- (
- address a,
- uint256 b,
- uint256[] memory c
- ) = getMetadataWithoutCall();
-
- require(a == msg.sender);
- require(b == someValue);
- require(c.length == 9);
- require(xyz == uint160(a) + b);
-
- bytes memory expected = hex'68656c6c6f20776f726c64';
- require(data.length == expected.length);
- for (uint256 i = 0; i < expected.length; i++) {
- require(data[i] == expected[i]);
- }
-
- emit SomeEvent(a, b, c);
- emit SomeData(data);
-
- return (b, c);
- }
-
- function testRevert (string memory data) public {
- (address a,,) = getMetadataWithoutCall();
-
- // should evaluate to `true`
- if (a != address(0)) {
- revert(data);
- }
- }
-}
diff --git a/assets/eip-3450/lagrange.gif b/assets/eip-3450/lagrange.gif
deleted file mode 100644
index de7268b..0000000
Binary files a/assets/eip-3450/lagrange.gif and /dev/null differ
diff --git a/assets/eip-3450/wordlist.txt b/assets/eip-3450/wordlist.txt
deleted file mode 100644
index 942040e..0000000
--- a/assets/eip-3450/wordlist.txt
+++ /dev/null
@@ -1,2048 +0,0 @@
-abandon
-ability
-able
-about
-above
-absent
-absorb
-abstract
-absurd
-abuse
-access
-accident
-account
-accuse
-achieve
-acid
-acoustic
-acquire
-across
-act
-action
-actor
-actress
-actual
-adapt
-add
-addict
-address
-adjust
-admit
-adult
-advance
-advice
-aerobic
-affair
-afford
-afraid
-again
-age
-agent
-agree
-ahead
-aim
-air
-airport
-aisle
-alarm
-album
-alcohol
-alert
-alien
-all
-alley
-allow
-almost
-alone
-alpha
-already
-also
-alter
-always
-amateur
-amazing
-among
-amount
-amused
-analyst
-anchor
-ancient
-anger
-angle
-angry
-animal
-ankle
-announce
-annual
-another
-answer
-antenna
-antique
-anxiety
-any
-apart
-apology
-appear
-apple
-approve
-april
-arch
-arctic
-area
-arena
-argue
-arm
-armed
-armor
-army
-around
-arrange
-arrest
-arrive
-arrow
-art
-artefact
-artist
-artwork
-ask
-aspect
-assault
-asset
-assist
-assume
-asthma
-athlete
-atom
-attack
-attend
-attitude
-attract
-auction
-audit
-august
-aunt
-author
-auto
-autumn
-average
-avocado
-avoid
-awake
-aware
-away
-awesome
-awful
-awkward
-axis
-baby
-bachelor
-bacon
-badge
-bag
-balance
-balcony
-ball
-bamboo
-banana
-banner
-bar
-barely
-bargain
-barrel
-base
-basic
-basket
-battle
-beach
-bean
-beauty
-because
-become
-beef
-before
-begin
-behave
-behind
-believe
-below
-belt
-bench
-benefit
-best
-betray
-better
-between
-beyond
-bicycle
-bid
-bike
-bind
-biology
-bird
-birth
-bitter
-black
-blade
-blame
-blanket
-blast
-bleak
-bless
-blind
-blood
-blossom
-blouse
-blue
-blur
-blush
-board
-boat
-body
-boil
-bomb
-bone
-bonus
-book
-boost
-border
-boring
-borrow
-boss
-bottom
-bounce
-box
-boy
-bracket
-brain
-brand
-brass
-brave
-bread
-breeze
-brick
-bridge
-brief
-bright
-bring
-brisk
-broccoli
-broken
-bronze
-broom
-brother
-brown
-brush
-bubble
-buddy
-budget
-buffalo
-build
-bulb
-bulk
-bullet
-bundle
-bunker
-burden
-burger
-burst
-bus
-business
-busy
-butter
-buyer
-buzz
-cabbage
-cabin
-cable
-cactus
-cage
-cake
-call
-calm
-camera
-camp
-can
-canal
-cancel
-candy
-cannon
-canoe
-canvas
-canyon
-capable
-capital
-captain
-car
-carbon
-card
-cargo
-carpet
-carry
-cart
-case
-cash
-casino
-castle
-casual
-cat
-catalog
-catch
-category
-cattle
-caught
-cause
-caution
-cave
-ceiling
-celery
-cement
-census
-century
-cereal
-certain
-chair
-chalk
-champion
-change
-chaos
-chapter
-charge
-chase
-chat
-cheap
-check
-cheese
-chef
-cherry
-chest
-chicken
-chief
-child
-chimney
-choice
-choose
-chronic
-chuckle
-chunk
-churn
-cigar
-cinnamon
-circle
-citizen
-city
-civil
-claim
-clap
-clarify
-claw
-clay
-clean
-clerk
-clever
-click
-client
-cliff
-climb
-clinic
-clip
-clock
-clog
-close
-cloth
-cloud
-clown
-club
-clump
-cluster
-clutch
-coach
-coast
-coconut
-code
-coffee
-coil
-coin
-collect
-color
-column
-combine
-come
-comfort
-comic
-common
-company
-concert
-conduct
-confirm
-congress
-connect
-consider
-control
-convince
-cook
-cool
-copper
-copy
-coral
-core
-corn
-correct
-cost
-cotton
-couch
-country
-couple
-course
-cousin
-cover
-coyote
-crack
-cradle
-craft
-cram
-crane
-crash
-crater
-crawl
-crazy
-cream
-credit
-creek
-crew
-cricket
-crime
-crisp
-critic
-crop
-cross
-crouch
-crowd
-crucial
-cruel
-cruise
-crumble
-crunch
-crush
-cry
-crystal
-cube
-culture
-cup
-cupboard
-curious
-current
-curtain
-curve
-cushion
-custom
-cute
-cycle
-dad
-damage
-damp
-dance
-danger
-daring
-dash
-daughter
-dawn
-day
-deal
-debate
-debris
-decade
-december
-decide
-decline
-decorate
-decrease
-deer
-defense
-define
-defy
-degree
-delay
-deliver
-demand
-demise
-denial
-dentist
-deny
-depart
-depend
-deposit
-depth
-deputy
-derive
-describe
-desert
-design
-desk
-despair
-destroy
-detail
-detect
-develop
-device
-devote
-diagram
-dial
-diamond
-diary
-dice
-diesel
-diet
-differ
-digital
-dignity
-dilemma
-dinner
-dinosaur
-direct
-dirt
-disagree
-discover
-disease
-dish
-dismiss
-disorder
-display
-distance
-divert
-divide
-divorce
-dizzy
-doctor
-document
-dog
-doll
-dolphin
-domain
-donate
-donkey
-donor
-door
-dose
-double
-dove
-draft
-dragon
-drama
-drastic
-draw
-dream
-dress
-drift
-drill
-drink
-drip
-drive
-drop
-drum
-dry
-duck
-dumb
-dune
-during
-dust
-dutch
-duty
-dwarf
-dynamic
-eager
-eagle
-early
-earn
-earth
-easily
-east
-easy
-echo
-ecology
-economy
-edge
-edit
-educate
-effort
-egg
-eight
-either
-elbow
-elder
-electric
-elegant
-element
-elephant
-elevator
-elite
-else
-embark
-embody
-embrace
-emerge
-emotion
-employ
-empower
-empty
-enable
-enact
-end
-endless
-endorse
-enemy
-energy
-enforce
-engage
-engine
-enhance
-enjoy
-enlist
-enough
-enrich
-enroll
-ensure
-enter
-entire
-entry
-envelope
-episode
-equal
-equip
-era
-erase
-erode
-erosion
-error
-erupt
-escape
-essay
-essence
-estate
-eternal
-ethics
-evidence
-evil
-evoke
-evolve
-exact
-example
-excess
-exchange
-excite
-exclude
-excuse
-execute
-exercise
-exhaust
-exhibit
-exile
-exist
-exit
-exotic
-expand
-expect
-expire
-explain
-expose
-express
-extend
-extra
-eye
-eyebrow
-fabric
-face
-faculty
-fade
-faint
-faith
-fall
-false
-fame
-family
-famous
-fan
-fancy
-fantasy
-farm
-fashion
-fat
-fatal
-father
-fatigue
-fault
-favorite
-feature
-february
-federal
-fee
-feed
-feel
-female
-fence
-festival
-fetch
-fever
-few
-fiber
-fiction
-field
-figure
-file
-film
-filter
-final
-find
-fine
-finger
-finish
-fire
-firm
-first
-fiscal
-fish
-fit
-fitness
-fix
-flag
-flame
-flash
-flat
-flavor
-flee
-flight
-flip
-float
-flock
-floor
-flower
-fluid
-flush
-fly
-foam
-focus
-fog
-foil
-fold
-follow
-food
-foot
-force
-forest
-forget
-fork
-fortune
-forum
-forward
-fossil
-foster
-found
-fox
-fragile
-frame
-frequent
-fresh
-friend
-fringe
-frog
-front
-frost
-frown
-frozen
-fruit
-fuel
-fun
-funny
-furnace
-fury
-future
-gadget
-gain
-galaxy
-gallery
-game
-gap
-garage
-garbage
-garden
-garlic
-garment
-gas
-gasp
-gate
-gather
-gauge
-gaze
-general
-genius
-genre
-gentle
-genuine
-gesture
-ghost
-giant
-gift
-giggle
-ginger
-giraffe
-girl
-give
-glad
-glance
-glare
-glass
-glide
-glimpse
-globe
-gloom
-glory
-glove
-glow
-glue
-goat
-goddess
-gold
-good
-goose
-gorilla
-gospel
-gossip
-govern
-gown
-grab
-grace
-grain
-grant
-grape
-grass
-gravity
-great
-green
-grid
-grief
-grit
-grocery
-group
-grow
-grunt
-guard
-guess
-guide
-guilt
-guitar
-gun
-gym
-habit
-hair
-half
-hammer
-hamster
-hand
-happy
-harbor
-hard
-harsh
-harvest
-hat
-have
-hawk
-hazard
-head
-health
-heart
-heavy
-hedgehog
-height
-hello
-helmet
-help
-hen
-hero
-hidden
-high
-hill
-hint
-hip
-hire
-history
-hobby
-hockey
-hold
-hole
-holiday
-hollow
-home
-honey
-hood
-hope
-horn
-horror
-horse
-hospital
-host
-hotel
-hour
-hover
-hub
-huge
-human
-humble
-humor
-hundred
-hungry
-hunt
-hurdle
-hurry
-hurt
-husband
-hybrid
-ice
-icon
-idea
-identify
-idle
-ignore
-ill
-illegal
-illness
-image
-imitate
-immense
-immune
-impact
-impose
-improve
-impulse
-inch
-include
-income
-increase
-index
-indicate
-indoor
-industry
-infant
-inflict
-inform
-inhale
-inherit
-initial
-inject
-injury
-inmate
-inner
-innocent
-input
-inquiry
-insane
-insect
-inside
-inspire
-install
-intact
-interest
-into
-invest
-invite
-involve
-iron
-island
-isolate
-issue
-item
-ivory
-jacket
-jaguar
-jar
-jazz
-jealous
-jeans
-jelly
-jewel
-job
-join
-joke
-journey
-joy
-judge
-juice
-jump
-jungle
-junior
-junk
-just
-kangaroo
-keen
-keep
-ketchup
-key
-kick
-kid
-kidney
-kind
-kingdom
-kiss
-kit
-kitchen
-kite
-kitten
-kiwi
-knee
-knife
-knock
-know
-lab
-label
-labor
-ladder
-lady
-lake
-lamp
-language
-laptop
-large
-later
-latin
-laugh
-laundry
-lava
-law
-lawn
-lawsuit
-layer
-lazy
-leader
-leaf
-learn
-leave
-lecture
-left
-leg
-legal
-legend
-leisure
-lemon
-lend
-length
-lens
-leopard
-lesson
-letter
-level
-liar
-liberty
-library
-license
-life
-lift
-light
-like
-limb
-limit
-link
-lion
-liquid
-list
-little
-live
-lizard
-load
-loan
-lobster
-local
-lock
-logic
-lonely
-long
-loop
-lottery
-loud
-lounge
-love
-loyal
-lucky
-luggage
-lumber
-lunar
-lunch
-luxury
-lyrics
-machine
-mad
-magic
-magnet
-maid
-mail
-main
-major
-make
-mammal
-man
-manage
-mandate
-mango
-mansion
-manual
-maple
-marble
-march
-margin
-marine
-market
-marriage
-mask
-mass
-master
-match
-material
-math
-matrix
-matter
-maximum
-maze
-meadow
-mean
-measure
-meat
-mechanic
-medal
-media
-melody
-melt
-member
-memory
-mention
-menu
-mercy
-merge
-merit
-merry
-mesh
-message
-metal
-method
-middle
-midnight
-milk
-million
-mimic
-mind
-minimum
-minor
-minute
-miracle
-mirror
-misery
-miss
-mistake
-mix
-mixed
-mixture
-mobile
-model
-modify
-mom
-moment
-monitor
-monkey
-monster
-month
-moon
-moral
-more
-morning
-mosquito
-mother
-motion
-motor
-mountain
-mouse
-move
-movie
-much
-muffin
-mule
-multiply
-muscle
-museum
-mushroom
-music
-must
-mutual
-myself
-mystery
-myth
-naive
-name
-napkin
-narrow
-nasty
-nation
-nature
-near
-neck
-need
-negative
-neglect
-neither
-nephew
-nerve
-nest
-net
-network
-neutral
-never
-news
-next
-nice
-night
-noble
-noise
-nominee
-noodle
-normal
-north
-nose
-notable
-note
-nothing
-notice
-novel
-now
-nuclear
-number
-nurse
-nut
-oak
-obey
-object
-oblige
-obscure
-observe
-obtain
-obvious
-occur
-ocean
-october
-odor
-off
-offer
-office
-often
-oil
-okay
-old
-olive
-olympic
-omit
-once
-one
-onion
-online
-only
-open
-opera
-opinion
-oppose
-option
-orange
-orbit
-orchard
-order
-ordinary
-organ
-orient
-original
-orphan
-ostrich
-other
-outdoor
-outer
-output
-outside
-oval
-oven
-over
-own
-owner
-oxygen
-oyster
-ozone
-pact
-paddle
-page
-pair
-palace
-palm
-panda
-panel
-panic
-panther
-paper
-parade
-parent
-park
-parrot
-party
-pass
-patch
-path
-patient
-patrol
-pattern
-pause
-pave
-payment
-peace
-peanut
-pear
-peasant
-pelican
-pen
-penalty
-pencil
-people
-pepper
-perfect
-permit
-person
-pet
-phone
-photo
-phrase
-physical
-piano
-picnic
-picture
-piece
-pig
-pigeon
-pill
-pilot
-pink
-pioneer
-pipe
-pistol
-pitch
-pizza
-place
-planet
-plastic
-plate
-play
-please
-pledge
-pluck
-plug
-plunge
-poem
-poet
-point
-polar
-pole
-police
-pond
-pony
-pool
-popular
-portion
-position
-possible
-post
-potato
-pottery
-poverty
-powder
-power
-practice
-praise
-predict
-prefer
-prepare
-present
-pretty
-prevent
-price
-pride
-primary
-print
-priority
-prison
-private
-prize
-problem
-process
-produce
-profit
-program
-project
-promote
-proof
-property
-prosper
-protect
-proud
-provide
-public
-pudding
-pull
-pulp
-pulse
-pumpkin
-punch
-pupil
-puppy
-purchase
-purity
-purpose
-purse
-push
-put
-puzzle
-pyramid
-quality
-quantum
-quarter
-question
-quick
-quit
-quiz
-quote
-rabbit
-raccoon
-race
-rack
-radar
-radio
-rail
-rain
-raise
-rally
-ramp
-ranch
-random
-range
-rapid
-rare
-rate
-rather
-raven
-raw
-razor
-ready
-real
-reason
-rebel
-rebuild
-recall
-receive
-recipe
-record
-recycle
-reduce
-reflect
-reform
-refuse
-region
-regret
-regular
-reject
-relax
-release
-relief
-rely
-remain
-remember
-remind
-remove
-render
-renew
-rent
-reopen
-repair
-repeat
-replace
-report
-require
-rescue
-resemble
-resist
-resource
-response
-result
-retire
-retreat
-return
-reunion
-reveal
-review
-reward
-rhythm
-rib
-ribbon
-rice
-rich
-ride
-ridge
-rifle
-right
-rigid
-ring
-riot
-ripple
-risk
-ritual
-rival
-river
-road
-roast
-robot
-robust
-rocket
-romance
-roof
-rookie
-room
-rose
-rotate
-rough
-round
-route
-royal
-rubber
-rude
-rug
-rule
-run
-runway
-rural
-sad
-saddle
-sadness
-safe
-sail
-salad
-salmon
-salon
-salt
-salute
-same
-sample
-sand
-satisfy
-satoshi
-sauce
-sausage
-save
-say
-scale
-scan
-scare
-scatter
-scene
-scheme
-school
-science
-scissors
-scorpion
-scout
-scrap
-screen
-script
-scrub
-sea
-search
-season
-seat
-second
-secret
-section
-security
-seed
-seek
-segment
-select
-sell
-seminar
-senior
-sense
-sentence
-series
-service
-session
-settle
-setup
-seven
-shadow
-shaft
-shallow
-share
-shed
-shell
-sheriff
-shield
-shift
-shine
-ship
-shiver
-shock
-shoe
-shoot
-shop
-short
-shoulder
-shove
-shrimp
-shrug
-shuffle
-shy
-sibling
-sick
-side
-siege
-sight
-sign
-silent
-silk
-silly
-silver
-similar
-simple
-since
-sing
-siren
-sister
-situate
-six
-size
-skate
-sketch
-ski
-skill
-skin
-skirt
-skull
-slab
-slam
-sleep
-slender
-slice
-slide
-slight
-slim
-slogan
-slot
-slow
-slush
-small
-smart
-smile
-smoke
-smooth
-snack
-snake
-snap
-sniff
-snow
-soap
-soccer
-social
-sock
-soda
-soft
-solar
-soldier
-solid
-solution
-solve
-someone
-song
-soon
-sorry
-sort
-soul
-sound
-soup
-source
-south
-space
-spare
-spatial
-spawn
-speak
-special
-speed
-spell
-spend
-sphere
-spice
-spider
-spike
-spin
-spirit
-split
-spoil
-sponsor
-spoon
-sport
-spot
-spray
-spread
-spring
-spy
-square
-squeeze
-squirrel
-stable
-stadium
-staff
-stage
-stairs
-stamp
-stand
-start
-state
-stay
-steak
-steel
-stem
-step
-stereo
-stick
-still
-sting
-stock
-stomach
-stone
-stool
-story
-stove
-strategy
-street
-strike
-strong
-struggle
-student
-stuff
-stumble
-style
-subject
-submit
-subway
-success
-such
-sudden
-suffer
-sugar
-suggest
-suit
-summer
-sun
-sunny
-sunset
-super
-supply
-supreme
-sure
-surface
-surge
-surprise
-surround
-survey
-suspect
-sustain
-swallow
-swamp
-swap
-swarm
-swear
-sweet
-swift
-swim
-swing
-switch
-sword
-symbol
-symptom
-syrup
-system
-table
-tackle
-tag
-tail
-talent
-talk
-tank
-tape
-target
-task
-taste
-tattoo
-taxi
-teach
-team
-tell
-ten
-tenant
-tennis
-tent
-term
-test
-text
-thank
-that
-theme
-then
-theory
-there
-they
-thing
-this
-thought
-three
-thrive
-throw
-thumb
-thunder
-ticket
-tide
-tiger
-tilt
-timber
-time
-tiny
-tip
-tired
-tissue
-title
-toast
-tobacco
-today
-toddler
-toe
-together
-toilet
-token
-tomato
-tomorrow
-tone
-tongue
-tonight
-tool
-tooth
-top
-topic
-topple
-torch
-tornado
-tortoise
-toss
-total
-tourist
-toward
-tower
-town
-toy
-track
-trade
-traffic
-tragic
-train
-transfer
-trap
-trash
-travel
-tray
-treat
-tree
-trend
-trial
-tribe
-trick
-trigger
-trim
-trip
-trophy
-trouble
-truck
-true
-truly
-trumpet
-trust
-truth
-try
-tube
-tuition
-tumble
-tuna
-tunnel
-turkey
-turn
-turtle
-twelve
-twenty
-twice
-twin
-twist
-two
-type
-typical
-ugly
-umbrella
-unable
-unaware
-uncle
-uncover
-under
-undo
-unfair
-unfold
-unhappy
-uniform
-unique
-unit
-universe
-unknown
-unlock
-until
-unusual
-unveil
-update
-upgrade
-uphold
-upon
-upper
-upset
-urban
-urge
-usage
-use
-used
-useful
-useless
-usual
-utility
-vacant
-vacuum
-vague
-valid
-valley
-valve
-van
-vanish
-vapor
-various
-vast
-vault
-vehicle
-velvet
-vendor
-venture
-venue
-verb
-verify
-version
-very
-vessel
-veteran
-viable
-vibrant
-vicious
-victory
-video
-view
-village
-vintage
-violin
-virtual
-virus
-visa
-visit
-visual
-vital
-vivid
-vocal
-voice
-void
-volcano
-volume
-vote
-voyage
-wage
-wagon
-wait
-walk
-wall
-walnut
-want
-warfare
-warm
-warrior
-wash
-wasp
-waste
-water
-wave
-way
-wealth
-weapon
-wear
-weasel
-weather
-web
-wedding
-weekend
-weird
-welcome
-west
-wet
-whale
-what
-wheat
-wheel
-when
-where
-whip
-whisper
-wide
-width
-wife
-wild
-will
-win
-window
-wine
-wing
-wink
-winner
-winter
-wire
-wisdom
-wise
-wish
-witness
-wolf
-woman
-wonder
-wood
-wool
-word
-work
-world
-worry
-worth
-wrap
-wreck
-wrestle
-wrist
-write
-wrong
-yard
-year
-yellow
-you
-young
-youth
-zebra
-zero
-zone
-zoo
diff --git a/assets/eip-3475/ERC3475.sol b/assets/eip-3475/ERC3475.sol
deleted file mode 100644
index 43448e1..0000000
--- a/assets/eip-3475/ERC3475.sol
+++ /dev/null
@@ -1,433 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./interfaces/IERC3475.sol";
-
-contract ERC3475 is IERC3475 {
- /**
- * @notice this Struct is representing the Nonce properties as an object
- *
- */
- struct Nonce {
- // stores the values corresponding to the dates (issuance and maturity date).
- mapping(uint256 => IERC3475.Values) _values;
- // storing the issuance of the issued bonds with their balances.
- mapping(address => uint256) _balances;
- // defines the mapping for amount of bonds that can be delegated by Owner => operator address.
- mapping(address => mapping(address => uint256)) _allowances;
-
- // Overall supplies of this nonce
- uint256 _activeSupply;
- uint256 _burnedSupply;
- uint256 _redeemedSupply;
- }
-
- /**
- * @notice this Struct is representing the Class properties as an object
- * and can be retrieved by the classId
- */
- struct Class {
- mapping(uint256 => IERC3475.Values) _values;
- mapping(uint256 => IERC3475.Metadata) _nonceMetadata;
- mapping(uint256 => Nonce) nonces;
- }
-
- mapping(address => mapping(address => bool)) operatorApprovals;
-
- // from classId given
- mapping(uint256 => Class) internal _classes;
- mapping(uint256 => IERC3475.Metadata) _classMetadata;
-
- /**
- * @notice Here the constructor is just to initialize a class and nonce,
- * in practice, you will have a function to create a new class and nonce
- * to be deployed during the initial deployment cycle
- */
- constructor() {
- // define "symbol of the given class";
- _classMetadata[0].title = "symbol";
- _classMetadata[0]._type = "string";
- _classMetadata[0].description = "symbol of the class";
- // define "period of the class";
- _classMetadata[5].title = "period";
- _classMetadata[5]._type = "int";
- _classMetadata[5].description = "value (in months) about maturity time";
-
-
-
-
- // describing the symbol of the different class
- _classes[0]._values[0].stringValue = "DBIT Fix 6M";
- _classes[1]._values[0].stringValue = "DBIT Fix test Instantaneous";
-
-
- // define the maturity time period (for the test class).
- _classes[0]._values[5].uintValue = 10;
- _classes[1]._values[5].uintValue = 1;
-
- // write the time of maturity to nonce values, in other implementation, a create nonce function can be added
- _classes[0].nonces[0]._values[0].uintValue = block.timestamp + 180 days;
- _classes[0].nonces[1]._values[0].uintValue = block.timestamp + 181 days;
- _classes[0].nonces[2]._values[0].uintValue = block.timestamp + 182 days;
-
- // test for review the instantaneous class
- _classes[1].nonces[0]._values[0].uintValue = block.timestamp + 1;
- _classes[1].nonces[1]._values[0].uintValue = block.timestamp + 2;
- _classes[1].nonces[2]._values[0].uintValue = block.timestamp + 3;
-
- // define metadata explaining "maturity of the nonce";
- _classes[0]._nonceMetadata[0].title = "maturity";
- _classes[0]._nonceMetadata[0]._type = "int";
- _classes[0]._nonceMetadata[0].description = "maturity date in integer";
-
- _classes[1]._nonceMetadata[0].title = "maturity";
- _classes[1]._nonceMetadata[0]._type = "int";
- _classes[1]._nonceMetadata[0].description = "maturity date in integer";
-
- // initializing all of the nonces for issued bonds
- _classes[0].nonces[0]._values[0].boolValue = true;
- _classes[0].nonces[1]._values[0].boolValue = true;
- _classes[0].nonces[2]._values[0].boolValue = true;
- }
-
- // Writable functions.
- function transferFrom(
- address _from,
- address _to,
- Transaction[] calldata _transactions
- ) public virtual override {
- require(
- _from != address(0),
- "ERC3475: can't transfer from the zero address"
- );
- require(
- _to != address(0),
- "ERC3475:use burn() instead"
- );
- require(
- msg.sender == _from ||
- isApprovedFor(_from, msg.sender),
- "ERC3475:caller-not-owner-or-approved"
- );
- uint256 len = _transactions.length;
- for (uint256 i = 0; i < len; i++) {
- _transferFrom(_from, _to, _transactions[i]);
- }
- emit Transfer(msg.sender, _from, _to, _transactions);
- }
-
- function transferAllowanceFrom(
- address _from,
- address _to,
- Transaction[] calldata _transactions
- ) public virtual override {
- require(
- _from != address(0),
- "ERC3475: can't transfer allowed amt from zero address"
- );
- require(
- _to != address(0),
- "ERC3475: use burn() instead"
- );
- uint256 len = _transactions.length;
- for (uint256 i = 0; i < len; i++) {
- require(
- _transactions[i]._amount <= allowance(_from, msg.sender, _transactions[i].classId, _transactions[i].nonceId),
- "ERC3475:caller-not-owner-or-approved"
- );
- _transferAllowanceFrom(msg.sender, _from, _to, _transactions[i]);
- }
- emit Transfer(msg.sender, _from, _to, _transactions);
- }
-
- function issue(address _to, Transaction[] calldata _transactions)
- external
- virtual
- override
- {
- uint256 len = _transactions.length;
- for (uint256 i = 0; i < len; i++) {
- require(
- _to != address(0),
- "ERC3475: can't issue to the zero address"
- );
- _issue(_to, _transactions[i]);
- }
- emit Issue(msg.sender, _to, _transactions);
- }
-
- function redeem(address _from, Transaction[] calldata _transactions)
- external
- virtual
- override
- {
- require(
- _from != address(0),
- "ERC3475: can't redeem from the zero address"
- );
- uint256 len = _transactions.length;
- for (uint256 i = 0; i < len; i++) {
- (, uint256 progressRemaining) = getProgress(
- _transactions[i].classId,
- _transactions[i].nonceId
- );
- require(
- progressRemaining == 0,
- "ERC3475 Error: Not redeemable"
- );
- _redeem(_from, _transactions[i]);
- }
- emit Redeem(msg.sender, _from, _transactions);
- }
-
- function burn(address _from, Transaction[] calldata _transactions)
- external
- virtual
- override
- {
- require(
- _from != address(0),
- "ERC3475: can't burn from the zero address"
- );
- require(
- msg.sender == _from ||
- isApprovedFor(_from, msg.sender),
- "ERC3475: caller-not-owner-or-approved"
- );
- uint256 len = _transactions.length;
- for (uint256 i = 0; i < len; i++) {
- _burn(_from, _transactions[i]);
- }
- emit Burn(msg.sender, _from, _transactions);
- }
-
- function approve(address _spender, Transaction[] calldata _transactions)
- external
- virtual
- override
- {
- for (uint256 i = 0; i < _transactions.length; i++) {
- _classes[_transactions[i].classId]
- .nonces[_transactions[i].nonceId]
- ._allowances[msg.sender][_spender] = _transactions[i]._amount;
- }
- }
-
- function setApprovalFor(
- address operator,
- bool approved
- ) public virtual override {
- operatorApprovals[msg.sender][operator] = approved;
- emit ApprovalFor(msg.sender, operator, approved);
- }
-
- // READABLES
- function totalSupply(uint256 classId, uint256 nonceId)
- public
- view
- override
- returns (uint256)
- {
- return (activeSupply(classId, nonceId) +
- burnedSupply(classId, nonceId) +
- redeemedSupply(classId, nonceId)
- );
- }
-
- function activeSupply(uint256 classId, uint256 nonceId)
- public
- view
- override
- returns (uint256)
- {
- return _classes[classId].nonces[nonceId]._activeSupply;
- }
-
- function burnedSupply(uint256 classId, uint256 nonceId)
- public
- view
- override
- returns (uint256)
- {
- return _classes[classId].nonces[nonceId]._burnedSupply;
- }
-
- function redeemedSupply(uint256 classId, uint256 nonceId)
- public
- view
- override
- returns (uint256)
- {
- return _classes[classId].nonces[nonceId]._redeemedSupply;
- }
-
- function balanceOf(
- address account,
- uint256 classId,
- uint256 nonceId
- ) public view override returns (uint256) {
- require(
- account != address(0),
- "ERC3475: balance query for the zero address"
- );
- return _classes[classId].nonces[nonceId]._balances[account];
- }
-
- function classMetadata(uint256 metadataId)
- external
- view
- override
- returns (Metadata memory) {
- return (_classMetadata[metadataId]);
- }
-
- function nonceMetadata(uint256 classId, uint256 metadataId)
- external
- view
- override
- returns (Metadata memory) {
- return (_classes[classId]._nonceMetadata[metadataId]);
- }
-
- function classValues(uint256 classId, uint256 metadataId)
- external
- view
- override
- returns (Values memory) {
- return (_classes[classId]._values[metadataId]);
- }
-
- function nonceValues(uint256 classId, uint256 nonceId, uint256 metadataId)
- external
- view
- override
- returns (Values memory) {
- return (_classes[classId].nonces[nonceId]._values[metadataId]);
- }
-
- /** determines the progress till the redemption of the bonds is valid (based on the type of bonds class).
- * @notice ProgressAchieved and `progressRemaining` is abstract.
- For e.g. we are giving time passed and time remaining.
- */
- function getProgress(uint256 classId, uint256 nonceId)
- public
- view
- override
- returns (uint256 progressAchieved, uint256 progressRemaining){
- uint256 issuanceDate = _classes[classId].nonces[nonceId]._values[0].uintValue;
- uint256 maturityDate = issuanceDate + _classes[classId].nonces[nonceId]._values[5].uintValue;
-
- // check whether the bond is being already initialized:
- progressAchieved = block.timestamp - issuanceDate;
- progressRemaining = block.timestamp < maturityDate
- ? maturityDate - block.timestamp
- : 0;
- }
- /**
- gets the allowance of the bonds identified by (classId,nonceId) held by _owner to be spend by spender.
- */
- function allowance(
- address _owner,
- address spender,
- uint256 classId,
- uint256 nonceId
- ) public view virtual override returns (uint256) {
- return _classes[classId].nonces[nonceId]._allowances[_owner][spender];
- }
-
- /**
- checks the status of approval to transfer the ownership of bonds by _owner to operator.
- */
- function isApprovedFor(
- address _owner,
- address operator
- ) public view virtual override returns (bool) {
- return operatorApprovals[_owner][operator];
- }
-
- // INTERNALS
- function _transferFrom(
- address _from,
- address _to,
- IERC3475.Transaction calldata _transaction
- ) private {
- Nonce storage nonce = _classes[_transaction.classId].nonces[_transaction.nonceId];
- require(
- nonce._balances[_from] >= _transaction._amount,
- "ERC3475: not enough bond to transfer"
- );
-
- //transfer balance
- nonce._balances[_from] -= _transaction._amount;
- nonce._balances[_to] += _transaction._amount;
- }
-
- function _transferAllowanceFrom(
- address _operator,
- address _from,
- address _to,
- IERC3475.Transaction calldata _transaction
- ) private {
- Nonce storage nonce = _classes[_transaction.classId].nonces[_transaction.nonceId];
- require(
- nonce._balances[_from] >= _transaction._amount,
- "ERC3475: not allowed amount"
- );
- // reducing the allowance and decreasing accordingly.
- nonce._allowances[_from][_operator] -= _transaction._amount;
-
- //transfer balance
- nonce._balances[_from] -= _transaction._amount;
- nonce._balances[_to] += _transaction._amount;
- }
-
- function _issue(
- address _to,
- IERC3475.Transaction calldata _transaction
- ) private {
- Nonce storage nonce = _classes[_transaction.classId].nonces[_transaction.nonceId];
-
- //transfer balance
- nonce._balances[_to] += _transaction._amount;
- nonce._activeSupply += _transaction._amount;
- }
-
-
- function _redeem(
- address _from,
- IERC3475.Transaction calldata _transaction
- ) private {
- Nonce storage nonce = _classes[_transaction.classId].nonces[_transaction.nonceId];
- // verify whether _amount of bonds to be redeemed are sufficient available for the given nonce of the bonds
-
- require(
- nonce._balances[_from] >= _transaction._amount,
- "ERC3475: not enough bond to transfer"
- );
-
- //transfer balance
- nonce._balances[_from] -= _transaction._amount;
- nonce._activeSupply -= _transaction._amount;
- nonce._redeemedSupply += _transaction._amount;
- }
-
-
- function _burn(
- address _from,
- IERC3475.Transaction calldata _transaction
- ) private {
- Nonce storage nonce = _classes[_transaction.classId].nonces[_transaction.nonceId];
- // verify whether _amount of bonds to be burned are sfficient available for the given nonce of the bonds
- require(
- nonce._balances[_from] >= _transaction._amount,
- "ERC3475: not enough bond to transfer"
- );
-
- //transfer balance
- nonce._balances[_from] -= _transaction._amount;
- nonce._activeSupply -= _transaction._amount;
- nonce._burnedSupply += _transaction._amount;
- }
-
-}
diff --git a/assets/eip-3475/ERC3475.test.ts b/assets/eip-3475/ERC3475.test.ts
deleted file mode 100644
index cf94602..0000000
--- a/assets/eip-3475/ERC3475.test.ts
+++ /dev/null
@@ -1,333 +0,0 @@
-// @notice : run the typechain generate commance into the smrt contract repository (truffle in our case), after the contracts are compiled.
-import { ERC3475Instance } from "../types/truffle-contracts";
-
-function sleep(ms: any) {
- return new Promise((resolve) => {
- setTimeout(resolve, ms);
- });
-
-}
-
-
-
-
-const Bond = artifacts.require("ERC3475");
-
-contract('Bond', async (accounts: string[]) => {
-
- let bondContract: ERC3475Instance;
- const lender = accounts[1];
- const operator = accounts[2];
- const secondaryMarketBuyer = accounts[3];
- const secondaryMarketBuyer2 = accounts[4];
- const spender = accounts[5];
-
- const DBITClassId: number = 0;
- const firstNonceId: number = 0;
-
- interface _transaction {
- classId: string | number | BN;
- nonceId: string | number | BN;
- amount: string | number | BN;
- }
-
- before('testing', async () => {
- bondContract = await Bond.deployed();
-
- })
-
- it('should issue bonds to a lender', async () => {
- let _transactionIssuer: _transaction[]
- =
- [{
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 7000
- }];
-
- await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
- await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
- const balance = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()
- const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber()
- assert.equal(balance, 14000);
- assert.equal(activeSupply, 14000);
- })
- it('lender should be able to transfer bonds to another address', async () => {
-
- const transferBonds: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 2000
- }];
- await bondContract.transferFrom(lender, secondaryMarketBuyer, transferBonds, { from: lender })
-
- const lenderBalance = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()
- const secondaryBuyerBalance = (await bondContract.balanceOf(secondaryMarketBuyer, DBITClassId, firstNonceId)).toNumber()
- const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber()
-
- assert.equal(lenderBalance, 12000);
- assert.equal(secondaryBuyerBalance, 2000);
- assert.equal(activeSupply, 14000);
- })
- it('operator should be able to manipulate bonds after approval', async () => {
- const transactionApproval: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 2000
- }];
-
- await bondContract.setApprovalFor(operator, true, { from: lender })
- const isApproved = await bondContract.isApprovedFor(lender, operator);
- assert.isTrue(isApproved);
- await bondContract.transferFrom(lender, secondaryMarketBuyer2, transactionApproval, { from: operator })
- expect((await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()).to.equal(10000);
- expect((await bondContract.balanceOf(secondaryMarketBuyer2, DBITClassId, firstNonceId)).toNumber()).to.equal(2000);
-
- })
-
- it('lender should redeem bonds when conditions are met', async () => {
- const redemptionTransaction: _transaction[] = [
- {
- classId: 1,
- nonceId: 1,
- amount: 2000
-
- },
- ];
- await bondContract.issue(accounts[2],redemptionTransaction, {from: accounts[2]});
- assert.equal((await bondContract.balanceOf(accounts[2], 1, 1)).toNumber(), 2000);
- // adding delay for passing the redemption time period.
- await sleep(7000);
-
- await bondContract.redeem(accounts[2], redemptionTransaction, {from:accounts[2]});
-
- assert.equal((await bondContract.balanceOf(accounts[2], DBITClassId, firstNonceId)).toNumber(), 0);
- })
-
-
- it('lender should not be able to redeem bonds when conditions are not met', async () => {
- const redemptionTransaction: _transaction[] = [
-
- {
- classId: 0,
- nonceId: 0,
- amount: 2000
-
- },
-
- ];
-
- await bondContract.issue(accounts[2],redemptionTransaction, {from: accounts[2]});
- assert.equal((await bondContract.balanceOf(accounts[2], 0, 0)).toNumber(), 2000);
- try {
- await bondContract.redeem(accounts[2], redemptionTransaction, {from:accounts[2]});
- }
- catch(e:any){
- assert.isTrue(true);
- }
-
- })
- //////////////////// UNIT TESTS //////////////////////////////
-
- it('should transfer bonds from an caller address to another', async () => {
- const transactionTransfer: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 500
- }];
- await bondContract.issue(lender, transactionTransfer, { from: lender });
- const tx = (await bondContract.transferFrom(lender, secondaryMarketBuyer, transactionTransfer, {from:lender})).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should issue bonds to a given address', async () => {
-
- const transactionIssue: _transaction[] = [
- {
- classId: 1,
- nonceId: firstNonceId,
- amount: 500
-
- }
- ];
- const tx = (await bondContract.issue(lender, transactionIssue)).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should redeem bonds from a given address', async () => {
- const transactionRedeem: _transaction[] = [
- {
- classId: 1,
- nonceId: firstNonceId,
- amount: 500
-
- }];
- await bondContract.issue(lender, transactionRedeem, {from: lender});
- sleep(7000);
-
- const tx = (await bondContract.redeem(lender, transactionRedeem, {from:lender})).tx;
-
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should burn bonds from a given address', async () => {
- const transactionRedeem: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 500
- }];
-
- await bondContract.issue(lender, transactionRedeem, {from: lender});
- const tx = (await bondContract.burn(lender, transactionRedeem, {from:lender})).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should approve spender to manage a given amount of bonds from the caller address', async () => {
- const transactionApprove: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 500
- }];
-
- await bondContract.issue(lender, transactionApprove, {from: lender});
- const tx = (await bondContract.approve(spender, transactionApprove)).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('setApprovalFor (called by bond owner) should be able to give operator permissions to manage bonds for given classId', async () => {
- const tx = (await bondContract.setApprovalFor(operator, true, { from: lender })).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should batch approve', async () => {
-
- const transactionApprove: _transaction[] = [
- {
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 500
- },
- { classId: 1, nonceId: 0, amount: 900 }
-
- ];
-
-
- await await bondContract.issue(spender,transactionApprove, {from:spender});
- const tx = (await bondContract.approve(spender, transactionApprove, {from:spender})).tx;
- console.log(tx)
- assert.isString(tx);
- })
-
- it('should return the active supply', async () => {
- const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber();
- console.log(activeSupply)
- assert.isNumber(activeSupply);
- })
-
- it('should return the redeemed supply', async () => {
- const redeemedSupply = (await bondContract.redeemedSupply(DBITClassId, firstNonceId)).toNumber();
- console.log(redeemedSupply)
- assert.isNumber(redeemedSupply);
- })
-
- it('should return the burned supply', async () => {
- const burnedSupply = (await bondContract.burnedSupply(DBITClassId, firstNonceId)).toNumber();
- console.log(burnedSupply)
- assert.isNumber(burnedSupply);
- })
-
- it('should return the total supply', async () => {
- const totalSupply = (await bondContract.totalSupply(DBITClassId, firstNonceId)).toNumber();
- console.log(totalSupply)
- assert.isNumber(totalSupply);
- })
-
- it('should return the balanceOf a bond of a given address', async () => {
- const balanceOf = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber();
- console.log(balanceOf)
- assert.isNumber(balanceOf);
- })
-
- it('should return the symbol of a class of bond', async () => {
- let metadataId = 0;
- const symbol: {
- stringValue: string;
- uintValue: BN;
- addressValue: string;
- boolValue: boolean;
- } = (await bondContract.classValues(DBITClassId, metadataId));
- console.log(JSON.stringify(symbol));
- assert.isString(symbol.stringValue);
- })
-
- it('should return the Values for given bond class', async () => {
- const metadataId = 0;
-
- let _transactionIssuer: _transaction[]
- =
- [{
- classId: DBITClassId,
- nonceId: firstNonceId,
- amount: 7000
- }];
-
- await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
- const valuesClass = (await bondContract.classValues(DBITClassId, metadataId));
- console.log("class infos: ", JSON.stringify(valuesClass));
- assert.isString(valuesClass.toString());
- })
-
- it('should return the infos of a nonce for given bond class', async () => {
- const metadataId = 0;
- const infos = (await bondContract.nonceValues(DBITClassId, firstNonceId, metadataId));
- console.log("nonce infos: ", JSON.stringify(infos))
- assert.isString(infos.toString());
- })
-
- it('should return if an operator is approved on a class and nonce given for an address', async () => {
- const isApproved = (await bondContract.isApprovedFor(lender, operator));
- console.log("operator is Approved? : ", isApproved)
- assert.isBoolean(isApproved);
- })
-
- it('should return if its redeemable', async () => {
- let _transactionIssuer: _transaction[]
- =
- [{
- classId: 1,
- nonceId: 1,
- amount: 7000
- }];
-
- await bondContract.issue(accounts[1], _transactionIssuer, { from: accounts[1] })
- const getProgress = await bondContract.getProgress(1,1);
- console.log("is Redeemable? : ", getProgress[1].toNumber() >= 0)
- assert.isNumber(getProgress[1].toNumber());
-
- })
-
- it('should set allowance of a spender', async () => {
-
- const allowance = (await bondContract.allowance(lender, spender, DBITClassId, firstNonceId, {from:lender})).toNumber();
- console.log("allowance : ", allowance)
- assert.isNumber(allowance);
- })
-
- it('should return if operator is approved for', async () => {
- const isApproved = (await bondContract.isApprovedFor(lender, operator));
- console.log("operator is Approved? : ", isApproved)
- assert.isTrue(isApproved);
- })
-
-});
diff --git a/assets/eip-3475/Metadata.md b/assets/eip-3475/Metadata.md
deleted file mode 100644
index ac7c36f..0000000
--- a/assets/eip-3475/Metadata.md
+++ /dev/null
@@ -1,92 +0,0 @@
-# Metadata standards
-
-
-This documentation consists of various JSON schemas (examples or standards) that can be referenced by the reader of this EIP for implementing EIP-3475 bonds storage.
-
-## 1. Description metadata:
-
-```json
-[
- {
- "title": "defining the title information",
- "_type": "explaining the type of the title information added",
- "description": "little description about the information stored in the bond",
- }
-]
-```
-
-Example: adding details in bonds describing the local jurisdiction of the bonds where it's issued:
-
-```json
-{
-"title": "localisation",
-"_type": "string",
-"description": "jurisdiction law codes compatibility"
-"values": ["fr ", "de", "ch"]
-}
-```
-The 'values' field defined above can also be ISO codes or other hex standard representation.
-## 2. Nonce metadata:
-
-- **Information defining the state of the bond**
-
-```json
-[
- {
- "title": "maturity",
- "_type": "uint",
- "description": "Lorem ipsum...",
- "values": [0, 0, 0]
- }
-]
-```
-
-
-## 3. Class metadata:
-
-```json
-[
- {
- "title": "symbol",
- "_type": "string",
- "description": "Lorem ipsum...",
- "values": ["Class symbol 1", "Class symbol 2", "Class symbol 3"],
- },
- {
- "title": "issuer",
- "_type": "string",
- "description": "Lorem ipsum...",
- "values": ["Issuer name 1", "Issuer name 2", "Issuer name 3"],
- },
-
- {
- "title": "issuer_address",
- "_type": "address",
- "description": "Lorem ipsum...",
- "values":["Address 1.", "Address 2", "Address 3"]
- },
-
- {
- "title": "class_type",
- "_type": "string",
- "description": "Lorem ipsum...",
- "values": ["Class Type 1", "Class Type 2", "Class Type 3"]
- },
-
- {
- "title": "token_address",
- "_type": "address",
- "description": "Lorem ipsum...",
- "values":["Address 1.", "Address 2", "Address 3"]
- },
-
- {
- "title": "period",
- "_type": "uint",
- "description": "Lorem ipsum...",
- "values": [0, 0, 0]
- }
-]
-```
-## Examples of other standards:
- - ISO-20022 standard is the recently adopted standard by banks for communicating financial operators (Banks, trading intermediaries, underwriters) that also include bond operations.
diff --git a/assets/eip-3475/interfaces/IERC3475.sol b/assets/eip-3475/interfaces/IERC3475.sol
deleted file mode 100644
index 9fa2b1b..0000000
--- a/assets/eip-3475/interfaces/IERC3475.sol
+++ /dev/null
@@ -1,218 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-
-pragma solidity ^0.8.0;
-
-
-interface IERC3475 {
- // STRUCTURE
- /**
- * @dev Values structure of the Metadata
- */
- struct Values {
- string stringValue;
- uint uintValue;
- address addressValue;
- bool boolValue;
- }
- /**
- * @dev structure allows to define particular bond metadata (ie the values in the class as well as nonce inputs).
- * @notice 'title' defining the title information,
- * @notice '_type' explaining the data type of the title information added (eg int, bool, address),
- * @notice 'description' explains little description about the information stored in the bond",
- */
- struct Metadata {
- string title;
- string _type;
- string description;
- }
- /**
- * @dev structure that defines the parameters for specific issuance of bonds and amount which are to be transferred/issued/given allowance, etc.
- * @notice this structure is used to streamline the input parameters for functions of this standard with that of other Token standards like ERC20.
- * @classId is the class id of the bond.
- * @nonceId is the nonce id of the given bond class. This param is for distinctions of the issuing conditions of the bond.
- * @amount is the amount of the bond that will be transferred.
- */
- struct Transaction {
- uint256 classId;
- uint256 nonceId;
- uint256 _amount;
- }
-
- // WRITABLES
- /**
- * @dev allows the transfer of a bond from one address to another (either single or in batches).
- * @param _from is the address of the holder whose balance is about to decrease.
- * @param _to is the address of the recipient whose balance is about to increase.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be transferred}.
- */
- function transferFrom(address _from, address _to, Transaction[] calldata _transactions) external;
- /**
- * @dev allows the transfer of allowance from one address to another (either single or in batches).
- * @param _from is the address of the holder whose balance about to decrease.
- * @param _to is the address of the recipient whose balance is about to increased.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be allowed to transferred}.
- */
- function transferAllowanceFrom(address _from, address _to, Transaction[] calldata _transactions) external;
- /**
- * @dev allows issuing of any number of bond types to an address(either single/batched issuance).
- * The calling of this function needs to be restricted to bond issuer contract.
- * @param _to is the address to which the bond will be issued.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be issued for given whitelisted bond}.
- */
- function issue(address _to, Transaction[] calldata _transactions) external;
- /**
- * @dev allows redemption of any number of bond types from an address.
- * The calling of this function needs to be restricted to bond issuer contract.
- * @param _from is the address _from which the bond will be redeemed.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be redeemed for given whitelisted bond}.
- */
- function redeem(address _from, Transaction[] calldata _transactions) external;
-
- /**
- * @dev allows the transfer of any number of bond types from an address to another.
- * The calling of this function needs to be restricted to bond issuer contract.
- * @param _from is the address of the holder whose balance about to decrees.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be redeemed for given whitelisted bond}.
- */
- function burn(address _from, Transaction[] calldata _transactions) external;
-
- /**
- * @dev Allows _spender to withdraw from your account multiple times, up to the amount.
- * @notice If this function is called again, it overwrites the current allowance with amount.
- * @param _spender is the address the caller approve for his bonds.
- * @param _transactions is the object defining {class,nonce and amount of the bonds to be approved for given whitelisted bond}.
- */
- function approve(address _spender, Transaction[] calldata _transactions) external;
-
- /**
- * @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens.
- * @dev MUST emit the ApprovalForAll event on success.
- * @param _operator Address to add to the set of authorized operators
- * @param _approved "True" if the operator is approved, "False" to revoke approval.
- */
- function setApprovalFor(address _operator, bool _approved) external;
-
- // READABLES
-
- /**
- * @dev Returns the total supply of the bond in question.
- */
- function totalSupply(uint256 classId, uint256 nonceId) external view returns (uint256);
-
- /**
- * @dev Returns the redeemed supply of the bond in question.
- */
- function redeemedSupply(uint256 classId, uint256 nonceId) external view returns (uint256);
-
- /**
- * @dev Returns the active supply of the bond in question.
- */
- function activeSupply(uint256 classId, uint256 nonceId) external view returns (uint256);
-
- /**
- * @dev Returns the burned supply of the bond in question.
- */
- function burnedSupply(uint256 classId, uint256 nonceId) external view returns (uint256);
-
- /**
- * @dev Returns the balance of the giving bond classId and bond nonce.
- */
- function balanceOf(address _account, uint256 classId, uint256 nonceId) external view returns (uint256);
-
- /**
- * @dev Returns the JSON metadata of the classes.
- * The metadata SHOULD follow a set of structure explained later in eip-3475.md
- * @param metadataId is the index corresponding to the class parameter that you want to return from mapping.
- */
- function classMetadata(uint256 metadataId) external view returns ( Metadata memory);
-
- /**
- * @dev Returns the JSON metadata of the Values of the nonces in the corresponding class.
- * @param classId is the specific classId of which you want to find the metadata of the corresponding nonce.
- * @param metadataId is the index corresponding to the class parameter that you want to return from mapping.
- * @notice The metadata SHOULD follow a set of structure explained later in metadata section.
- */
- function nonceMetadata(uint256 classId, uint256 metadataId) external view returns ( Metadata memory);
-
- /**
- * @dev Returns the values of the given classId.
- * @param classId is the specific classId of which we want to return the parameter.
- * @param metadataId is the index corresponding to the class parameter that you want to return from mapping.
- * the metadata SHOULD follow a set of structures explained in eip-3475.md
- */
- function classValues(uint256 classId, uint256 metadataId) external view returns ( Values memory);
-
- /**
- * @dev Returns the values of given nonceId.
- * @param metadataId index number of structure as explained in the metadata section in EIP-3475.
- * @param classId is the class of bonds for which you determine the nonce.
- * @param nonceId is the nonce for which you return the value struct info.
- * Returns the values object corresponding to the given value.
- */
- function nonceValues(uint256 classId, uint256 nonceId, uint256 metadataId) external view returns ( Values memory);
-
- /**
- * @dev Returns the information about the progress needed to redeem the bond identified by classId and nonceId.
- * @notice Every bond contract can have its own logic concerning the progress definition.
- * @param classId The class of bonds.
- * @param nonceId is the nonce of bonds for finding the progress.
- * Returns progressAchieved is the current progress achieved.
- * Returns progressRemaining is the remaining progress.
- */
- function getProgress(uint256 classId, uint256 nonceId) external view returns (uint256 progressAchieved, uint256 progressRemaining);
-
- /**
- * @notice Returns the amount that spender is still allowed to withdraw from _owner (for given classId and nonceId issuance)
- * @param _owner is the address whose owner allocates some amount to the _spender address.
- * @param classId is the classId of the bond.
- * @param nonceId is the nonce corresponding to the class for which you are approving the spending of total amount of bonds.
- */
- function allowance(address _owner, address _spender, uint256 classId, uint256 nonceId) external view returns (uint256);
- /**
- * @notice Queries the approval status of an operator for bonds (for all classes and nonce issuances of owner).
- * @param _owner is the current holder of the bonds for all classes/nonces.
- * @param _operator is the address with access to the bonds of _owner for transferring.
- * Returns "true" if the operator is approved, "false" if not.
- */
- function isApprovedFor(address _owner, address _operator) external view returns (bool);
-
- // EVENTS
- /**
- * @notice MUST trigger when tokens are transferred, including zero value transfers.
- * e.g:
- emit Transfer(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef, 0x492Af743654549b12b1B807a9E0e8F397E44236E,0x3d03B6C79B75eE7aB35298878D05fe36DC1fEf, [IERC3475.Transaction(1,14,500)])
- means that operator 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef wants to transfer 500 bonds of class 1 , Nonce 14 of owner 0x492Af743654549b12b1B807a9E0e8F397E44236E to address 0x3d03B6C79B75eE7aB35298878D05fe36DC1fEf.
- */
- event Transfer(address indexed _operator, address indexed _from, address indexed _to, Transaction[] _transactions);
- /**
- * @notice MUST trigger when tokens are issued
- * @notice Issue MUST trigger when Bonds are issued. This SHOULD not include zero value Issuing.
- * @dev This SHOULD not include zero value issuing.
- * @dev Issue MUST be triggered when the operator (i.e Bank address) contract issues bonds to the given entity.
- eg: emit Issue(_operator, 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,[IERC3475.Transaction(1,14,500)]);
- issue by address(operator) 500 Bonds(nonce14,class 0) to address 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.
- */
- event Issue(address indexed _operator, address indexed _to, Transaction[] _transactions);
- /**
- * @notice MUST trigger when tokens are redeemed.
- * @notice Redeem MUST trigger when Bonds are redeemed. This SHOULD not include zero value redemption.
- * eg: emit Redeem(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,0x492Af743654549b12b1B807a9E0e8F397E44236E,[IERC3475.Transaction(1,14,500)]);
- * this emit event when 5000 bonds of class 1, nonce 14 owned by address 0x492Af743654549b12b1B807a9E0e8F397E44236E are being redeemed by 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.
- */
- event Redeem(address indexed _operator, address indexed _from, Transaction[] _transactions);
- /**
- * @notice MUST trigger when tokens are burned
- * @dev `Burn` MUST trigger when the bonds are being redeemed via staking (or being invalidated) by the bank contract.
- * @dev `Burn` MUST trigger when Bonds are burned. This SHOULD not include zero value burning
- * @notice emit Burn(0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef,0x492Af743654549b12b1B807a9E0e8F397E44236E,[IERC3475.Transaction(1,14,500)]);
- * emits event when 5000 bonds of owner 0x492Af743654549b12b1B807a9E0e8F397E44236E of type (class 1, nonce 14) are burned by operator 0x2d03B6C79B75eE7aB35298878D05fe36DC1fE8Ef.
- */
- event Burn(address indexed _operator, address indexed _from, Transaction[] _transactions);
- /**
- * @dev MUST emit when approval for a second party/operator address to manage all bonds from a classId given for an owner address is enabled or disabled (absence of an event assumes disabled).
- * @dev its emitted when address(_owner) approves the address(_operator) to transfer his bonds.
- * @notice Approval MUST trigger when bond holders are approving an _operator. This SHOULD not include zero value approval.
- */
- event ApprovalFor(address indexed _owner, address indexed _operator, bool _approved);
-}
diff --git a/assets/eip-3525/README.md b/assets/eip-3525/README.md
deleted file mode 100644
index a2c57b6..0000000
--- a/assets/eip-3525/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# EIP-3525
-
-## Demonstration only
-
-The code included in this directory is ONLY for the purpose of demonstrating how to implement this proposal, it is not a full-featured implementation ready for production.
-
-So please DO NOT use the code here for purposes other than study.
diff --git a/assets/eip-3525/contracts/ERC3525.sol b/assets/eip-3525/contracts/ERC3525.sol
deleted file mode 100644
index b955f69..0000000
--- a/assets/eip-3525/contracts/ERC3525.sol
+++ /dev/null
@@ -1,223 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "ERC721Enumerable.sol";
-import "./interface/IERC3525.sol";
-import "./interface/IERC3525Metadata.sol";
-import "./interface/IERC3525Receiver.sol";
-
-contract ERC3525 is IERC3525, IERC3525Metadata, ERC721Enumerable {
- using Address for address;
- using Strings for uint256;
-
- struct ApproveData {
- address[] approvals;
- mapping(address => uint256) allowances;
- }
-
- /// @dev tokenId => values
- mapping(uint256 => uint256) internal _values;
-
- /// @dev tokenId => operator => units
- mapping(uint256 => ApproveData) private _approvedValues;
-
- /// @dev tokenId => slot
- mapping(uint256 => uint256) internal _slots;
-
- string private _name;
- string private _symbol;
- uint8 private _decimals;
-
- constructor( string memory name_, string memory symbol_, uint8 decimals_) ERC721(name_, symbol_) {
- _decimals = decimals_;
- }
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721Enumerable) returns (bool)
- {
- return
- interfaceId == type(IERC3525).interfaceId ||
- interfaceId == type(IERC3525Metadata).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- function valueDecimals() public view virtual override returns (uint8) {
- return _decimals;
- }
-
- function balanceOf(uint256 tokenId_) public view virtual override returns (uint256)
- {
- require( _exists(tokenId_), "ERC3525: balance query for nonexistent token");
- return _values[tokenId_];
- }
-
- function slotOf(uint256 tokenId_) public view virtual override returns (uint256)
- {
- require(_exists(tokenId_), "ERC3525: slot query for nonexistent token");
- return _slots[tokenId_];
- }
-
- function contractURI() public view virtual override returns (string memory)
- {
- string memory baseURI = _baseURI();
- return
- bytes(baseURI).length > 0
- ? string( abi.encodePacked( baseURI, "contract/", Strings.toHexString(uint256(uint160(address(this)))))) : "";
- }
-
- function slotURI(uint256 slot_) public view virtual override returns (string memory)
- {
- string memory baseURI = _baseURI();
- return
- bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, "slot/", slot_.toString())) : "";
- }
-
- function approve( uint256 tokenId_, address to_, uint256 value_) external payable virtual override {
- address owner = ERC721.ownerOf(tokenId_);
- require(to_ != owner, "ERC3525: approval to current owner");
-
- require(
- ERC721._isApprovedOrOwner(_msgSender(), tokenId_),
- "ERC3525: approve caller is not owner nor approved for all"
- );
-
- _approveValue(tokenId_, to_, value_);
- }
-
- function allowance(uint256 tokenId_, address operator_) public view virtual override returns (uint256)
- {
- return _approvedValues[tokenId_].allowances[operator_];
- }
-
- function transferFrom( uint256 fromTokenId_, address to_, uint256 value_) public payable virtual override returns (uint256) {
- _spendAllowance(_msgSender(), fromTokenId_, value_);
-
- uint256 newTokenId = _getNewTokenId(fromTokenId_);
- _mint(to_, newTokenId, _slots[fromTokenId_]);
- _transfer(fromTokenId_, newTokenId, value_);
-
- return newTokenId;
- }
-
- function transferFrom( uint256 fromTokenId_, uint256 toTokenId_, uint256 value_) public payable virtual override {
- _spendAllowance(_msgSender(), fromTokenId_, value_);
-
- _transfer(fromTokenId_, toTokenId_, value_);
- }
-
- function _mint( address to_, uint256 tokenId_, uint256 slot_) private {
- ERC721._mint(to_, tokenId_);
- _slots[tokenId_] = slot_;
- emit SlotChanged(tokenId_, 0, slot_);
- }
-
- function _mintValue( address to_, uint256 tokenId_, uint256 slot_, uint256 value_) internal virtual {
- require(to_ != address(0), "ERC3525: mint to the zero address");
- require(tokenId_ != 0, "ERC3525: cannot mint zero tokenId");
- require(!_exists(tokenId_), "ERC3525: token already minted");
-
- _mint(to_, tokenId_, slot_);
-
- _beforeValueTransfer(address(0), to_, 0, tokenId_, slot_, value_);
- _values[tokenId_] = value_;
- _afterValueTransfer(address(0), to_, 0, tokenId_, slot_, value_);
-
- emit TransferValue(0, tokenId_, value_);
- }
-
- function _burn(uint256 tokenId_) internal virtual override {
- address owner = ERC721.ownerOf(tokenId_);
- ERC721._burn(tokenId_);
-
- uint256 slot = _slots[tokenId_];
- uint256 value = _values[tokenId_];
-
- _beforeValueTransfer(owner, address(0), tokenId_, 0, slot, value);
- delete _slots[tokenId_];
- delete _values[tokenId_];
- _afterValueTransfer(owner, address(0), tokenId_, 0, slot, value);
-
- emit TransferValue(tokenId_, 0, value);
- emit SlotChanged(tokenId_, slot, 0);
- }
-
- function _transfer( uint256 fromTokenId_, uint256 toTokenId_, uint256 value_) internal virtual {
- require( _exists(fromTokenId_),
- "ERC35255: transfer from nonexistent token");
- require(_exists(toTokenId_), "ERC35255: transfer to nonexistent token");
-
- require( _values[fromTokenId_] >= value_,
- "ERC3525: transfer amount exceeds balance");
- require( _slots[fromTokenId_] == _slots[toTokenId_],
- "ERC3535: transfer to token with different slot");
-
- address from = ERC721.ownerOf(fromTokenId_);
- address to = ERC721.ownerOf(toTokenId_);
- _beforeValueTransfer(from, to, fromTokenId_, toTokenId_, _slots[fromTokenId_], value_);
-
- _values[fromTokenId_] -= value_;
- _values[toTokenId_] += value_;
-
- _afterValueTransfer(from, to, fromTokenId_, toTokenId_, _slots[fromTokenId_], value_);
-
- emit TransferValue(fromTokenId_, toTokenId_, value_);
- }
-
- function _spendAllowance( address operator_, uint256 tokenId_, uint256 value_) internal virtual {
- uint256 currentAllowance = ERC3525.allowance(tokenId_, operator_);
- if ( !_isApprovedOrOwner(operator_, tokenId_) && currentAllowance != type(uint256).max) {
- require( currentAllowance >= value_, "ERC3525: insufficient allowance");
- _approveValue(tokenId_, operator_, currentAllowance - value_);
- }
- }
-
- function _approveValue( uint256 tokenId_, address to_, uint256 value_) internal virtual {
- ApproveData storage approveData = _approvedValues[tokenId_];
- approveData.approvals.push(to_);
- approveData.allowances[to_] = value_;
-
- emit ApprovalValue(tokenId_, to_, value_);
- }
-
- function _getNewTokenId(uint256 fromTokenId_) internal virtual returns (uint256)
- {
- return ERC721Enumerable.totalSupply() + 1;
- }
-
- function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {
- //clear approve data
- uint256 length = _approvedValues[tokenId].approvals.length;
- for (uint256 i = 0; i < length; i++) {
- address approval = _approvedValues[tokenId].approvals[i];
- delete _approvedValues[tokenId].allowances[approval];
- }
- delete _approvedValues[tokenId].approvals;
- }
-
- function _afterTokenTransfer(address from, address to, uint256 tokenId) internal virtual override {}
-
- function _checkOnERC3525Received( uint256 fromTokenId_, uint256 toTokenId_, uint256 value_, bytes memory data_) private returns (bool) {
- address to = ERC721.ownerOf((toTokenId_));
- if (to.isContract() && IERC165(to).supportsInterface(type(IERC3525Receiver).interfaceId)) {
- try
- IERC3525Receiver(to).onERC3525Received( _msgSender(), fromTokenId_, toTokenId_, value_, data_)
- returns (bytes4 retval) {
- return retval == IERC3525Receiver.onERC3525Received.selector;
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert( "ERC3525: transfer to non ERC3525Receiver implementer");
- } else {
- // solhint-disable-next-line
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- } else {
- return true;
- }
- }
-
- function _beforeValueTransfer( address from_, address to_, uint256 fromTokenId_, uint256 toTokenId_, uint256 slot_, uint256 value_) internal virtual {}
-
- function _afterValueTransfer( address from_, address to_, uint256 fromTokenId_, uint256 toTokenId_, uint256 slot_, uint256 value_) internal virtual {}
-}
diff --git a/assets/eip-3525/contracts/ERC3525Example.sol b/assets/eip-3525/contracts/ERC3525Example.sol
deleted file mode 100644
index 16df657..0000000
--- a/assets/eip-3525/contracts/ERC3525Example.sol
+++ /dev/null
@@ -1,154 +0,0 @@
-//SPDX-License-Identifier: MIT
-pragma solidity ^0.8.0;
-
-import "./ERC3525.sol";
-import "StringConvertor.sol";
-import "base64.sol";
-
-/**
- * This is a demo contract for how to generate slot
- */
-contract ERC3525Example is ERC3525 {
- using StringConvertor for uint256;
-
- /**
- * @notice Properties of the slot, which determine the value of slot.
- */
- struct SlotDetail {
- string name;
- string description;
- string image;
- address underlying;
- uint8 vestingType;
- uint32 maturity;
- uint32 term;
- }
-
- // slot => slotDetail
- mapping(uint256 => SlotDetail) private _slotDetails;
-
- uint256 constant _externalMintMaxId = 1000000000;
-
- constructor( string memory name_, string memory symbol_, uint8 decimals_) ERC3525(name_, symbol_, decimals_) {}
-
- function mint( string memory slotName_, string memory slotDescription_, string memory slotImage_,
- uint256 tokenId_, address underlying_, uint8 vestingType_, uint32 maturity_, uint32 term_, uint256 value_) public {
- require(tokenId_ < _externalMintMaxId, "ERC3525: tokenId is too large");
- uint256 slot = _getSlot(underlying_, vestingType_, maturity_, term_);
- _slotDetails[slot] = SlotDetail({
- name: slotName_,
- description: slotDescription_,
- image: slotImage_,
- underlying: underlying_,
- vestingType: vestingType_,
- maturity: maturity_,
- term: term_
- });
-
- ERC3525._mintValue(_msgSender(), tokenId_, slot, value_);
- }
-
- function getSlotDetail(uint256 slot_) public view returns (SlotDetail memory) {
- return _slotDetails[slot_];
- }
-
- function _getNewTokenId(uint256 fromTokenId_) internal virtual override returns (uint256) {
- return 1000000000 + fromTokenId_;
- }
-
- /**
- * @dev Generate the value of slot by utilizing keccak256 algorithm to calculate the hash
- * value of multi properties.
- */
- function _getSlot( address underlying_, uint8 vestingType_, uint32 maturity_, uint32 term_) internal pure virtual returns (uint256 slot_) {
- return
- uint256(
- keccak256(
- abi.encodePacked(
- underlying_,
- vestingType_,
- maturity_,
- term_
- )
- )
- );
- }
-
- function slotURI(uint256 slot_) public view virtual override returns (string memory) {
- return
- string(
- abi.encodePacked(
- /* solhint-disable */
- "data:application/json;base64,",
- Base64.encode(
- abi.encodePacked(
- '{"name":"',
- _slotDetails[slot_].name,
- '","description":"',
- _slotDetails[slot_].description,
- '","image":"',
- _slotDetails[slot_].image,
- '","properties":',
- _slotProperties(slot_),
- "}"
- )
- )
- /* solhint-enable */
- )
- );
- }
-
- /**
- * @dev Generate the content of the `properties` field of `slotURI`.
- */
- function _slotProperties(uint256 slot_) internal view returns (string memory) {
- SlotDetail storage slotDetail = _slotDetails[slot_];
- return
- string(
- /* solhint-disable */
- abi.encodePacked(
- "[",
- abi.encodePacked(
- '{"name":"underlying",',
- '"description":"Address of the underlying token locked in this contract.",',
- '"value":"',
- Strings.toHexString(
- uint256(uint160(slotDetail.underlying))
- ),
- '",',
- '"order":1,',
- '"display_type":"string"},'
- ),
- abi.encodePacked(
- '{"name":"vesting_type",',
- '"description":"Vesting type that represents the releasing mode of underlying assets.",',
- '"value":',
- uint256(slotDetail.vestingType).toString(),
- ",",
- '"order":2,',
- '"display_type":"number"},'
- ),
- abi.encodePacked(
- '{"name":"maturity",',
- '"description":"Maturity that all underlying assets would be completely released.",',
- '"value":',
- uint256(slotDetail.maturity).toString(),
- ",",
- '"order":3,',
- '"display_type":"date"},'
- ),
- abi.encodePacked(
- '{"name":"term",',
- '"description":"The length of the locking period (in seconds)",',
- '"value":',
- uint256(slotDetail.term).toString(),
- ",",
- '"order":4,',
- '"display_type":"number"}'
- ),
- "]"
- )
- /* solhint-enable */
- );
- }
-}
diff --git a/assets/eip-3525/contracts/ERC3525SlotApprovable.sol b/assets/eip-3525/contracts/ERC3525SlotApprovable.sol
deleted file mode 100644
index 871df34..0000000
--- a/assets/eip-3525/contracts/ERC3525SlotApprovable.sol
+++ /dev/null
@@ -1,74 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC3525.sol";
-import "./interface/IERC3525SlotApprovable.sol";
-
-abstract contract ERC3525SlotApprovable is ERC3525, IERC3525SlotApprovable {
- // @dev owner => slot => operator => approved
- mapping(address => mapping(uint256 => mapping(address => bool)))
- private _slotApprovals;
-
- function setApprovalForSlot( address owner_, uint256 slot_, address operator_, bool approved_) external payable virtual override {
- require(
- _msgSender() == owner_ || isApprovedForAll(owner_, _msgSender()),
- "ERC3525SlotApprovable: caller is not owner nor approved for all"
- );
- _setApprovalForSlot(owner_, slot_, operator_, approved_);
- }
-
- function isApprovedForSlot( address owner_, uint256 slot_, address operator_) public view virtual override returns (bool) {
- return _slotApprovals[owner_][slot_][operator_];
- }
-
- function approve(address to_, uint256 tokenId_) public virtual override(IERC721, ERC721) {
- address owner = ERC721.ownerOf(tokenId_);
- uint256 slot = ERC3525.slotOf(tokenId_);
- require(to_ != owner, "ERC3525: approval to current owner");
-
- require(
- _msgSender() == owner ||
- ERC721.isApprovedForAll(owner, _msgSender()) ||
- ERC3525SlotApprovable.isApprovedForSlot(
- owner,
- slot,
- _msgSender()
- ),
- "ERC3525: caller is not owner nor approved"
- );
-
- _approve(to_, tokenId_);
- }
-
- function approve(uint256 tokenId_, address to_, uint256 value_) external payable virtual override(IERC3525, ERC3525) {
- address owner = ERC721.ownerOf(tokenId_);
- require(to_ != owner, "ERC3525: approval to current owner");
-
- require(
- _isApprovedOrOwner(_msgSender(), tokenId_),
- "ERC3525: caller is not owner nor approved"
- );
-
- _approveValue(tokenId_, to_, value_);
- }
-
- function _setApprovalForSlot( address owner_, uint256 slot_, address operator_, bool approved_) internal virtual {
- require(owner_ != operator_, "ERC3525SlotApprovable: approve to owner");
- _slotApprovals[owner_][slot_][operator_] = approved_;
- emit ApprovalForSlot(owner_, slot_, operator_, approved_);
- }
-
- function _isApprovedOrOwner(address operator_, uint256 tokenId_) internal view virtual override returns (bool) {
- require(
- _exists(tokenId_),
- "ERC3525: operator query for nonexistent token"
- );
- address owner = ERC721.ownerOf(tokenId_);
- uint256 slot = ERC3525.slotOf(tokenId_);
- return (operator_ == owner ||
- getApproved(tokenId_) == operator_ ||
- ERC721.isApprovedForAll(owner, operator_) ||
- ERC3525SlotApprovable.isApprovedForSlot(owner, slot, operator_));
- }
-}
diff --git a/assets/eip-3525/contracts/ERC3525SlotEnumerable.sol b/assets/eip-3525/contracts/ERC3525SlotEnumerable.sol
deleted file mode 100644
index 7be3711..0000000
--- a/assets/eip-3525/contracts/ERC3525SlotEnumerable.sol
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC3525.sol";
-import "./interface/IERC3525SlotEnumerable.sol";
-
-abstract contract ERC3525SlotEnumerable is ERC3525, IERC3525SlotEnumerable {
- struct SlotData {
- uint256 slot;
- uint256[] slotTokens;
- // mapping(uint256 => uint256) slotTokensIndex;
- }
-
- // slot => tokenId => index
- mapping(uint256 => mapping(uint256 => uint256)) private _slotTokensIndex;
-
- SlotData[] private _allSlots;
-
- // slot => index
- mapping(uint256 => uint256) private _allSlotsIndex;
-
- function slotCount() public view virtual override returns (uint256) {
- return _allSlots.length;
- }
-
- function slotByIndex(uint256 index_) public view virtual override returns (uint256) {
- require(
- index_ < ERC3525SlotEnumerable.slotCount(),
- "ERC3525SlotEnumerable: slot index out of bounds"
- );
- return _allSlots[index_].slot;
- }
-
- function _slotExists(uint256 slot_) internal view virtual returns (bool) {
- return
- _allSlots.length != 0 &&
- _allSlots[_allSlotsIndex[slot_]].slot == slot_;
- }
-
- function tokenSupplyInSlot(uint256 slot_) public view virtual override returns (uint256) {
- if (!_slotExists(slot_)) {
- return 0;
- }
- return _allSlots[_allSlotsIndex[slot_]].slotTokens.length;
- }
-
- function tokenInSlotByIndex(uint256 slot_, uint256 index_) public view virtual override returns (uint256) {
- require(
- index_ < ERC3525SlotEnumerable.tokenSupplyInSlot(slot_),
- "ERC3525SlotEnumerable: slot token index out of bounds"
- );
- return _allSlots[_allSlotsIndex[slot_]].slotTokens[index_];
- }
-
- function _tokenExistsInSlot(uint256 slot_, uint256 tokenId_) private view returns (bool) {
- SlotData storage slotData = _allSlots[_allSlotsIndex[slot_]];
- return
- slotData.slotTokens.length > 0 &&
- slotData.slotTokens[_slotTokensIndex[slot_][tokenId_]] == tokenId_;
- }
-
- function _beforeValueTransfer( address from_, address to_, uint256 fromTokenId_, uint256 toTokenId_, uint256 slot_,
- uint256 value_) internal virtual override {
- if (from_ == address(0) && fromTokenId_ == 0 && !_slotExists(slot_)) {
- SlotData memory slotData = SlotData({
- slot: slot_,
- slotTokens: new uint256[](0)
- });
- _addSlotToAllSlotsEnumeration(slotData);
- }
-
- //Shh - currently unused
- to_;
- toTokenId_;
- value_;
- }
-
- function _afterValueTransfer( address from_, address to_, uint256 fromTokenId_, uint256 toTokenId_, uint256 slot_,
- uint256 value_) internal virtual override {
- if (
- from_ == address(0) &&
- fromTokenId_ == 0 &&
- !_tokenExistsInSlot(slot_, toTokenId_)
- ) {
- _addTokenToSlotEnumeration(slot_, toTokenId_);
- } else if (
- to_ == address(0) &&
- toTokenId_ == 0 &&
- _tokenExistsInSlot(slot_, fromTokenId_)
- ) {
- _removeTokenFromSlotEnumeration(slot_, fromTokenId_);
- }
-
- //Shh - currently unused
- value_;
- }
-
- function _addSlotToAllSlotsEnumeration(SlotData memory slotData) private {
- _allSlotsIndex[slotData.slot] = _allSlots.length;
- _allSlots.push(slotData);
- }
-
- function _addTokenToSlotEnumeration(uint256 slot_, uint256 tokenId_) private {
- SlotData storage slotData = _allSlots[_allSlotsIndex[slot_]];
- _slotTokensIndex[slot_][tokenId_] = slotData.slotTokens.length;
- slotData.slotTokens.push(tokenId_);
- }
-
- function _removeTokenFromSlotEnumeration(uint256 slot_, uint256 tokenId_) private {
- SlotData storage slotData = _allSlots[_allSlotsIndex[slot_]];
- uint256 lastTokenIndex = slotData.slotTokens.length - 1;
- uint256 lastTokenId = slotData.slotTokens[lastTokenIndex];
- uint256 tokenIndex = slotData.slotTokens[tokenId_];
-
- slotData.slotTokens[tokenIndex] = lastTokenId;
- _slotTokensIndex[slot_][lastTokenId] = tokenIndex;
-
- delete _slotTokensIndex[slot_][tokenId_];
- slotData.slotTokens.pop();
- }
-}
diff --git a/assets/eip-3525/contracts/interface/IERC3525.sol b/assets/eip-3525/contracts/interface/IERC3525.sol
deleted file mode 100644
index d62af24..0000000
--- a/assets/eip-3525/contracts/interface/IERC3525.sol
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "IERC165.sol";
-import "IERC721.sol";
-
-/**
- * @title ERC-3525 Semi-Fungible Token Standard
- * @dev See https://eips.ethereum.org/EIPS/eip-3525
- * Note: the ERC-165 identifier for this interface is 0xc97ae3d5.
- */
-interface IERC3525 is IERC165, IERC721 {
- /**
- * @dev MUST emit when value of a token is transferred to another token with the same slot,
- * including zero value transfers (_value == 0) as well as transfers when tokens are created
- * (`_fromTokenId` == 0) or destroyed (`_toTokenId` == 0).
- * @param _fromTokenId The token id to transfer value from
- * @param _toTokenId The token id to transfer value to
- * @param _value The transferred value
- */
- event TransferValue( uint256 indexed _fromTokenId, uint256 indexed _toTokenId, uint256 _value);
-
- /**
- * @dev MUST emits when the approval value of a token is set or changed.
- * @param _tokenId The token to approve
- * @param _operator The operator to approve for
- * @param _value The maximum value that `_operator` is allowed to manage
- */
- event ApprovalValue( uint256 indexed _tokenId, address indexed _operator, uint256 _value);
-
- /**
- * @dev MUST emit when the slot of a token is set or changed.
- * @param _tokenId The token of which slot is set or changed
- * @param _oldSlot The previous slot of the token
- * @param _newSlot The updated slot of the token
- */
- event SlotChanged( uint256 indexed _tokenId, uint256 indexed _oldSlot, uint256 indexed _newSlot);
-
- /**
- * @notice Get the number of decimals the token uses for value - e.g. 6, means the user
- * representation of the value of a token can be calculated by dividing it by 1,000,000.
- * Considering the compatibility with third-party wallets, this function is defined as
- * `valueDecimals()` instead of `decimals()` to avoid conflict with ERC20 tokens.
- * @return The number of decimals for value
- */
- function valueDecimals() external view returns (uint8);
-
- /**
- * @notice Get the value of a token.
- * @param _tokenId The token for which to query the balance
- * @return The value of `_tokenId`
- */
- function balanceOf(uint256 _tokenId) external view returns (uint256);
-
- /**
- * @notice Get the slot of a token.
- * @param _tokenId The identifier for a token
- * @return The slot of the token
- */
- function slotOf(uint256 _tokenId) external view returns (uint256);
-
- /**
- * @notice Allow an operator to manage the value of a token, up to the `_value` amount.
- * @dev MUST revert unless caller is the current owner, an authorized operator, or the approved
- * address for `_tokenId`.
- * MUST emit ApprovalValue event.
- * @param _tokenId The token to approve
- * @param _operator The operator to be approved
- * @param _value The maximum value of `_toTokenId` that `_operator` is allowed to manage
- */
- function approve( uint256 _tokenId, address _operator, uint256 _value) external payable;
-
- /**
- * @notice Get the maximum value of a token that an operator is allowed to manage.
- * @param _tokenId The token for which to query the allowance
- * @param _operator The address of an operator
- * @return The current approval value of `_tokenId` that `_operator` is allowed to manage
- */
- function allowance(uint256 _tokenId, address _operator) external view returns (uint256);
-
- /**
- * @notice Transfer value from a specified token to another specified token with the same slot.
- * @dev Caller MUST be the current owner, an authorized operator or an operator who has been
- * approved the whole `_fromTokenId` or part of it.
- * MUST revert if `_fromTokenId` or `_toTokenId` is zero token id or does not exist.
- * MUST revert if slots of `_fromTokenId` and `_toTokenId` do not match.
- * MUST revert if `_value` exceeds the balance of `_fromTokenId` or its allowance to the
- * operator.
- * MUST emit `TransferValue` event.
- * @param _fromTokenId The token to transfer value from
- * @param _toTokenId The token to transfer value to
- * @param _value The transferred value
- */
- function transferFrom( uint256 _fromTokenId, uint256 _toTokenId, uint256 _value) external payable;
-
- /**
- * @notice Transfer value from a specified token to an address. The caller should confirm that
- * `_to` is capable of receiving ERC3525 tokens.
- * @dev This function MUST create a new ERC3525 token with the same slot for `_to` to receive
- * the transferred value.
- * MUST revert if `_fromTokenId` is zero token id or does not exist.
- * MUST revert if `_to` is zero address.
- * MUST revert if `_value` exceeds the balance of `_fromTokenId` or its allowance to the
- * operator.
- * MUST emit `Transfer` and `TransferValue` events.
- * @param _fromTokenId The token to transfer value from
- * @param _to The address to transfer value to
- * @param _value The transferred value
- * @return ID of the new token created for `_to` which receives the transferred value
- */
- function transferFrom( uint256 _fromTokenId, address _to, uint256 _value) external payable returns (uint256);
-}
diff --git a/assets/eip-3525/contracts/interface/IERC3525Metadata.sol b/assets/eip-3525/contracts/interface/IERC3525Metadata.sol
deleted file mode 100644
index 6d90fba..0000000
--- a/assets/eip-3525/contracts/interface/IERC3525Metadata.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC3525.sol";
-import "IERC721Metadata.sol";
-
-/**
- * @title ERC-3525 Semi-Fungible Token Standard, optional extension for metadata
- * @dev Interfaces for any contract that wants to support query of the Uniform Resource Identifier
- * (URI) for the ERC3525 contract as well as a specified slot.
- * Because of the higher reliability of data stored in smart contracts compared to data stored in
- * centralized systems, it is recommended that metadata, including `contractURI`, `slotURI` and
- * `tokenURI`, be directly returned in JSON format, instead of being returned with a url pointing
- * to any resource stored in a centralized system.
- * See https://eips.ethereum.org/EIPS/eip-3525
- * Note: the ERC-165 identifier for this interface is 0xe1600902.
- */
-interface IERC3525Metadata is IERC3525, IERC721Metadata {
- /**
- * @notice Returns the Uniform Resource Identifier (URI) for the current ERC3525 contract.
- * @dev This function SHOULD return the URI for this contract in JSON format, starting with
- * header `data:application/json;`.
- * See https://eips.ethereum.org/EIPS/eip-3525 for the JSON schema for contract URI.
- * @return The JSON formatted URI of the current ERC3525 contract
- */
- function contractURI() external view returns (string memory);
-
- /**
- * @notice Returns the Uniform Resource Identifier (URI) for the specified slot.
- * @dev This function SHOULD return the URI for `_slot` in JSON format, starting with header
- * `data:application/json;`.
- * See https://eips.ethereum.org/EIPS/eip-3525 for the JSON schema for slot URI.
- * @return The JSON formatted URI of `_slot`
- */
- function slotURI(uint256 _slot) external view returns (string memory);
-}
diff --git a/assets/eip-3525/contracts/interface/IERC3525Receiver.sol b/assets/eip-3525/contracts/interface/IERC3525Receiver.sol
deleted file mode 100644
index 86e0d61..0000000
--- a/assets/eip-3525/contracts/interface/IERC3525Receiver.sol
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-/**
- * @title ERC3525 token receiver interface
- * @dev Interface for any contract that wants to support safeTransfers from ERC3525 contracts.
- * Note: the ERC-165 identifier for this interface is 0x009ce20b.
- */
-interface IERC3525Receiver {
- /**
- * @notice Handle the receipt of an ERC3525 token value.
- * @dev An ERC3525 smart contract MUST call this function on the recipient contract after a
- * value transfer (i.e. `safeTransferFrom(uint256,uint256,uint256,bytes)`).
- * MUST return 0x009ce20b (i.e. `bytes4(keccak256('onERC3525Received(address,uint256,uint256,
- * uint256,bytes)'))`) if the transfer is accepted.
- * MUST revert or return any value other than 0x009ce20b if the transfer is rejected.
- * @param _operator The address which triggered the transfer
- * @param _fromTokenId The token id to transfer value from
- * @param _toTokenId The token id to transfer value to
- * @param _value The transferred value
- * @param _data Additional data with no specified format
- * @return `bytes4(keccak256('onERC3525Received(address,uint256,uint256,uint256,bytes)'))`
- * unless the transfer is rejected.
- */
- function onERC3525Received(address _operator, uint256 _fromTokenId, uint256 _toTokenId, uint256 _value, bytes calldata _data) external returns (bytes4);
-}
\ No newline at end of file
diff --git a/assets/eip-3525/contracts/interface/IERC3525SlotApprovable.sol b/assets/eip-3525/contracts/interface/IERC3525SlotApprovable.sol
deleted file mode 100644
index 1bfea70..0000000
--- a/assets/eip-3525/contracts/interface/IERC3525SlotApprovable.sol
+++ /dev/null
@@ -1,47 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC3525.sol";
-
-/**
- * @title ERC-3525 Semi-Fungible Token Standard, optional extension for approval of slot level
- * @dev Interfaces for any contract that wants to support approval of slot level, which allows an
- * operator to manage one's tokens with the same slot.
- * See https://eips.ethereum.org/EIPS/eip-3525
- * Note: the ERC-165 identifier for this interface is 0xb688be58.
- */
-interface IERC3525SlotApprovable is IERC3525 {
- /**
- * @dev MUST emits when an operator is approved or disapproved to manage all of `_owner`'s
- * tokens with the same slot.
- * @param _owner The address whose tokens are approved
- * @param _slot The slot to approve, all of `_owner`'s tokens with this slot are approved
- * @param _operator The operator being approved or disapproved
- * @param _approved Identify if `_operator` is approved or disapproved
- */
- event ApprovalForSlot( address indexed _owner, uint256 indexed _slot, address indexed _operator, bool _approved);
-
- /**
- * @notice Approve or disapprove an operator to manage all of `_owner`'s tokens with the
- * specified slot.
- * @dev Caller SHOULD be `_owner` or an operator who has been authorized through
- * `setApprovalForAll`.
- * MUST emit ApprovalSlot event.
- * @param _owner The address that owns the ERC3525 tokens
- * @param _slot The slot of tokens being queried approval of
- * @param _operator The address for whom to query approval
- * @param _approved Identify if `_operator` would be approved or disapproved
- */
- function setApprovalForSlot( address _owner, uint256 _slot, address _operator, bool _approved) external payable;
-
- /**
- * @notice Query if `_operator` is authorized to manage all of `_owner`'s tokens with the
- * specified slot.
- * @param _owner The address that owns the ERC3525 tokens
- * @param _slot The slot of tokens being queried approval of
- * @param _operator The address for whom to query approval
- * @return True if `_operator` is authorized to manage all of `_owner`'s tokens with `_slot`,
- * false otherwise.
- */
- function isApprovedForSlot( address _owner, uint256 _slot, address _operator) external view returns (bool);
-}
diff --git a/assets/eip-3525/contracts/interface/IERC3525SlotEnumerable.sol b/assets/eip-3525/contracts/interface/IERC3525SlotEnumerable.sol
deleted file mode 100644
index f10086f..0000000
--- a/assets/eip-3525/contracts/interface/IERC3525SlotEnumerable.sol
+++ /dev/null
@@ -1,42 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC3525.sol";
-import "IERC721Enumerable.sol";
-
-/**
- * @title ERC-3525 Semi-Fungible Token Standard, optional extension for slot enumeration
- * @dev Interfaces for any contract that wants to support enumeration of slots as well as tokens
- * with the same slot.
- * See https://eips.ethereum.org/EIPS/eip-3525
- * Note: the ERC-165 identifier for this interface is 0x3b741b9e.
- */
-interface IERC3525SlotEnumerable is IERC3525, IERC721Enumerable {
- /**
- * @notice Get the total amount of slots stored by the contract.
- * @return The total amount of slots
- */
- function slotCount() external view returns (uint256);
-
- /**
- * @notice Get the slot at the specified index of all slots stored by the contract.
- * @param _index The index in the slot list
- * @return The slot at `index` of all slots.
- */
- function slotByIndex(uint256 _index) external view returns (uint256);
-
- /**
- * @notice Get the total amount of tokens with the same slot.
- * @param _slot The slot to query token supply for
- * @return The total amount of tokens with the specified `_slot`
- */
- function tokenSupplyInSlot(uint256 _slot) external view returns (uint256);
-
- /**
- * @notice Get the token at the specified index of all tokens with the same slot.
- * @param _slot The slot to query tokens with
- * @param _index The index in the token list of the slot
- * @return The token ID at `_index` of all tokens with `_slot`
- */
- function tokenInSlotByIndex(uint256 _slot, uint256 _index) external view returns (uint256);
-}
diff --git a/assets/eip-3525/test/test.ts b/assets/eip-3525/test/test.ts
deleted file mode 100644
index 4ca5f3a..0000000
--- a/assets/eip-3525/test/test.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import { BigNumber } from "ethers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { ERC3525Example } from "../typechain";
-import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
-
-const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
-const ZERO_TOKEN_ID = 0;
-
-let owner: SignerWithAddress,
- approval: SignerWithAddress,
- to: SignerWithAddress;
-let token: ERC3525Example;
-let snapshotId: any;
-const fromTokenId = 35251;
-const toTokenId = 35252;
-const fromValue = 10000000000;
-const approveValue = 5000000000;
-const transferValue = 3000000000;
-const slotDetails = {
- name: "Test Slot",
- description: "Test Slot Description",
- image: "https://example.com/slot/test_slot.png",
- underlying: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
- vestingType: 1,
- maturity: 1658989800,
- term: 2592000,
- value: fromValue,
-};
-
-describe("ERC3525", function () {
- before(async () => {
- const signers = await ethers.getSigners();
- owner = signers[0];
- approval = signers[1];
- to = signers[2];
- const ERC3525Factory = await ethers.getContractFactory("ERC3525Example");
- token = (await ERC3525Factory.deploy(
- "TST",
- "Test 3525",
- 18
- )) as ERC3525Example;
- await token.deployed();
-
- await token.mint(
- slotDetails.name,
- slotDetails.description,
- slotDetails.image,
- fromTokenId,
- slotDetails.underlying,
- slotDetails.vestingType,
- slotDetails.maturity,
- slotDetails.term,
- slotDetails.value
- );
-
- await token.mint(
- slotDetails.name,
- slotDetails.description,
- slotDetails.image,
- toTokenId,
- slotDetails.underlying,
- slotDetails.vestingType,
- slotDetails.maturity,
- slotDetails.term,
- 0
- );
- });
-
- beforeEach(async function () {
- snapshotId = await ethers.provider.send("evm_snapshot", []);
- });
-
- afterEach(async function () {
- await ethers.provider.send("evm_revert", [snapshotId]);
- });
-
- describe("ERC3525 Example", function () {
- it("approve value should be success", async () => {
- await token["approve(uint256,address,uint256)"](
- fromTokenId,
- approval.address,
- approveValue
- );
-
- expect(await token.allowance(fromTokenId, approval.address)).to.eq(
- approveValue
- );
- });
-
- it("transfer value to id should be success", async () => {
- expect(
- await token["transferFrom(uint256,uint256,uint256)"](
- fromTokenId,
- toTokenId,
- transferValue
- )
- );
- expect(await token["balanceOf(uint256)"](fromTokenId)).to.eq(
- fromValue - transferValue
- );
- expect(await token["balanceOf(uint256)"](toTokenId)).to.eq(transferValue);
- });
-
- it("transfer value to address should be success", async () => {
- expect(
- await token["transferFrom(uint256,address,uint256)"](
- fromTokenId,
- to.address,
- transferValue
- )
- );
- expect(await token["balanceOf(uint256)"](fromTokenId)).to.eq(
- fromValue - transferValue
- );
- const newTokenId = 1000000000 + fromTokenId;
- expect(await token["balanceOf(uint256)"](newTokenId)).to.eq(
- transferValue
- );
- });
-
- it("approved value should be correct after transfer value to id", async () => {
- await token["approve(uint256,address,uint256)"](
- fromTokenId,
- approval.address,
- approveValue
- );
- const approvalToken = token.connect(approval);
- await approvalToken["transferFrom(uint256,uint256,uint256)"](
- fromTokenId,
- toTokenId,
- transferValue
- );
- expect(await token.allowance(fromTokenId, approval.address)).to.eq(
- approveValue - transferValue
- );
- });
- });
-});
diff --git a/assets/eip-3607/geth.diff b/assets/eip-3607/geth.diff
deleted file mode 100644
index ea65164..0000000
--- a/assets/eip-3607/geth.diff
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/core/state_transition.go b/core/state_transition.go
-index 18777d8d4..3b25155c6 100644
---- a/core/state_transition.go
-+++ b/core/state_transition.go
-@@ -219,6 +219,11 @@ func (st *StateTransition) preCheck() error {
- st.msg.From().Hex(), msgNonce, stNonce)
- }
- }
-+ // Make sure the sender is an EOA
-+ if codeHash := st.state.GetCodeHash(st.msg.From()); codeHash != emptyCodeHash {
-+ return fmt.Errorf("%w: address %v, codehash: %s", ErrSenderNoEOA,
-+ st.msg.From().Hex(), codeHash)
-+ }
- // Make sure that transaction feeCap is greater than the baseFee (post london)
- if st.evm.ChainConfig().IsLondon(st.evm.Context.BlockNumber) {
- if l := st.feeCap.BitLen(); l > 256 {
\ No newline at end of file
diff --git a/assets/eip-3770/examples.png b/assets/eip-3770/examples.png
deleted file mode 100644
index 0793b6b..0000000
Binary files a/assets/eip-3770/examples.png and /dev/null differ
diff --git a/assets/eip-4337/image1.png b/assets/eip-4337/image1.png
deleted file mode 100644
index ced8ea5..0000000
Binary files a/assets/eip-4337/image1.png and /dev/null differ
diff --git a/assets/eip-4337/image2.png b/assets/eip-4337/image2.png
deleted file mode 100644
index 6d0c6f7..0000000
Binary files a/assets/eip-4337/image2.png and /dev/null differ
diff --git a/assets/eip-4361/example.js b/assets/eip-4361/example.js
deleted file mode 100644
index 12ec7ee..0000000
--- a/assets/eip-4361/example.js
+++ /dev/null
@@ -1,238 +0,0 @@
-// To run this example, navigate to this directory and run `npm i && node example.js`
-
-const apgApi = require('apg-js/src/apg-api/api');
-const apgLib = require('apg-js/src/apg-lib/node-exports');
-
-const GRAMMAR = `
-sign-in-with-ethereum =
- domain %s" wants you to sign in with your Ethereum account:" LF
- address LF
- LF
- [ statement LF ]
- LF
- %s"URI: " URI LF
- %s"Version: " version LF
- %s"Chain ID: " chain-id LF
- %s"Nonce: " nonce LF
- %s"Issued At: " issued-at
- [ LF %s"Expiration Time: " expiration-time ]
- [ LF %s"Not Before: " not-before ]
- [ LF %s"Request ID: " request-id ]
- [ LF %s"Resources:"
- resources ]
-
-domain = authority
-
-address = "0x" 40*40HEXDIG
- ; Must also conform to captilization
- ; checksum encoding specified in EIP-55
- ; where applicable (EOAs).
-
-statement = 1*( reserved / unreserved / " " )
- ; The purpose is to exclude LF (line breaks).
-
-version = "1"
-
-nonce = 8*( ALPHA / DIGIT )
-
-issued-at = date-time
-expiration-time = date-time
-not-before = date-time
-
-request-id = *pchar
-
-chain-id = 1*DIGIT
- ; See EIP-155 for valid CHAIN_IDs.
-
-resources = *( LF resource )
-
-resource = "- " URI
-
-; ------------------------------------------------------------------------------
-; RFC 3986
-
-URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
-
-hier-part = "//" authority path-abempty
- / path-absolute
- / path-rootless
- / path-empty
-
-scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-
-authority = [ userinfo "@" ] host [ ":" port ]
-userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
-host = IP-literal / IPv4address / reg-name
-port = *DIGIT
-
-IP-literal = "[" ( IPv6address / IPvFuture ) "]"
-
-IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
-
-IPv6address = 6( h16 ":" ) ls32
- / "::" 5( h16 ":" ) ls32
- / [ h16 ] "::" 4( h16 ":" ) ls32
- / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32
- / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32
- / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32
- / [ *4( h16 ":" ) h16 ] "::" ls32
- / [ *5( h16 ":" ) h16 ] "::" h16
- / [ *6( h16 ":" ) h16 ] "::"
-
-h16 = 1*4HEXDIG
-ls32 = ( h16 ":" h16 ) / IPv4address
-IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
-dec-octet = DIGIT ; 0-9
- / %x31-39 DIGIT ; 10-99
- / "1" 2DIGIT ; 100-199
- / "2" %x30-34 DIGIT ; 200-249
- / "25" %x30-35 ; 250-255
-
-reg-name = *( unreserved / pct-encoded / sub-delims )
-
-path-abempty = *( "/" segment )
-path-absolute = "/" [ segment-nz *( "/" segment ) ]
-path-rootless = segment-nz *( "/" segment )
-path-empty = 0pchar
-
-segment = *pchar
-segment-nz = 1*pchar
-
-pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
-
-query = *( pchar / "/" / "?" )
-
-fragment = *( pchar / "/" / "?" )
-
-pct-encoded = "%" HEXDIG HEXDIG
-
-unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
-reserved = gen-delims / sub-delims
-gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
-sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
- / "*" / "+" / "," / ";" / "="
-
-; ------------------------------------------------------------------------------
-; RFC 3339
-
-date-fullyear = 4DIGIT
-date-month = 2DIGIT ; 01-12
-date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on
- ; month/year
-time-hour = 2DIGIT ; 00-23
-time-minute = 2DIGIT ; 00-59
-time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second
- ; rules
-time-secfrac = "." 1*DIGIT
-time-numoffset = ("+" / "-") time-hour ":" time-minute
-time-offset = "Z" / time-numoffset
-
-partial-time = time-hour ":" time-minute ":" time-second
- [time-secfrac]
-full-date = date-fullyear "-" date-month "-" date-mday
-full-time = partial-time time-offset
-
-date-time = full-date "T" full-time
-
-; ------------------------------------------------------------------------------
-; RFC 5234
-
-ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
-LF = %x0A
- ; linefeed
-DIGIT = %x30-39
- ; 0-9
-HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
-`;
-
-const parseMessage = (message) => {
- const api = new apgApi(GRAMMAR);
- api.generate();
-
- const grammarObj = api.toObject();
- const parser = new apgLib.parser();
- parser.ast = new apgLib.ast();
- const id = apgLib.ids;
-
- const charToString = apgLib.utils.charsToString;
-
- const getField = (field) => function (state, chars, phraseIndex, phraseLength, data) {
- const ret = id.SEM_OK;
- if (state === id.SEM_PRE) {
- data[field] = charToString(chars, phraseIndex, phraseLength);
- }
- return ret;
- };
-
- const domain = getField("domain");
- parser.ast.callbacks.domain = domain;
- const address = getField("address");
- parser.ast.callbacks.address = address;
- const statement = getField("statement");
- parser.ast.callbacks.statement = statement;
- const uri = getField("uri");
- parser.ast.callbacks.uri = uri;
- const version = getField("version");
- parser.ast.callbacks.version = version;
- const chainId = getField("chainId");
- parser.ast.callbacks['chain-id'] = chainId;
- const nonce = getField("nonce");
- parser.ast.callbacks.nonce = nonce;
- const issuedAt = getField("issuedAt");
- parser.ast.callbacks['issued-at'] = issuedAt;
- const expirationTime = getField("expirationTime");
- parser.ast.callbacks['expiration-time'] = expirationTime;
- const notBefore = getField("notBefore");
- parser.ast.callbacks['not-before'] = notBefore;
- const requestId = getField("requestId");
- parser.ast.callbacks['request-id'] = requestId;
-
- const resources = function (state, chars, phraseIndex, phraseLength, data) {
- const ret = id.SEM_OK;
- if (state === id.SEM_PRE) {
- data.resources = apgLib.utils
- .charsToString(chars, phraseIndex, phraseLength)
- .slice(3)
- .split('\n- ');
- }
- return ret;
- };
- parser.ast.callbacks.resources = resources;
-
- const result = parser.parse(grammarObj, 'sign-in-with-ethereum', message);
- if (!result.success) {
- throw new Error(`Invalid message: ${JSON.stringify(result)}`);
- }
- const elements = {};
- parser.ast.translate(elements);
- let obj = {};
- for (const [key, value] of Object.entries(elements)) {
- obj[key] = value;
- }
- return obj;
-}
-
-const createMessage = ({ domain, address, uri, version, chainId, nonce, issuedAt }) => {
- const header = `${domain} wants you to sign in with your Ethereum account:\n${address}\n\n\n`;
- const uriField = `URI: ${uri}\n`;
- const versionField = `Version: ${version}\n`;
- const chainField = `Chain ID: ${chainId}\n`;
- const nonceField = `Nonce: ${nonce}\n`;
- const issuedAtField = `Issued At: ${issuedAt}`;
- return [header, uriField, versionField, chainField, nonceField, issuedAtField].join('');
-}
-
-const message = createMessage({
- domain: "example.com",
- address: "0x51e913F93EBBF41f0DAc68219c31c1c15DFe3C49",
- uri: "https://example.com",
- version: '1',
- chainId: '1',
- nonce: "Ap4xKpGjEcYkYubmH4Vpw7pW8b3s6cJd",
- issuedAt: "2022-05-18T14:11:46.065Z",
-});
-
-const messageObject = parseMessage(message);
-
-console.log(message, '\n');
-console.log(messageObject);
diff --git a/assets/eip-4361/package.json b/assets/eip-4361/package.json
deleted file mode 100644
index 1819473..0000000
--- a/assets/eip-4361/package.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "name": "eip4361-example",
- "version": "1.0.0",
- "description": "Reference implementation for Sign-In with Ethereum",
- "main": "example.js",
- "dependencies": {
- "apg-js": "^4.1.1"
- }
-}
diff --git a/assets/eip-4361/signing.png b/assets/eip-4361/signing.png
deleted file mode 100644
index f92b4e6..0000000
Binary files a/assets/eip-4361/signing.png and /dev/null differ
diff --git a/assets/eip-4396/degradation.png b/assets/eip-4396/degradation.png
deleted file mode 100644
index cc2262a..0000000
Binary files a/assets/eip-4396/degradation.png and /dev/null differ
diff --git a/assets/eip-4396/degradation_buffers.png b/assets/eip-4396/degradation_buffers.png
deleted file mode 100644
index fd87694..0000000
Binary files a/assets/eip-4396/degradation_buffers.png and /dev/null differ
diff --git a/assets/eip-4396/degradation_elasticity.png b/assets/eip-4396/degradation_elasticity.png
deleted file mode 100644
index 29c95dd..0000000
Binary files a/assets/eip-4396/degradation_elasticity.png and /dev/null differ
diff --git a/assets/eip-4396/new_formula.png b/assets/eip-4396/new_formula.png
deleted file mode 100644
index 46934d3..0000000
Binary files a/assets/eip-4396/new_formula.png and /dev/null differ
diff --git a/assets/eip-4396/old_formula.png b/assets/eip-4396/old_formula.png
deleted file mode 100644
index 27f07ab..0000000
Binary files a/assets/eip-4396/old_formula.png and /dev/null differ
diff --git a/assets/eip-4400/.gitignore b/assets/eip-4400/.gitignore
deleted file mode 100644
index 6d1e7e0..0000000
--- a/assets/eip-4400/.gitignore
+++ /dev/null
@@ -1,6 +0,0 @@
-node_modules
-
-#Hardhat files
-cache
-artifacts
-typechain
diff --git a/assets/eip-4400/LICENSE b/assets/eip-4400/LICENSE
deleted file mode 100644
index 1625c17..0000000
--- a/assets/eip-4400/LICENSE
+++ /dev/null
@@ -1,121 +0,0 @@
-Creative Commons Legal Code
-
-CC0 1.0 Universal
-
- CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
- LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
- ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
- INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
- REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
- PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
- THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
- HEREUNDER.
-
-Statement of Purpose
-
-The laws of most jurisdictions throughout the world automatically confer
-exclusive Copyright and Related Rights (defined below) upon the creator
-and subsequent owner(s) (each and all, an "owner") of an original work of
-authorship and/or a database (each, a "Work").
-
-Certain owners wish to permanently relinquish those rights to a Work for
-the purpose of contributing to a commons of creative, cultural and
-scientific works ("Commons") that the public can reliably and without fear
-of later claims of infringement build upon, modify, incorporate in other
-works, reuse and redistribute as freely as possible in any form whatsoever
-and for any purposes, including without limitation commercial purposes.
-These owners may contribute to the Commons to promote the ideal of a free
-culture and the further production of creative, cultural and scientific
-works, or to gain reputation or greater distribution for their Work in
-part through the use and efforts of others.
-
-For these and/or other purposes and motivations, and without any
-expectation of additional consideration or compensation, the person
-associating CC0 with a Work (the "Affirmer"), to the extent that he or she
-is an owner of Copyright and Related Rights in the Work, voluntarily
-elects to apply CC0 to the Work and publicly distribute the Work under its
-terms, with knowledge of his or her Copyright and Related Rights in the
-Work and the meaning and intended legal effect of CC0 on those rights.
-
-1. Copyright and Related Rights. A Work made available under CC0 may be
-protected by copyright and related or neighboring rights ("Copyright and
-Related Rights"). Copyright and Related Rights include, but are not
-limited to, the following:
-
- i. the right to reproduce, adapt, distribute, perform, display,
- communicate, and translate a Work;
- ii. moral rights retained by the original author(s) and/or performer(s);
-iii. publicity and privacy rights pertaining to a person's image or
- likeness depicted in a Work;
- iv. rights protecting against unfair competition in regards to a Work,
- subject to the limitations in paragraph 4(a), below;
- v. rights protecting the extraction, dissemination, use and reuse of data
- in a Work;
- vi. database rights (such as those arising under Directive 96/9/EC of the
- European Parliament and of the Council of 11 March 1996 on the legal
- protection of databases, and under any national implementation
- thereof, including any amended or successor version of such
- directive); and
-vii. other similar, equivalent or corresponding rights throughout the
- world based on applicable law or treaty, and any national
- implementations thereof.
-
-2. Waiver. To the greatest extent permitted by, but not in contravention
-of, applicable law, Affirmer hereby overtly, fully, permanently,
-irrevocably and unconditionally waives, abandons, and surrenders all of
-Affirmer's Copyright and Related Rights and associated claims and causes
-of action, whether now known or unknown (including existing as well as
-future claims and causes of action), in the Work (i) in all territories
-worldwide, (ii) for the maximum duration provided by applicable law or
-treaty (including future time extensions), (iii) in any current or future
-medium and for any number of copies, and (iv) for any purpose whatsoever,
-including without limitation commercial, advertising or promotional
-purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
-member of the public at large and to the detriment of Affirmer's heirs and
-successors, fully intending that such Waiver shall not be subject to
-revocation, rescission, cancellation, termination, or any other legal or
-equitable action to disrupt the quiet enjoyment of the Work by the public
-as contemplated by Affirmer's express Statement of Purpose.
-
-3. Public License Fallback. Should any part of the Waiver for any reason
-be judged legally invalid or ineffective under applicable law, then the
-Waiver shall be preserved to the maximum extent permitted taking into
-account Affirmer's express Statement of Purpose. In addition, to the
-extent the Waiver is so judged Affirmer hereby grants to each affected
-person a royalty-free, non transferable, non sublicensable, non exclusive,
-irrevocable and unconditional license to exercise Affirmer's Copyright and
-Related Rights in the Work (i) in all territories worldwide, (ii) for the
-maximum duration provided by applicable law or treaty (including future
-time extensions), (iii) in any current or future medium and for any number
-of copies, and (iv) for any purpose whatsoever, including without
-limitation commercial, advertising or promotional purposes (the
-"License"). The License shall be deemed effective as of the date CC0 was
-applied by Affirmer to the Work. Should any part of the License for any
-reason be judged legally invalid or ineffective under applicable law, such
-partial invalidity or ineffectiveness shall not invalidate the remainder
-of the License, and in such case Affirmer hereby affirms that he or she
-will not (i) exercise any of his or her remaining Copyright and Related
-Rights in the Work or (ii) assert any associated claims and causes of
-action with respect to the Work, in either case contrary to Affirmer's
-express Statement of Purpose.
-
-4. Limitations and Disclaimers.
-
- a. No trademark or patent rights held by Affirmer are waived, abandoned,
- surrendered, licensed or otherwise affected by this document.
- b. Affirmer offers the Work as-is and makes no representations or
- warranties of any kind concerning the Work, express, implied,
- statutory or otherwise, including without limitation warranties of
- title, merchantability, fitness for a particular purpose, non
- infringement, or the absence of latent or other defects, accuracy, or
- the present or absence of errors, whether or not discoverable, all to
- the greatest extent permissible under applicable law.
- c. Affirmer disclaims responsibility for clearing rights of other persons
- that may apply to the Work or any use thereof, including without
- limitation any person's Copyright and Related Rights in the Work.
- Further, Affirmer disclaims responsibility for obtaining any necessary
- consents, permissions or other rights required for any use of the
- Work.
- d. Affirmer understands and acknowledges that Creative Commons is not a
- party to this document and has no duty or obligation with respect to
- this CC0 or use of the Work.
\ No newline at end of file
diff --git a/assets/eip-4400/README.md b/assets/eip-4400/README.md
deleted file mode 100644
index d62d9ea..0000000
--- a/assets/eip-4400/README.md
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-# ERC721 Consumable Extension
-
-[![License: CC0-1.0](https://img.shields.io/badge/License-CC0-yellow.svg)](https://creativecommons.org/publicdomain/zero/1.0/)
-
-
-
-This project provides a reference implementation of the proposed `ERC721Consumer` OPTIONAL extension.
-
-## Install
-
-In order to install the required dependencies you need to execute:
-```shell
-npm install
-```
-
-## Compile
-
-In order to compile the solidity contracts you need to execute:
-```shell
-npx hardhat compile
-```
-
-## Tests
-
-```shell
-npx hardhat test
-```
\ No newline at end of file
diff --git a/assets/eip-4400/abi/ERC721Consumable.json b/assets/eip-4400/abi/ERC721Consumable.json
deleted file mode 100644
index 87c8cde..0000000
--- a/assets/eip-4400/abi/ERC721Consumable.json
+++ /dev/null
@@ -1,410 +0,0 @@
-[
- {
- "inputs": [
- {
- "internalType": "string",
- "name": "name_",
- "type": "string"
- },
- {
- "internalType": "string",
- "name": "symbol_",
- "type": "string"
- }
- ],
- "stateMutability": "nonpayable",
- "type": "constructor"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "approved",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "Approval",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "operator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "bool",
- "name": "approved",
- "type": "bool"
- }
- ],
- "name": "ApprovalForAll",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "consumer",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "ConsumerChanged",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "Transfer",
- "type": "event"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "approve",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "owner",
- "type": "address"
- }
- ],
- "name": "balanceOf",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "_consumer",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "_tokenId",
- "type": "uint256"
- }
- ],
- "name": "changeConsumer",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "_tokenId",
- "type": "uint256"
- }
- ],
- "name": "consumerOf",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "getApproved",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- }
- ],
- "name": "isApprovedForAll",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "name",
- "outputs": [
- {
- "internalType": "string",
- "name": "",
- "type": "string"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "ownerOf",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- },
- {
- "internalType": "bytes",
- "name": "_data",
- "type": "bytes"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "approved",
- "type": "bool"
- }
- ],
- "name": "setApprovalForAll",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "bytes4",
- "name": "interfaceId",
- "type": "bytes4"
- }
- ],
- "name": "supportsInterface",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [],
- "name": "symbol",
- "outputs": [
- {
- "internalType": "string",
- "name": "",
- "type": "string"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "tokenURI",
- "outputs": [
- {
- "internalType": "string",
- "name": "",
- "type": "string"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "transferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- }
-]
diff --git a/assets/eip-4400/abi/IERC721Consumable.json b/assets/eip-4400/abi/IERC721Consumable.json
deleted file mode 100644
index 8b0e6b8..0000000
--- a/assets/eip-4400/abi/IERC721Consumable.json
+++ /dev/null
@@ -1,349 +0,0 @@
-[
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "approved",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "Approval",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "operator",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "bool",
- "name": "approved",
- "type": "bool"
- }
- ],
- "name": "ApprovalForAll",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "consumer",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "ConsumerChanged",
- "type": "event"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "Transfer",
- "type": "event"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "approve",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "owner",
- "type": "address"
- }
- ],
- "name": "balanceOf",
- "outputs": [
- {
- "internalType": "uint256",
- "name": "balance",
- "type": "uint256"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "_consumer",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "_tokenId",
- "type": "uint256"
- }
- ],
- "name": "changeConsumer",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "_tokenId",
- "type": "uint256"
- }
- ],
- "name": "consumerOf",
- "outputs": [
- {
- "internalType": "address",
- "name": "",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "getApproved",
- "outputs": [
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- }
- ],
- "name": "isApprovedForAll",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "ownerOf",
- "outputs": [
- {
- "internalType": "address",
- "name": "owner",
- "type": "address"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- },
- {
- "internalType": "bytes",
- "name": "data",
- "type": "bytes"
- }
- ],
- "name": "safeTransferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "operator",
- "type": "address"
- },
- {
- "internalType": "bool",
- "name": "_approved",
- "type": "bool"
- }
- ],
- "name": "setApprovalForAll",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "bytes4",
- "name": "interfaceId",
- "type": "bytes4"
- }
- ],
- "name": "supportsInterface",
- "outputs": [
- {
- "internalType": "bool",
- "name": "",
- "type": "bool"
- }
- ],
- "stateMutability": "view",
- "type": "function"
- },
- {
- "inputs": [
- {
- "internalType": "address",
- "name": "from",
- "type": "address"
- },
- {
- "internalType": "address",
- "name": "to",
- "type": "address"
- },
- {
- "internalType": "uint256",
- "name": "tokenId",
- "type": "uint256"
- }
- ],
- "name": "transferFrom",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
- }
-]
diff --git a/assets/eip-4400/contracts/ERC721Consumable.sol b/assets/eip-4400/contracts/ERC721Consumable.sol
deleted file mode 100644
index 56912b9..0000000
--- a/assets/eip-4400/contracts/ERC721Consumable.sol
+++ /dev/null
@@ -1,59 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity 0.8.11;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC721Consumable.sol";
-
-contract ERC721Consumable is IERC721Consumable, ERC721 {
-
- // Mapping from token ID to consumer address
- mapping(uint256 => address) _tokenConsumers;
-
- constructor (string memory name_, string memory symbol_) ERC721(name_, symbol_) {}
-
- /**
- * @dev Returns true if the `msg.sender` is approved, owner or consumer of the `tokenId`
- */
- function _isApprovedOwnerOrConsumer(uint256 tokenId) internal view returns (bool) {
- return _isApprovedOrOwner(msg.sender, tokenId) || _tokenConsumers[tokenId] == msg.sender;
- }
-
- /**
- * @dev See {IERC721Consumable-consumerOf}
- */
- function consumerOf(uint256 _tokenId) view external returns (address) {
- require(_exists(_tokenId), "ERC721Consumable: consumer query for nonexistent token");
- return _tokenConsumers[_tokenId];
- }
-
- /**
- * @dev See {IERC721Consumable-changeConsumer}
- */
- function changeConsumer(address _consumer, uint256 _tokenId) external {
- address owner = this.ownerOf(_tokenId);
- require(msg.sender == owner || msg.sender == getApproved(_tokenId) || isApprovedForAll(owner, msg.sender),
- "ERC721Consumable: changeConsumer caller is not owner nor approved");
- _changeConsumer(owner, _consumer, _tokenId);
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
- return interfaceId == type(IERC721Consumable).interfaceId || super.supportsInterface(interfaceId);
- }
-
- function _beforeTokenTransfer(address _from, address _to, uint256 _tokenId) internal virtual override (ERC721) {
- super._beforeTokenTransfer(_from, _to, _tokenId);
- _changeConsumer(_from, address(0), _tokenId);
- }
-
- /**
- * @dev Changes the consumer
- * Requirement: `tokenId` must exist
- */
- function _changeConsumer(address _owner, address _consumer, uint256 _tokenId) internal {
- _tokenConsumers[_tokenId] = _consumer;
- emit ConsumerChanged(_owner, _consumer, _tokenId);
- }
-}
diff --git a/assets/eip-4400/contracts/ExampleToken.sol b/assets/eip-4400/contracts/ExampleToken.sol
deleted file mode 100644
index 74f5b48..0000000
--- a/assets/eip-4400/contracts/ExampleToken.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity 0.8.11;
-
-import "./ERC721Consumable.sol";
-
-contract ExampleToken is ERC721Consumable {
-
- uint256 public idCounter = 0;
-
- constructor() ERC721Consumable("ReferenceImpl", "RIMPL") { }
-
- // @notice Mints new NFT to msg.sender
- function mint() external returns (uint256) {
- idCounter++;
- _mint(msg.sender, idCounter);
- return idCounter;
- }
-}
diff --git a/assets/eip-4400/contracts/IERC721Consumable.sol b/assets/eip-4400/contracts/IERC721Consumable.sol
deleted file mode 100644
index e03f737..0000000
--- a/assets/eip-4400/contracts/IERC721Consumable.sol
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity 0.8.11;
-
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-
-/// @title ERC-721 Consumer Role extension
-/// Note: the ERC-165 identifier for this interface is 0x953c8dfa
-interface IERC721Consumable is IERC721 {
-
- /// @notice Emitted when `owner` changes the `consumer` of an NFT
- /// The zero address for consumer indicates that there is no consumer address
- /// When a Transfer event emits, this also indicates that the consumer address
- /// for that NFT (if any) is set to none
- event ConsumerChanged(address indexed owner, address indexed consumer, uint256 indexed tokenId);
-
- /// @notice Get the consumer address of an NFT
- /// @dev The zero address indicates that there is no consumer
- /// Throws if `_tokenId` is not a valid NFT
- /// @param _tokenId The NFT to get the consumer address for
- /// @return The consumer address for this NFT, or the zero address if there is none
- function consumerOf(uint256 _tokenId) view external returns (address);
-
- /// @notice Change or reaffirm the consumer address for an NFT
- /// @dev The zero address indicates there is no consumer address
- /// Throws unless `msg.sender` is the current NFT owner, an authorised
- /// operator of the current owner or approved address
- /// Throws if `_tokenId` is not valid NFT
- /// @param _consumer The new consumer of the NFT
- function changeConsumer(address _consumer, uint256 _tokenId) external;
-}
diff --git a/assets/eip-4400/hardhat.config.ts b/assets/eip-4400/hardhat.config.ts
deleted file mode 100644
index da97857..0000000
--- a/assets/eip-4400/hardhat.config.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import '@nomiclabs/hardhat-waffle';
-import 'hardhat-abi-exporter';
-import 'hardhat-typechain';
-
-
-module.exports = {
- solidity: {
- compilers: [
- {
- version: "0.8.11",
- },
- ],
- settings: {
- optimizer: {
- enabled: true,
- runs: 200,
- },
- },
- },
- defaultNetwork: 'hardhat',
- abiExporter: {
- only: ['IERC721Consumable', 'ERC721Consumable'],
- clear: true,
- flat: true,
- },
-};
diff --git a/assets/eip-4400/package.json b/assets/eip-4400/package.json
deleted file mode 100644
index 3530cc7..0000000
--- a/assets/eip-4400/package.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "hardhat-project",
- "devDependencies": {
- "@nomiclabs/hardhat-ethers": "^2.0.2",
- "@nomiclabs/hardhat-waffle": "^2.0.1",
- "@typechain/ethers-v5": "^2.0.0",
- "@types/chai": "^4.2.14",
- "@types/mocha": "^8.0.3",
- "@types/node": "^14.14.6",
- "chai": "^4.3.4",
- "ethereum-waffle": "^3.4.0",
- "ethers": "^5.4.7",
- "hardhat": "^2.6.7",
- "hardhat-abi-exporter": "^2.3.1",
- "hardhat-typechain": "^0.3.3",
- "ts-node": "^10.4.0",
- "typechain": "^3.0.0",
- "typescript": "^4.5.2"
- },
- "dependencies": {
- "@openzeppelin/contracts": "^4.3.2"
- }
-}
diff --git a/assets/eip-4400/test/erc721-consumable.ts b/assets/eip-4400/test/erc721-consumable.ts
deleted file mode 100644
index a65c6e3..0000000
--- a/assets/eip-4400/test/erc721-consumable.ts
+++ /dev/null
@@ -1,134 +0,0 @@
-import {ethers} from "hardhat";
-import {expect} from 'chai';
-import {SignerWithAddress} from "@nomiclabs/hardhat-ethers/signers";
-import {Erc721Consumable} from "../typechain";
-
-describe("ERC721Consumable", async () => {
- let owner: SignerWithAddress, approved: SignerWithAddress, operator: SignerWithAddress, consumer: SignerWithAddress,
- other: SignerWithAddress;
- let token: Erc721Consumable;
- let snapshotId: any;
- const tokenID = 1; // The first minted NFT
-
- before(async () => {
- const signers = await ethers.getSigners();
- owner = signers[0];
- approved = signers[1];
- operator = signers[2];
- consumer = signers[3];
- other = signers[4];
-
- const ConsumableToken = await ethers.getContractFactory("ExampleToken");
- const deployedContract = await ConsumableToken.deploy();
- await deployedContract.deployed();
- token = deployedContract as Erc721Consumable;
-
- await token.mint();
- })
-
- beforeEach(async function () {
- snapshotId = await ethers.provider.send('evm_snapshot', []);
- });
-
- afterEach(async function () {
- await ethers.provider.send('evm_revert', [snapshotId]);
- });
-
- it('should implement ERC165', async () => {
- expect(await token.supportsInterface("0x953c8dfa")).to.be.true;
- })
-
- it('should successfully change consumer', async () => {
- // when:
- await token.changeConsumer(consumer.address, tokenID);
- // then:
- expect(await token.consumerOf(tokenID)).to.equal(consumer.address);
- });
-
- it('should emit event with args', async () => {
- // when:
- const tx = await token.changeConsumer(consumer.address, tokenID);
-
- // then:
- await expect(tx)
- .to.emit(token, 'ConsumerChanged')
- .withArgs(owner.address, consumer.address, tokenID);
- });
-
- it('should successfully change consumer when caller is approved', async () => {
- // given:
- await token.approve(approved.address, tokenID);
- // when:
- const tx = await token.connect(approved).changeConsumer(consumer.address, tokenID);
-
- // then:
- await expect(tx)
- .to.emit(token, 'ConsumerChanged')
- .withArgs(owner.address, consumer.address, tokenID);
- // and:
- expect(await token.consumerOf(tokenID)).to.equal(consumer.address);
- });
-
- it('should successfully change consumer when caller is operator', async () => {
- // given:
- await token.setApprovalForAll(operator.address, true);
- // when:
- const tx = await token.connect(operator).changeConsumer(consumer.address, tokenID);
-
- // then:
- await expect(tx)
- .to.emit(token, 'ConsumerChanged')
- .withArgs(owner.address, consumer.address, tokenID);
- // and:
- expect(await token.consumerOf(tokenID)).to.equal(consumer.address);
- });
-
- it('should revert when caller is not owner, not approved', async () => {
- const expectedRevertMessage = 'ERC721Consumable: changeConsumer caller is not owner nor approved';
- await expect(token.connect(other).changeConsumer(consumer.address, tokenID))
- .to.be.revertedWith(expectedRevertMessage);
- });
-
- it('should revert when caller is approved for the token', async () => {
- // given:
- await token.changeConsumer(consumer.address, tokenID);
- // then:
- const expectedRevertMessage = 'ERC721Consumable: changeConsumer caller is not owner nor approved';
- await expect(token.connect(consumer).changeConsumer(consumer.address, tokenID))
- .to.be.revertedWith(expectedRevertMessage);
- });
-
- it('should revert when tokenID is nonexistent', async () => {
- const invalidTokenID = 2;
- const expectedRevertMessage = 'ERC721: owner query for nonexistent token';
- await expect(token.changeConsumer(consumer.address, invalidTokenID))
- .to.be.revertedWith(expectedRevertMessage);
- });
-
- it('should revert when calling consumerOf with nonexistent tokenID', async () => {
- const invalidTokenID = 2;
- const expectedRevertMessage = 'ERC721Consumable: consumer query for nonexistent token';
- await expect(token.consumerOf(invalidTokenID))
- .to.be.revertedWith(expectedRevertMessage);
- });
-
- it('should clear consumer on transfer', async () => {
- await token.changeConsumer(consumer.address, tokenID);
- await expect(token.transferFrom(owner.address, other.address, tokenID))
- .to.emit(token, 'ConsumerChanged')
- .withArgs(owner.address, ethers.constants.AddressZero, tokenID);
- })
-
- it('should emit ConsumerChanged on mint', async () => {
- await expect(token.mint())
- .to.emit(token, 'ConsumerChanged')
- .withArgs(ethers.constants.AddressZero, ethers.constants.AddressZero, tokenID + 1);
- })
-
- it('should not be able to transfer from consumer', async () => {
- const expectedRevertMessage = 'ERC721: transfer caller is not owner nor approved';
- await token.changeConsumer(consumer.address, tokenID);
- await expect(token.connect(consumer).transferFrom(owner.address, other.address, tokenID))
- .to.revertedWith(expectedRevertMessage)
- })
-});
\ No newline at end of file
diff --git a/assets/eip-4400/tsconfig.json b/assets/eip-4400/tsconfig.json
deleted file mode 100644
index 57fc82e..0000000
--- a/assets/eip-4400/tsconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "module": "commonjs",
- "strict": true,
- "esModuleInterop": true,
- "outDir": "dist",
- "resolveJsonModule": true
- },
- "exclude": [
- "contracts"
- ],
- "include": [
- "./scripts",
- "./test"
- ],
- "files": [
- "./hardhat.config.ts"
- ]
-}
diff --git a/assets/eip-4488/gas_and_calldata_sample.csv b/assets/eip-4488/gas_and_calldata_sample.csv
deleted file mode 100644
index af49e30..0000000
--- a/assets/eip-4488/gas_and_calldata_sample.csv
+++ /dev/null
@@ -1,6871 +0,0 @@
-Gas, gas used, calldata bytes
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
-500000, 111711, 260
-464096, 311440, 2500
-800000, 323095, 932
-75865, 63221, 68
-34795, 34795, 68
-21000, 21000, 0
-21000, 21000, 0
-150000, 84032, 356
-21000, 21000, 0
-80815, 53530, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-105000, 63221, 68
-105000, 46109, 68
-105000, 46097, 68
-95000, 34989, 68
-64733, 54016, 68
-100000, 65058, 228
-338108, 249986, 260
-94813, 63209, 68
-30000, 21000, 0
-158666, 87719, 356
-199352, 98833, 324
-73711, 51547, 68
-120000, 47115, 68
-50000, 21000, 0
-400000, 37190, 68
-50000, 21000, 0
-90000, 34740, 68
-53615, 46622, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-69826, 46551, 68
-360915, 238860, 260
-420000, 21000, 0
-105000, 35065, 68
-105000, 34497, 68
-420000, 51883, 68
-105000, 35065, 68
-67798, 52153, 68
-1000000, 65625, 68
-1000000, 52344, 68
-105000, 21000, 0
-1000000, 64117, 68
-21000, 21000, 0
-21000, 21000, 0
-50719, 46109, 68
-46574, 46195, 68
-21000, 21000, 0
-21000, 21000, 0
-65000, 63209, 68
-186660, 144803, 260
-63000, 21000, 0
-74685, 47238, 68
-73639, 46366, 68
-90912, 60311, 68
-76676, 48897, 68
-21000, 21000, 0
-21000, 21000, 0
-66163, 65625, 68
-58500, 39457, 68
-73932, 51701, 68
-351400, 58670, 228
-21000, 21000, 0
-67798, 52153, 68
-45568, 35053, 68
-45568, 35053, 68
-67783, 52141, 68
-45568, 35053, 68
-45568, 35053, 68
-67798, 52153, 68
-45568, 35053, 68
-276714, 203765, 228
-60760, 60311, 68
-69163, 46109, 68
-84000, 48537, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 65613, 68
-250000, 51842, 68
-250000, 30324, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63197, 68
-21000, 21000, 0
-274546, 204205, 228
-199518, 141377, 260
-50000, 21000, 0
-50000, 36745, 0
-50000, 21000, 0
-200000, 52101, 68
-216034, 134250, 68
-220387, 139325, 68
-208084, 128950, 68
-146416, 97611, 228
-216034, 134250, 68
-72792, 60837, 68
-21000, 21000, 0
-250000, 65613, 68
-250000, 51618, 68
-250000, 63209, 68
-250000, 46109, 68
-21000, 21000, 0
-21000, 21000, 0
-250000, 63185, 68
-21000, 21000, 0
-21000, 21000, 0
-46458, 46458, 68
-72823, 48549, 68
-221617, 177894, 741
-21000, 21000, 0
-21000, 21000, 0
-250000, 30019, 68
-250000, 43725, 68
-250000, 35318, 68
-250000, 32349, 68
-250000, 29995, 68
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-21000, 21000, 0
-250000, 30007, 68
-250000, 29995, 68
-250000, 29801, 68
-216034, 134250, 68
-218777, 174205, 741
-184280, 136844, 1605
-591388, 581894, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-250000, 41309, 68
-397746, 271747, 260
-84000, 63197, 68
-21000, 21000, 0
-216407, 173130, 741
-1083221, 748810, 11140
-188263, 154461, 292
-69579, 46386, 68
-99226, 60813, 68
-252590, 185604, 260
-177663, 144507, 260
-21000, 21000, 0
-21000, 21000, 0
-89509, 59673, 68
-289917, 236617, 452
-21000, 21000, 0
-21000, 21000, 0
-328651, 243067, 2404
-186273, 131073, 580
-243811, 194718, 292
-151988, 116198, 260
-55904, 46587, 68
-222578, 182796, 292
-73188, 48525, 68
-69565, 46377, 68
-76373, 76373, 4
-21000, 21000, 0
-31091, 30597, 68
-31093, 31093, 164
-21000, 21000, 0
-21000, 21000, 0
-516883, 397602, 4
-49810, 49444, 68
-46458, 46458, 68
-81091, 81091, 36
-21000, 21000, 0
-94831, 63221, 68
-192939, 148081, 196
-53786, 48897, 68
-21000, 21000, 0
-305274, 240686, 1317
-384582, 254638, 260
-248867, 241097, 516
-21000, 21000, 0
-218864, 202318, 324
-46622, 46622, 68
-928568, 921613, 68
-46726, 46726, 68
-86416, 57623, 68
-183349, 127177, 228
-264834, 192696, 292
-21000, 21000, 0
-55970, 46642, 68
-403845, 267480, 260
-303605, 223801, 2404
-21000, 21000, 0
-142123, 41309, 68
-123188, 43725, 68
-21000, 21000, 0
-170000, 41297, 68
-170000, 41297, 68
-21000, 21000, 0
-93292, 61715, 68
-21000, 21000, 0
-142123, 41309, 68
-173205, 118856, 228
-346944, 259139, 2788
-185338, 128292, 580
-55932, 46610, 68
-325135, 320541, 36
-179888, 113786, 228
-21000, 21000, 0
-21000, 21000, 0
-77535, 46890, 68
-21000, 21000, 0
-197936, 140059, 260
-21000, 21000, 0
-278679, 227251, 292
-156000, 156000, 36
-53748, 53748, 68
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-21000, 21000, 0
-250000, 21000, 0
-250000, 21000, 0
-81493, 54329, 36
diff --git a/assets/eip-4519/ESP32_Firmware/main.cpp b/assets/eip-4519/ESP32_Firmware/main.cpp
deleted file mode 100644
index 7e13258..0000000
--- a/assets/eip-4519/ESP32_Firmware/main.cpp
+++ /dev/null
@@ -1,709 +0,0 @@
-/***
- * This example of ESP32 (Pycom LoPy4) firmware was developed by Javier Arcenegui at "Instituto de
- * Microelectrónica de Sevilla IMSE-CNM (Universidad de Sevilla-CSIC)" for the EIP4519. This firmware makes the device generate its own Ethereum account and save in the EEPROM the data required in the future to regenerate
- * the same account. In the newest versions of ESP32 ("ESP32 S2" or
- * "ESP32 S3") these data can be saved in a protected area.
- *
- * The Smart Contract is published on "0x6Dba58fF5AA2d8447C4460d2527033A81646Ae97".
- * It was proved in the Ethereum Kovan testnet.
- *
- * This code was developed with the infuraIO extension for Visual Studio Code and the Arduino Framework.
- * The alphawallet/Web3E@^1.22 library must be added in the configuration file (platformio.ini)
- *
- * Helper data are employed to regenerate the same Ethereum account based on CTR-DRBG PRNG.
- * The helper data format is the following:
- *
- * ------------------------- Helper data Format -----------------------
- * |---------------|----------------|----------------|----|----|----|
- * | key_ctr |Personalization | contex_counter | rc | el | ri |
- * |---------------|----------------|----------------|----|----|----|
- * 51 35 19 3 2 1 0 (Byte)
- *
- ***/
-
-#include
-#include
-#include
-#include
-#include "mbedtls/ctr_drbg.h"
-#include "mbedtls/entropy.h"
-#include
-#include
-#include "esp_wifi.h"
-#include
-#include
-#include
-#include
-#include "Trezor/secp256k1.h"
-#include "Trezor/ecdsa.h"
-#include "Trezor/sha3.h"
-
-#define EEPROM_SIZE 52 //The size required by the 51 bytes of helper data and the byte to know if the token is registered on the blockchain
-#define EIP4519CONTRACT "0x6Dba58fF5AA2d8447C4460d2527033A81646Ae97" //This is the reference for the EIP4519 Smart Non-Fungible Token on Kovan (IT MUST BE CHANGED)
-
-//These are the states of the EIP4519
-enum STATES{
- waitingForOwner = 0,
- engagedWithOwner = 1,
- waitingForUser = 2,
- engagedWithUser = 3
-};
-
-void setupWifi(); //This function is the same as the wifi example of the ESP32 Arduino Wifi
-uint8_t HexTo4Bits(uint8_t Hex); //This function is used to change an hexadecimal defined in ASCII character to a uint8_t
-STATES queryTokenStatus(); //This function is used to recover the information of the SmartNFT associated to this device
-void hex2Char(unsigned char *inHex, unsigned char *charH, unsigned char *charL); //This function is needed to convert an uint8_t to two ASCII characters
-
-void sendEngage(); //This function sends the hash of the shared key to complete the transaction in Ethereum
-
-//Declaration of the variable to save the state of the SmartNFT
-STATES tokenState;
-
-//Declaration of the variables for the private/public Keys and the Address associated
-
-unsigned char privateKey_ethAccount[32];
-unsigned char publicKey_ethAccount[64];
-unsigned char ethAddress[20];
-
-//Declaration of the variable to save the helper data generated/recovered, which are employed to obtain the private Key of Ethereum account
-uint8_t helperData[51];
-
-//These variables are used to save the addresses in ASCII associated to the SmartNFT and the SmartNFT ID
-unsigned char OwnerAddress[42];
-unsigned char UserAddress[42];
-unsigned char deviceAddress[43];
-uint32_t tokenID;
-
-//Wifi setup parameters: IT MUST BE CHANGED
-int wificounter = 0;
-const char *ssid = "";
-const char *password = "= 10)
- {
- printf("Restarting ...\n");
- ESP.restart(); //Targeting 8266 & ESP32. You may need to replace this
-
- }
-
- delay(10);
-
- printf("\n");
- printf("WiFi connected.\n");
- printf("IP address: %d.%d.%d.%d\n",WiFi.localIP()[0],WiFi.localIP()[1],WiFi.localIP()[2],WiFi.localIP()[3]);
-}
-
-STATES queryTokenStatus(){
- Contract contract(&web3, EIP4519CONTRACT);
- //Generate the JSON to check the status
- deviceAddress[0] = '0';
- deviceAddress[1] = 'x';
- for(int i = 0 ; i < 20 ; i++){
- hex2Char(ðAddress[i], &deviceAddress[2*i+2], &deviceAddress[2*i+3]);
- }
-
- String tokenAddress;
-
- printf("Query Status from token : ");
- for(int i = 0 ; i < 40 ; i++){
- printf("%c",deviceAddress[i+2]);
- tokenDevice[i+2] = deviceAddress[i+2];
- }
- printf("\n");
-
-
- //Call the function to get SmartNFT information
- String func = "getInfoTokenFromBCA(address)";
- string param = contract.SetupContractData(func.c_str(), &tokenDevice);
- string result = contract.ViewCall(¶m);
-
- //When data from blockchain are received, the SmartNFT information is saved
- printf("%s\n",result.c_str());
- int i = 0;
- while(result[i] != 'x'){
- i++;
- }
- i++;
- OwnerAddress[0] = UserAddress[0] = '0';
- OwnerAddress[1] = UserAddress[1] = 'x';
- //Owner address
- for(int j =24;j<64;j++){
- OwnerAddress[j-22] = result[i+j];
- }
- i +=64;
- //User address
- for(int j =24;j<64;j++){
- UserAddress[j-22] = result[i+j];
- }
-
- printf("\nOwner of token : 0x");
- for(int j = 0 ; j < 40 ; j++){
- printf("%c",OwnerAddress[j+2]);
- }
- printf("\nUser of token : 0x");
- for(int j = 0 ; j < 40 ; j++){
- printf("%c",UserAddress[j+2]);
- }
- i +=64;
-
- //tokenID
- tokenID = HexTo4Bits(result[i+56])*268435456+HexTo4Bits(result[i+57])*16777216+HexTo4Bits(result[i+58])*1048576+HexTo4Bits(result[i+59])*65536+HexTo4Bits(result[i+60])*4096+HexTo4Bits(result[i+61])*256+HexTo4Bits(result[i+62])*16+HexTo4Bits(result[i+63]);
- printf("\nToken ID = %d\n",tokenID);
-
- //SmartNFT state
- switch ((result[i+63])
- {
- case '1':
- return engagedWithOwner;
- break;
- case '2':
- return waitingForUser;
- break;
- case '3':
- return engagedWithUser;
- break;
- default:
- return waitingForOwner
- break;
- }
-}
-
-
-uint8_t HexTo4Bits(uint8_t Hex){
- if (Hex>='0'&&Hex<='9'){
- return (Hex-'0');
- }else if(Hex>='a'&&Hex<='f'){
- return Hex-'a'+10;
- }else if(Hex>='A'&&Hex<='F'){
- return Hex-'A'+10;
- }
-}
-
-void hex2Char(unsigned char *inHex, unsigned char *charH, unsigned char *charL){
- uint8_t charIN[2];
- charIN[0] = (inHex[0] / 16);
- charIN[1] = (inHex[0] % 16);
- if (charIN[0] < 10){
- charH[0] = charIN[0] + '0';
- }else{
- charH[0] = charIN[0] + 'a' - 10;
- }
- if (charIN[1] < 10){
- charL[0] = charIN[1] + '0';
- }else{
- charL[0] = charIN[1] + 'a' - 10;
- }
-}
-
-void sendEngage(){
- Contract contract(&web3, EIP4519CONTRACT);
- //Define the function to call the blockchain. This function depends on the SmartNFT state
- string func;
- if(tokenState == waitingForOwner){
- func = "ownerEngagement(uint256)";
- }else if(tokenState == waitingForUser){
- func = "userEngagement(uint256)";
- }
-
- //Generate the hash of the shared key
- keccak_256(K_XD,32,hash_K_XD);
-
- //Put this hash as a uint256 variable
- uint256_t hash_K_XD_uin256 = 0;
- for(int i =0 ; i < 32 ; i++){
- hash_K_XD_uin256 += (uint256_t)hash_K_XD[i]<<8*(7-i);
- }
-
- //Call the function
- string param = contract.SetupContractData(func.c_str(), &hash_K_XD_uin256);
- string result = contract.Call(¶m);
-
-}
diff --git a/assets/eip-4519/ESP32_Firmware/readme.md b/assets/eip-4519/ESP32_Firmware/readme.md
deleted file mode 100644
index 611e466..0000000
--- a/assets/eip-4519/ESP32_Firmware/readme.md
+++ /dev/null
@@ -1,16 +0,0 @@
-#EIP4519 Proof of Concept - Firmware
-This firmware is designed for a device using an ESP32 as a smart asset associated with an EIP4519 SmartNFT. The device has two operation modes: registration mode and application mode.
-##Registration mode
-In this mode, the device generates 51 bytes with the TRNG of the ESP32 core. Those bytes are used for the initial values of a CTR-DRBG PRNG to generate the private key of the Ethereum account. Only the address of this account is shared. The UART port is needed for communications with this device.
-The commands in this mode are:
->‘0’ – Check if the device is ready.
->‘1’ – Share the address of the account.
->‘2’ – Save the initial values of CTR-DRBG PRNG in an EEPROM and changes the operation mode.
-##Application Mode
-The device reads the EEPROM to obtain the initial values of the CTR-DRBG PRNG and recover the Ethereum account. The device connects to a WiFi station. With Infura, the device checks the state of its associated SmartNFT registered on an EIP4519 Smart Contract and also checks if the device must be engaged with the owner or the user. The UART port is needed for communications with this device.
-The commands in this mode are:
->'Z'+OWNER/USER_ADDRESS – The device checks if the address must be authenticated and generates a nonce.
->'Y'+SIGN_D+'#'+NONCE_D – The device checks the signature, signs NONCE_D, and sends the signature.
->'Y'+SIGNED_PK+'#'+PK – The device checks the signature, generates the shared key, and sends the transaction to the EIP4519 Smart Contract.
->'C' – The EEPROM is cleared, only for debug process.
->'R' – The device is restarted to refresh the SmartNFT state, only for debug process.
diff --git a/assets/eip-4519/PoC_SmartNFT/ERC721_interface.sol b/assets/eip-4519/PoC_SmartNFT/ERC721_interface.sol
deleted file mode 100644
index 1fef13e..0000000
--- a/assets/eip-4519/PoC_SmartNFT/ERC721_interface.sol
+++ /dev/null
@@ -1,126 +0,0 @@
-///SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-/// @title ERC-721 Non-Fungible Token Standard
-/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
-/// Note: the ERC-165 identifier for this interface is 0x80ac58cd
-interface ERC721 /* is ERC165 */ {
- /// @dev This emits when ownership of any NFT changes by any mechanism.
- /// This event emits when NFTs are created (`from` == 0) and destroyed
- /// (`to` == 0). Exception: during contract creation, any number of NFTs
- /// may be created and assigned without emitting Transfer. At the time of
- /// any transfer, the approved address for that NFT (if any) is reset to none.
- event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
-
- /// @dev This emits when the approved address for an NFT is changed or
- /// reaffirmed. The zero address indicates there is no approved address.
- /// When a Transfer event emits, this also indicates that the approved
- /// address for that NFT (if any) is reset to none.
- event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
-
- /// @dev This emits when an operator is enabled or disabled for an owner.
- /// The operator can manage all NFTs of the owner.
- event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
-
- /// @notice Count all NFTs assigned to an owner
- /// @dev NFTs assigned to the zero address are considered invalid, and this
- /// function throws for queries about the zero address.
- /// @param _owner An address for whom to query the balance
- /// @return The number of NFTs owned by `_owner`, possibly zero
- function balanceOf(address _owner) external view returns (uint256);
-
- /// @notice Find the owner of an NFT
- /// @dev NFTs assigned to zero address are considered invalid, and queries
- /// about them do throw.
- /// @param _tokenId The identifier for an NFT
- /// @return The address of the owner of the NFT
- function ownerOf(uint256 _tokenId) external view returns (address);
-
- /// @notice Transfers the ownership of an NFT from one address to another address
- /// @dev Throws unless `msg.sender` is the current owner, an authorized
- /// operator, or the approved address for this NFT. Throws if `_from` is
- /// not the current owner. Throws if `_to` is the zero address. Throws if
- /// `_tokenId` is not a valid NFT. When transfer is complete, this function
- /// checks if `_to` is a smart contract (code size > 0). If so, it calls
- /// `onERC721Received` on `_to` and throws if the return value is not
- /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`.
- /// @param _from The current owner of the NFT
- /// @param _to The new owner
- /// @param _tokenId The NFT to transfer
- /// @param data Additional data with no specified format, sent in call to `_to`
- function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) external payable;
-
- /// @notice Transfers the ownership of an NFT from one address to another address
- /// @dev This works identically to the other function with an extra data parameter,
- /// except this function just sets data to ""
- /// @param _from The current owner of the NFT
- /// @param _to The new owner
- /// @param _tokenId The NFT to transfer
- function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
-
- /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
- /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
- /// THEY MAY BE PERMANENTLY LOST
- /// @dev Throws unless `msg.sender` is the current owner, an authorized
- /// operator, or the approved address for this NFT. Throws if `_from` is
- /// not the current owner. Throws if `_to` is the zero address. Throws if
- /// `_tokenId` is not a valid NFT.
- /// @param _from The current owner of the NFT
- /// @param _to The new owner
- /// @param _tokenId The NFT to transfer
- function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
-
- /// @notice Set or reaffirm the approved address for an NFT
- /// @dev The zero address indicates there is no approved address.
- /// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
- /// operator of the current owner.
- /// @param _approved The new approved NFT controller
- /// @param _tokenId The NFT to approve
- function approve(address _approved, uint256 _tokenId) external payable;
-
- /// @notice Enable or disable approval for a third party ("operator") to manage
- /// all of `msg.sender`'s assets.
- /// @dev Emits the ApprovalForAll event. The contract MUST allow
- /// multiple operators per owner.
- /// @param _operator Address to add to the set of authorized operators.
- /// @param _approved True if the operator is approved, false to revoke approval
- function setApprovalForAll(address _operator, bool _approved) external;
-
- /// @notice Get the approved address for a single NFT
- /// @dev Throws if `_tokenId` is not a valid NFT
- /// @param _tokenId The NFT to find the approved address for
- /// @return The approved address for this NFT, or the zero address if there is none
- function getApproved(uint256 _tokenId) external view returns (address);
-
-
- /// @notice Query if an address is an authorized operator for another address
- /// @param _owner The address that owns the NFTs
- /// @param _operator The address that acts on behalf of the owner
- /// @return True if `_operator` is an approved operator for `_owner`, false otherwise
- function isApprovedForAll(address _owner, address _operator) external view returns (bool);
-}
-
-interface ERC165 {
- /// @notice Query if a contract implements an interface
- /// @param interfaceID The interface identifier, as specified in ERC-165
- /// @dev Interface identification is specified in ERC-165. This function
- /// uses less than 30,000 gas.
- /// @return `true` if the contract implements `interfaceID` and
- /// `interfaceID` is not 0xffffffff, `false` otherwise
- function supportsInterface(bytes4 interfaceID) external view returns (bool);
-}
-
-interface ERC721TokenReceiver {
- /// @notice Handle the receipt of an NFT
- /// @dev The ERC721 smart contract calls this function on the
- /// recipient after a `transfer`. This function MAY throw to revert and reject the transfer. Return
- /// of other than the magic value MUST result in the transaction being reverted.
- /// @notice The contract address is always the message sender.
- /// @param _operator The address which called `safeTransferFrom` function
- /// @param _from The address which previously owned the token
- /// @param _tokenId The NFT identifier which is being transferred
- /// @param _data Additional data with no specified format
- /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
- /// unless throwing
- function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes memory _data) external returns(bytes4);
-}
diff --git a/assets/eip-4519/PoC_SmartNFT/PoC_SmartNFT.sol b/assets/eip-4519/PoC_SmartNFT/PoC_SmartNFT.sol
deleted file mode 100644
index 2681dbc..0000000
--- a/assets/eip-4519/PoC_SmartNFT/PoC_SmartNFT.sol
+++ /dev/null
@@ -1,272 +0,0 @@
-///SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./smartNFT_interface.sol";
-import "./ERC721_interface.sol";
-
-contract smartNFT_SC is ERC721,smartNFT{
- enum States { waitingForOwner, engagedWithOwner, waitingForUser, engagedWithUser }
-
- address manufacturer; //Address of manufacturer and owner of Smart Contract
- uint256 tokenCounter; //To give a genuine tokenID based on the number of tokens created
- mapping(uint256 => address) ownerOfSD; //To khow who is the owner of a specific owner
- mapping(address => uint256) tokenIDOfBCA; //To khow which is the tokenID associated to a secure device from the address
- mapping(address => uint256) ownerBalance; //To know how many tokens an owner has
- mapping(address => uint256) userBalance; //To know how many tokens a user can use
-
- struct Token_Struct{
- address approved; //Indicate who can transfer this token, 0 if no one
- address SD; //Indicate the address of the secure device associated to this token
- address user; //Indicate who can use this secure device
- States state; //If blocked (false) then token should be verified by a new user or a new owner
- uint256 hashK_OD; //Hash of the Key shared between owner and device
- uint256 hashK_UD; //Hash of the Key shared between user and device
- uint256 dataEngagement; //Public Key to create K_OD or K_UD depending on token state
- uint256 timestamp; //Last time that device updated its proof of live
- uint256 timeout; //timeout to verify a device error
- }
-
- Token_Struct[] Secure_Token;
-
- constructor() {
- manufacturer = msg.sender;
- tokenCounter = 1;
- Secure_Token.push(Token_Struct(address(0), address(0), address(0), States.waitingForOwner,0,0,0,0,0));
-
- }
-
- function createToken(address _addressSD, address _addressOwner) public virtual override returns (uint256){
- //Check if the sender of message is the manufacturer
- require(manufacturer == msg.sender);
- //Check if the Blockchain Account of the secure device is in the SmartContract
- if(tokenFromBCA(_addressSD)==0){
- //Create a new token
- Secure_Token.push(Token_Struct(address(0), _addressSD, address(0), States.waitingForOwner,0,0,0,block.timestamp,86400));
- //Assigning a new tokenId
- uint256 _tokenId = tokenCounter ++;
- tokenIDOfBCA[_addressSD] = _tokenId;
- //Assigning the owner
- ownerOfSD[_tokenId] = _addressOwner;
- ownerBalance[_addressOwner]++;
- //Return tokenId obtained
- return(_tokenId);
- }else{
- //If the BCA already exists then return the _tokenId
- return(tokenFromBCA(_addressSD));
- }
- }
-
- function setUser(uint256 _tokenId, address _addressUser) public virtual override{
- //Check the sender and the token state
- require((ownerOfSD[_tokenId] == msg.sender) && (Secure_Token[_tokenId].state >= States.engagedWithOwner));
- if((Secure_Token[_tokenId].timestamp + Secure_Token[_tokenId].timeout) > block.timestamp){
- //Only to avoid overflow, for example, in address 0.
- if(userBalance[Secure_Token[_tokenId].user]>0){
- //Update the balance of tokens assigned to the old user
- userBalance[Secure_Token[_tokenId].user]--;
- }
- //Update the balance of tokens assigned to the new user
- userBalance[_addressUser]++;
- //Assign the new user to the token
- Secure_Token[_tokenId].user = _addressUser;
- //Update the state of the token
- Secure_Token[_tokenId].state = States.waitingForUser;
- //Erase old key exchange data between device with old user assigned
- Secure_Token[_tokenId].dataEngagement =0;
- Secure_Token[_tokenId].hashK_UD = 0;
- emit UserAssigned(_tokenId,_addressUser);
- }else{
- Secure_Token[_tokenId].user = address(0);
- emit TimeoutAlarm(_tokenId);
- }
- }
-
- function startOwnerEngagement(uint256 _tokenId, uint256 _dataEngagement, uint256 _hashK_O) public virtual override{
- //Check if sender is the Owner of token and the State of token
- require(ownerOfSD[_tokenId] == msg.sender);
- if((Secure_Token[_tokenId].timestamp + Secure_Token[_tokenId].timeout) > block.timestamp){
- Secure_Token[_tokenId].dataEngagement = _dataEngagement;
- Secure_Token[_tokenId].hashK_OD = _hashK_O;
- }else{
- Secure_Token[_tokenId].user = address(0);
- emit TimeoutAlarm(_tokenId);
- }
- }
-
- function ownerEngagement(uint256 _hashK_D) public virtual override{
- uint256 _tokenId = tokenFromBCA(msg.sender);
- //Check if public key owner-device exists from tokenID of BCA sender
- require(Secure_Token[_tokenId].dataEngagement != 0);
- require (Secure_Token[_tokenId].hashK_OD == _hashK_D);
- require (Secure_Token[_tokenId].state == States.waitingForOwner);
- //Erase PK_Owner-Device and update timestamp
- Secure_Token[_tokenId].dataEngagement = 0;
- Secure_Token[_tokenId].timestamp = block.timestamp;
- //Update the state of token
- Secure_Token[_tokenId].state = States.engagedWithOwner;
- //Send a notification to owner and device
- emit OwnerEngaged(_tokenId);
- }
-
- function startUserEngagement(uint256 _tokenId, uint256 _dataEngagement, uint256 _hashK_U) public virtual override{
- //Check the sender and the state of token
- require(Secure_Token[_tokenId].user == msg.sender);
- if((Secure_Token[_tokenId].timestamp + Secure_Token[_tokenId].timeout) > block.timestamp){
- Secure_Token[_tokenId].dataEngagement = _dataEngagement;
- Secure_Token[_tokenId].hashK_UD = _hashK_U;
- }else{
- Secure_Token[_tokenId].user = address(0);
- emit TimeoutAlarm(_tokenId);
- }
- }
-
- function userEngagement(uint256 _hashK_D) public virtual override{
- uint256 _tokenId = tokenFromBCA(msg.sender);
- //Check if public key user-device exists from tokenID of BCA sender
- require(Secure_Token[_tokenId].dataEngagement != 0);
- require (Secure_Token[_tokenId].hashK_UD == _hashK_D);
- require (Secure_Token[_tokenId].state == States.waitingForUser);
- //Erase PK_User-Device and update timestamp
- Secure_Token[_tokenId].dataEngagement = 0;
- Secure_Token[_tokenId].timestamp = block.timestamp;
- //Update the state of token
- Secure_Token[_tokenId].state = States.engagedWithUser;
- //Send a notification to user and device
- emit UserEngaged(_tokenId);
- }
-
-
- function tokenFromBCA(address _addressSD) public virtual view override returns (uint256){
- return(tokenIDOfBCA[_addressSD]);
- }
-
- function ownerOfFromBCA(address _addressSD) public virtual view override returns (address){
- return(ownerOfSD[tokenIDOfBCA[_addressSD]]);
- }
-
- function userOf(uint256 _tokenId) public virtual view override returns (address){
- return(Secure_Token[_tokenId].user);
- }
-
- function userOfFromBCA(address _addressSD) public virtual override view returns (address){
- return(Secure_Token[tokenIDOfBCA[_addressSD]].user);
- }
-
- function userBalanceOf(address _addressUser) public virtual override view returns (uint256){
- return(userBalance[_addressUser]);
- }
-
- function userBalanceOfAnOwner(address _addressUser, address _addressOwner) public virtual override view returns (uint256){
- //TODO
- }
-
- function getInfoToken(uint256 _tokenId) public view returns ( address _BCA_OWNER,
- address _BCA_USER,
- address _BCA_SD,
- uint8 _state){
- _BCA_OWNER = ownerOfSD[_tokenId];
- _BCA_USER = Secure_Token[_tokenId].user;
- _BCA_SD = Secure_Token[_tokenId].SD;
- if(Secure_Token[_tokenId].state == States.waitingForOwner){
- _state = 0;
- }else if(Secure_Token[_tokenId].state == States.engagedWithOwner){
- _state = 1;
- }else if(Secure_Token[_tokenId].state == States.waitingForUser){
- _state = 2;
- }else {
- _state = 3;
- }
- }
-
- function getInfoTokenFromBCA(address _addressSD) public view returns ( address _BCA_OWNER,
- address _BCA_USER,
- uint256 _tokenId,
- uint8 _state){
- _tokenId = tokenIDOfBCA[_addressSD];
- _BCA_OWNER = ownerOfSD[_tokenId];
- _BCA_USER = Secure_Token[_tokenId].user;
- if(Secure_Token[_tokenId].state == States.waitingForOwner){
- _state = 0;
- }else if(Secure_Token[_tokenId].state == States.engagedWithOwner){
- _state = 1;
- }else if(Secure_Token[_tokenId].state == States.waitingForUser){
- _state = 2;
- }else {
- _state = 3;
- }
- }
-
- function balanceOf(address _owner) public virtual override view returns (uint256){
- return(ownerBalance[_owner]);
- }
-
- function ownerOf(uint256 _tokenId) public virtual override view returns (address){
- return(ownerOfSD[_tokenId]);
- }
-
- function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) public virtual override payable{
-
- }
-
- function safeTransferFrom(address _from, address _to, uint256 _tokenId) public virtual override payable{
- transferFrom(_from, _to, _tokenId);
- }
-
- function transferFrom(address _from, address _to, uint256 _tokenId) public virtual override payable{
- require((ownerOfSD[_tokenId] == msg.sender)||(Secure_Token[_tokenId].approved == msg.sender));
- require(ownerOfSD[_tokenId] == _from);
- if((Secure_Token[_tokenId].timestamp + Secure_Token[_tokenId].timeout) > block.timestamp){
- ownerOfSD[_tokenId] = _to;
- ownerBalance[_from]--;
- ownerBalance[_to]++;
- //Secure_Token[_tokenId].approved = address(0);
- Secure_Token[_tokenId].user = address(0);
- Secure_Token[_tokenId].state = States.waitingForOwner;
- //Erase old key exchange data between device with old Owner
- Secure_Token[_tokenId].dataEngagement = 0;
- Secure_Token[_tokenId].hashK_UD = 0;
- Secure_Token[_tokenId].hashK_OD = 0;
- emit Transfer(_from,_to,_tokenId);
- }else{
- Secure_Token[_tokenId].user = address(0);
- emit TimeoutAlarm(_tokenId);
- }
- }
-
- function approve(address _approved, uint256 _tokenId) public virtual override payable{
-
- }
-
- function setApprovalForAll(address _operator, bool _approved) public virtual override{
-
- }
-
- function getApproved(uint256 _tokenId) public virtual override view returns (address){
-
- }
-
- function isApprovedForAll(address _owner, address _operator) public virtual override view returns (bool){
-
- }
-
- function checkTimeout(uint256 _tokenId) public virtual override returns (bool){
- require(ownerOfSD[_tokenId] == msg.sender);
- if((Secure_Token[_tokenId].timestamp + Secure_Token[_tokenId].timeout) > block.timestamp){
- return true;
- }else{
- Secure_Token[_tokenId].user = address(0);
- emit TimeoutAlarm(_tokenId);
- return false;
- }
- }
-
- function updateTimestamp() public virtual override{
- Secure_Token[tokenFromBCA(msg.sender)].timestamp = block.timestamp;
- }
-
- function setTimeout(uint256 _tokenId, uint256 _timeout) public virtual override{
- require(ownerOfSD[_tokenId] == msg.sender);
- Secure_Token[_tokenId].timeout = _timeout;
- }
-}
diff --git a/assets/eip-4519/PoC_SmartNFT/README.md b/assets/eip-4519/PoC_SmartNFT/README.md
deleted file mode 100644
index cbb2773..0000000
--- a/assets/eip-4519/PoC_SmartNFT/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Proof of concept of an implementation of an Smart Non Fungible Token
-This proof of concept is launch in the Ethereum Kovan Testnet with the address 0x7eB5A03E7ED70ABf70fee48965D0411d37F335aC.
-Use the proposal Non Fungible Token binding assets with SmartNFT and define the user management of the assets.
diff --git a/assets/eip-4519/PoC_SmartNFT/SmartNFT_interface.sol b/assets/eip-4519/PoC_SmartNFT/SmartNFT_interface.sol
deleted file mode 100644
index 6b21203..0000000
--- a/assets/eip-4519/PoC_SmartNFT/SmartNFT_interface.sol
+++ /dev/null
@@ -1,83 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/// @title smartNFT: Hardblock - ERC-721 Non-Fungible Token Standard-based
-interface smartNFT{
- /// @dev This emits when an user of a NFT changes
- /// This event emits when the user of a token is assigned
- /// (`_addressUser` == 0) when a user is unassigned
- event UserAssigned(uint256 indexed tokenID, address indexed _addressUser);
-
- /// @dev This emits when an user of a NFT verifies a device
- /// This event emits when the user of a device finishes the assignment process
- event UserEngaged(uint256 indexed tokenID);
-
- /// @dev This emits when an owner of a NFT verifies a device
- /// This event emits when the owner of a device finishes the transfer process
- event OwnerEngaged(uint256 indexed tokenID);
-
- //TODO: Describe new functions and events
- event TimeoutAlarm(uint256 indexed tokenID);
-
- /// @notice This function defines how the smart device is bound to a new token
- /// @dev Only the manufacturer of the smart device account can create a token and will be the first owner of the token
- /// The initial state of the token is "waitingForOwner" until verified by the new owner
- /// @param _addressSD An address generated by the smart device. Only de smart device can generate this account. _addressOwner is the first owner of the Smart Device
- /// @return The tokenID of the token bound to the smart device
- function createToken(address _addressSD, address _addressOwner) external returns (uint256);
-
- /// @notice This function defines the transference of use of a smart device
- /// @dev Only the owner of the token account can transfer a token provided that the state of the token is "engagedWithOwner","waitingForUser" or "engagedWithUser".
- /// The state of the token must change to "waitingForUser" and the parameter addressUser of the token defined by _tokenID must change to _addressUser
- /// @param _tokenId The tokenID of the smart device
- /// @param _addressUser The address of the new user
- function setUser(uint256 _tokenId, address _addressUser) external;
-
- //TODO: Describe new functions and events
-
- function startOwnerEngagement(uint256 _tokenId, uint256 _dataEngage, uint256 _hashK_O) external;
- function ownerEngagement(uint256 _hashK_D) external;
- function startUserEngagement(uint256 _tokenId, uint256 _dataEngage, uint256 _hashK_U) external;
- function userEngagement(uint256 _hashK_D) external;
- function checkTimeout(uint256 _tokenId) external returns (bool);
- function setTimeout(uint256 _tokenId, uint256 _timeout) external;
- function updateTimestamp() external;
-
- /// @notice This function let us obtain the tokenID from an address of smart device
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _addressSD The address to obtain its token ID
- /// @return The token ID of the token bound to _addressSD
- function tokenFromBCA(address _addressSD) external view returns (uint256);
-
- /// @notice This function let us know who is the owner of the token from the address of the smart device
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _addressSD The address to obtain its owner
- /// @return The owner of the token bound to _addressSD
- function ownerOfFromBCA(address _addressSD) external view returns (address);
-
- /// @notice This function let us know who is the user of the token from the tokenId
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _tokenId of the token to obtain its user
- /// @return The user of the token with _tokenId
- function userOf(uint256 _tokenId) external view returns (address);
-
- /// @notice This function let us know who is the user of the token from the address of the smart device
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _addressSD The address to obtain its user.
- /// @return The user of the token bound to _addressSD.
- function userOfFromBCA(address _addressSD) external view returns (address);
-
- /// @notice This function let us know how many tokens an user has
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _addressUser The address of the user to know the number of tokens
- /// @return The number of tokens of the user
- function userBalanceOf(address _addressUser) external view returns (uint256);
-
- /// @notice This function let us know how many tokens of an owner an user has
- /// @dev Everybody can call this function. It does not execute any code on blockchain, only reads
- /// @param _addressUser The address of the user to know the number of tokens
- /// @param _addressOwner The address of the owner of the tokens
- /// @return The number of tokens of an owner that an user can use
- function userBalanceOfAnOwner(address _addressUser, address _addressOwner) external view returns (uint256);
-}
diff --git a/assets/eip-4519/images/Figure1.jpg b/assets/eip-4519/images/Figure1.jpg
deleted file mode 100644
index ac70ae6..0000000
Binary files a/assets/eip-4519/images/Figure1.jpg and /dev/null differ
diff --git a/assets/eip-4519/images/Figure2.jpg b/assets/eip-4519/images/Figure2.jpg
deleted file mode 100644
index aa99370..0000000
Binary files a/assets/eip-4519/images/Figure2.jpg and /dev/null differ
diff --git a/assets/eip-4519/images/Figure3.jpg b/assets/eip-4519/images/Figure3.jpg
deleted file mode 100644
index dd0e0ef..0000000
Binary files a/assets/eip-4519/images/Figure3.jpg and /dev/null differ
diff --git a/assets/eip-4519/images/Figure4.jpg b/assets/eip-4519/images/Figure4.jpg
deleted file mode 100644
index 62f1f81..0000000
Binary files a/assets/eip-4519/images/Figure4.jpg and /dev/null differ
diff --git a/assets/eip-4519/images/Figure5.jpg b/assets/eip-4519/images/Figure5.jpg
deleted file mode 100644
index 1f8a170..0000000
Binary files a/assets/eip-4519/images/Figure5.jpg and /dev/null differ
diff --git a/assets/eip-4519/sensors-21-03119.pdf b/assets/eip-4519/sensors-21-03119.pdf
deleted file mode 100644
index 1c8f8db..0000000
Binary files a/assets/eip-4519/sensors-21-03119.pdf and /dev/null differ
diff --git a/assets/eip-4671/ERC4671.sol b/assets/eip-4671/ERC4671.sol
deleted file mode 100644
index 5343d9e..0000000
--- a/assets/eip-4671/ERC4671.sol
+++ /dev/null
@@ -1,225 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/utils/Strings.sol";
-import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-
-import "./IERC4671.sol";
-import "./IERC4671Metadata.sol";
-import "./IERC4671Enumerable.sol";
-
-abstract contract ERC4671 is IERC4671, IERC4671Metadata, IERC4671Enumerable, ERC165 {
- // Token data
- struct Token {
- address issuer;
- address owner;
- bool valid;
- }
-
- // Mapping from tokenId to token
- mapping(uint256 => Token) private _tokens;
-
- // Mapping from owner to token ids
- mapping(address => uint256[]) private _indexedTokenIds;
-
- // Mapping from token id to index
- mapping(address => mapping(uint256 => uint256)) private _tokenIdIndex;
-
- // Mapping from owner to number of valid tokens
- mapping(address => uint256) private _numberOfValidTokens;
-
- // Token name
- string private _name;
-
- // Token symbol
- string private _symbol;
-
- // Total number of tokens emitted
- uint256 private _emittedCount;
-
- // Total number of token holders
- uint256 private _holdersCount;
-
- // Contract creator
- address private _creator;
-
- constructor (string memory name_, string memory symbol_) {
- _name = name_;
- _symbol = symbol_;
- _creator = msg.sender;
- }
-
- /// @notice Count all tokens assigned to an owner
- /// @param owner Address for whom to query the balance
- /// @return Number of tokens owned by `owner`
- function balanceOf(address owner) public view virtual override returns (uint256) {
- return _indexedTokenIds[owner].length;
- }
-
- /// @notice Get owner of a token
- /// @param tokenId Identifier of the token
- /// @return Address of the owner of `tokenId`
- function ownerOf(uint256 tokenId) public view virtual override returns (address) {
- return _getTokenOrRevert(tokenId).owner;
- }
-
- /// @notice Check if a token hasn't been revoked
- /// @param tokenId Identifier of the token
- /// @return True if the token is valid, false otherwise
- function isValid(uint256 tokenId) public view virtual override returns (bool) {
- return _getTokenOrRevert(tokenId).valid;
- }
-
- /// @notice Check if an address owns a valid token in the contract
- /// @param owner Address for whom to check the ownership
- /// @return True if `owner` has a valid token, false otherwise
- function hasValid(address owner) public view virtual override returns (bool) {
- return _numberOfValidTokens[owner] > 0;
- }
-
- /// @return Descriptive name of the tokens in this contract
- function name() public view virtual override returns (string memory) {
- return _name;
- }
-
- /// @return An abbreviated name of the tokens in this contract
- function symbol() public view virtual override returns (string memory) {
- return _symbol;
- }
-
- /// @notice URI to query to get the token's metadata
- /// @param tokenId Identifier of the token
- /// @return URI for the token
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
- _getTokenOrRevert(tokenId);
- bytes memory baseURI = bytes(_baseURI());
- if (baseURI.length > 0) {
- return string(abi.encodePacked(
- baseURI,
- Strings.toHexString(tokenId, 32)
- ));
- }
- return "";
- }
-
- /// @return emittedCount Number of tokens emitted
- function emittedCount() public view override returns (uint256) {
- return _emittedCount;
- }
-
- /// @return holdersCount Number of token holders
- function holdersCount() public view override returns (uint256) {
- return _holdersCount;
- }
-
- /// @notice Get the tokenId of a token using its position in the owner's list
- /// @param owner Address for whom to get the token
- /// @param index Index of the token
- /// @return tokenId of the token
- function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
- uint256[] storage ids = _indexedTokenIds[owner];
- require(index < ids.length, "Token does not exist");
- return ids[index];
- }
-
- /// @notice Get a tokenId by it's index, where 0 <= index < total()
- /// @param index Index of the token
- /// @return tokenId of the token
- function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
- return index;
- }
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
- return
- interfaceId == type(IERC4671).interfaceId ||
- interfaceId == type(IERC4671Metadata).interfaceId ||
- interfaceId == type(IERC4671Enumerable).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /// @notice Prefix for all calls to tokenURI
- /// @return Common base URI for all token
- function _baseURI() internal pure virtual returns (string memory) {
- return "";
- }
-
- /// @notice Mark the token as revoked
- /// @param tokenId Identifier of the token
- function _revoke(uint256 tokenId) internal virtual {
- Token storage token = _getTokenOrRevert(tokenId);
- require(token.valid, "Token is already invalid");
- token.valid = false;
- assert(_numberOfValidTokens[token.owner] > 0);
- _numberOfValidTokens[token.owner] -= 1;
- emit Revoked(token.owner, tokenId);
- }
-
- /// @notice Mint a new token
- /// @param owner Address for whom to assign the token
- /// @return tokenId Identifier of the minted token
- function _mint(address owner) internal virtual returns (uint256 tokenId) {
- tokenId = _emittedCount;
- _mintUnsafe(owner, tokenId, true);
- emit Minted(owner, tokenId);
- _emittedCount += 1;
- }
-
- /// @notice Mint a given tokenId
- /// @param owner Address for whom to assign the token
- /// @param tokenId Token identifier to assign to the owner
- /// @param valid Boolean to assert of the validity of the token
- function _mintUnsafe(address owner, uint256 tokenId, bool valid) internal {
- require(_tokens[tokenId].owner == address(0), "Cannot mint an assigned token");
- if (_indexedTokenIds[owner].length == 0) {
- _holdersCount += 1;
- }
- _tokens[tokenId] = Token(msg.sender, owner, valid);
- _tokenIdIndex[owner][tokenId] = _indexedTokenIds[owner].length;
- _indexedTokenIds[owner].push(tokenId);
- if (valid) {
- _numberOfValidTokens[owner] += 1;
- }
- }
-
- /// @return True if the caller is the contract's creator, false otherwise
- function _isCreator() internal view virtual returns (bool) {
- return msg.sender == _creator;
- }
-
- /// @notice Retrieve a token or revert if it does not exist
- /// @param tokenId Identifier of the token
- /// @return The Token struct
- function _getTokenOrRevert(uint256 tokenId) internal view virtual returns (Token storage) {
- Token storage token = _tokens[tokenId];
- require(token.owner != address(0), "Token does not exist");
- return token;
- }
-
- /// @notice Remove a token
- /// @param tokenId Token identifier to remove
- function _removeToken(uint256 tokenId) internal virtual {
- Token storage token = _getTokenOrRevert(tokenId);
- _removeFromUnorderedArray(_indexedTokenIds[token.owner], _tokenIdIndex[token.owner][tokenId]);
- if (_indexedTokenIds[token.owner].length == 0) {
- assert(_holdersCount > 0);
- _holdersCount -= 1;
- }
- if (token.valid) {
- assert(_numberOfValidTokens[token.owner] > 0);
- _numberOfValidTokens[token.owner] -= 1;
- }
- delete _tokens[tokenId];
- }
-
- /// @notice Removes an entry in an array by its index
- /// @param array Array for which to remove the entry
- /// @param index Index of the entry to remove
- function _removeFromUnorderedArray(uint256[] storage array, uint256 index) internal {
- require(index < array.length, "Trying to delete out of bound index");
- if (index != array.length - 1) {
- array[index] = array[array.length - 1];
- }
- array.pop();
- }
-}
diff --git a/assets/eip-4671/ERC4671Consensus.sol b/assets/eip-4671/ERC4671Consensus.sol
deleted file mode 100644
index bc3f1fc..0000000
--- a/assets/eip-4671/ERC4671Consensus.sol
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-import "./ERC4671.sol";
-import "./IERC4671Consensus.sol";
-
-contract ERC4671Consensus is ERC4671, IERC4671Consensus {
- // Consensus voters addresses
- mapping(address => bool) private _voters;
- address[] private _votersArray;
-
- // Mapping from voter to mint approvals
- mapping(address => mapping(address => bool)) private _mintApprovals;
-
- // Mapping from owner to approval counts
- mapping(address => uint256) private _mintApprovalCounts;
-
- // Mapping from voter to revoke approvals
- mapping(address => mapping(uint256 => bool)) private _revokeApprovals;
-
- // Mapping from tokenId to revoke counts
- mapping(uint256 => uint256) private _revokeApprovalCounts;
-
- constructor (string memory name_, string memory symbol_, address[] memory voters_) ERC4671(name_, symbol_) {
- _votersArray = voters_;
- for (uint256 i=0; i mapping(address => bool)) _allowed;
-
- /// @notice Grant one-time minting right to `operator` for `owner`
- /// An allowed operator can call the function to transfer rights.
- /// @param operator Address allowed to mint a token
- /// @param owner Address for whom `operator` is allowed to mint a token
- function delegate(address operator, address owner) public virtual override {
- _delegateAsDelegateOrCreator(operator, owner, _isCreator());
- }
-
- /// @notice Grant one-time minting right to a list of `operators` for a corresponding list of `owners`
- /// An allowed operator can call the function to transfer rights.
- /// @param operators Addresses allowed to mint a token
- /// @param owners Addresses for whom `operators` are allowed to mint a token
- function delegateBatch(address[] memory operators, address[] memory owners) public virtual override {
- require(operators.length == owners.length, "operators and owners must have the same length");
- bool isCreator = _isCreator();
- for (uint i=0; i address[]) private _records;
-
- // Mapping from owner to IERC4671Enumerable contract index
- mapping(address => mapping(address => uint256)) _indices;
-
- /// @notice Add a IERC4671Enumerable contract address to the caller's record
- /// @param token Address of the IERC4671Enumerable contract to add
- function add(address token) public virtual override {
- address[] storage contracts = _records[msg.sender];
- _indices[msg.sender][token] = contracts.length;
- contracts.push(token);
- emit Added(msg.sender, token);
- }
-
- /// @notice Remove a IERC4671Enumerable contract from the caller's record
- /// @param token Address of the IERC4671Enumerable contract to remove
- function remove(address token) public virtual override {
- uint256 index = _indexOfTokenOrRevert(msg.sender, token);
- address[] storage contracts = _records[msg.sender];
- if (index == contracts.length - 1) {
- _indices[msg.sender][token] = 0;
- } else {
- _indices[msg.sender][contracts[contracts.length - 1]] = index;
- }
- contracts[index] = contracts[contracts.length - 1];
- contracts.pop();
- emit Removed(msg.sender, token);
- }
-
- /// @notice Get all the IERC4671Enumerable contracts for a given owner
- /// @param owner Address for which to retrieve the IERC4671Enumerable contracts
- function get(address owner) public view virtual override returns (address[] memory) {
- return _records[owner];
- }
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
- return
- interfaceId == type(IERC4671Store).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- function _indexOfTokenOrRevert(address owner, address token) private view returns (uint256) {
- uint256 index = _indices[owner][token];
- require(index > 0 || _records[owner].length > 0, "Address not found");
- return index;
- }
-}
diff --git a/assets/eip-4671/IERC4671.sol b/assets/eip-4671/IERC4671.sol
deleted file mode 100644
index 3b97b9d..0000000
--- a/assets/eip-4671/IERC4671.sol
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-interface IERC4671 is IERC165 {
- /// Event emitted when a token `tokenId` is minted for `owner`
- event Minted(address owner, uint256 tokenId);
-
- /// Event emitted when token `tokenId` of `owner` is revoked
- event Revoked(address owner, uint256 tokenId);
-
- /// @notice Count all tokens assigned to an owner
- /// @param owner Address for whom to query the balance
- /// @return Number of tokens owned by `owner`
- function balanceOf(address owner) external view returns (uint256);
-
- /// @notice Get owner of a token
- /// @param tokenId Identifier of the token
- /// @return Address of the owner of `tokenId`
- function ownerOf(uint256 tokenId) external view returns (address);
-
- /// @notice Check if a token hasn't been revoked
- /// @param tokenId Identifier of the token
- /// @return True if the token is valid, false otherwise
- function isValid(uint256 tokenId) external view returns (bool);
-
- /// @notice Check if an address owns a valid token in the contract
- /// @param owner Address for whom to check the ownership
- /// @return True if `owner` has a valid token, false otherwise
- function hasValid(address owner) external view returns (bool);
-}
diff --git a/assets/eip-4671/IERC4671Consensus.sol b/assets/eip-4671/IERC4671Consensus.sol
deleted file mode 100644
index 81e8663..0000000
--- a/assets/eip-4671/IERC4671Consensus.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4671.sol";
-
-interface IERC4671Consensus is IERC4671 {
- /// @notice Get voters addresses for this consensus contract
- /// @return Addresses of the voters
- function voters() external view returns (address[] memory);
-
- /// @notice Cast a vote to mint a token for a specific address
- /// @param owner Address for whom to mint the token
- function approveMint(address owner) external;
-
- /// @notice Cast a vote to revoke a specific token
- /// @param tokenId Identifier of the token to revoke
- function approveRevoke(uint256 tokenId) external;
-}
diff --git a/assets/eip-4671/IERC4671Delegate.sol b/assets/eip-4671/IERC4671Delegate.sol
deleted file mode 100644
index cef2c68..0000000
--- a/assets/eip-4671/IERC4671Delegate.sol
+++ /dev/null
@@ -1,32 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4671.sol";
-
-interface IERC4671Delegate is IERC4671 {
- /// @notice Grant one-time minting right to `operator` for `owner`
- /// An allowed operator can call the function to transfer rights.
- /// @param operator Address allowed to mint a token
- /// @param owner Address for whom `operator` is allowed to mint a token
- function delegate(address operator, address owner) external;
-
- /// @notice Grant one-time minting right to a list of `operators` for a corresponding list of `owners`
- /// An allowed operator can call the function to transfer rights.
- /// @param operators Addresses allowed to mint
- /// @param owners Addresses for whom `operators` are allowed to mint a token
- function delegateBatch(address[] memory operators, address[] memory owners) external;
-
- /// @notice Mint a token. Caller must have the right to mint for the owner.
- /// @param owner Address for whom the token is minted
- function mint(address owner) external;
-
- /// @notice Mint tokens to multiple addresses. Caller must have the right to mint for all owners.
- /// @param owners Addresses for whom the tokens are minted
- function mintBatch(address[] memory owners) external;
-
- /// @notice Get the issuer of a token
- /// @param tokenId Identifier of the token
- /// @return Address who minted `tokenId`
- function issuerOf(uint256 tokenId) external view returns (address);
-}
diff --git a/assets/eip-4671/IERC4671Enumerable.sol b/assets/eip-4671/IERC4671Enumerable.sol
deleted file mode 100644
index 99f0eb3..0000000
--- a/assets/eip-4671/IERC4671Enumerable.sol
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4671.sol";
-
-interface IERC4671Enumerable is IERC4671 {
- /// @return emittedCount Number of tokens emitted
- function emittedCount() external view returns (uint256);
-
- /// @return holdersCount Number of token holders
- function holdersCount() external view returns (uint256);
-
- /// @notice Get the tokenId of a token using its position in the owner's list
- /// @param owner Address for whom to get the token
- /// @param index Index of the token
- /// @return tokenId of the token
- function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
-
- /// @notice Get a tokenId by it's index, where 0 <= index < total()
- /// @param index Index of the token
- /// @return tokenId of the token
- function tokenByIndex(uint256 index) external view returns (uint256);
-}
diff --git a/assets/eip-4671/IERC4671Metadata.sol b/assets/eip-4671/IERC4671Metadata.sol
deleted file mode 100644
index adc2fa5..0000000
--- a/assets/eip-4671/IERC4671Metadata.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4671.sol";
-
-interface IERC4671Metadata is IERC4671 {
- /// @return Descriptive name of the tokens in this contract
- function name() external view returns (string memory);
-
- /// @return An abbreviated name of the tokens in this contract
- function symbol() external view returns (string memory);
-
- /// @notice URI to query to get the token's metadata
- /// @param tokenId Identifier of the token
- /// @return URI for the token
- function tokenURI(uint256 tokenId) external view returns (string memory);
-}
diff --git a/assets/eip-4671/IERC4671Pull.sol b/assets/eip-4671/IERC4671Pull.sol
deleted file mode 100644
index c719273..0000000
--- a/assets/eip-4671/IERC4671Pull.sol
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4671.sol";
-
-interface IERC4671Pull is IERC4671 {
- /// @notice Pull a token from the owner wallet to the caller's wallet
- /// @param tokenId Identifier of the token to transfer
- /// @param owner Address that owns tokenId
- /// @param signature Signed data (tokenId, owner, recipient) by the owner of the token
- function pull(uint256 tokenId, address owner, bytes memory signature) external;
-}
diff --git a/assets/eip-4671/IERC4671Store.sol b/assets/eip-4671/IERC4671Store.sol
deleted file mode 100644
index 601b1f1..0000000
--- a/assets/eip-4671/IERC4671Store.sol
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-interface IERC4671Store is IERC165 {
- // Event emitted when a IERC4671Enumerable contract is added to the owner's records
- event Added(address owner, address token);
-
- // Event emitted when a IERC4671Enumerable contract is removed from the owner's records
- event Removed(address owner, address token);
-
- /// @notice Add a IERC4671Enumerable contract address to the caller's record
- /// @param token Address of the IERC4671Enumerable contract to add
- function add(address token) external;
-
- /// @notice Remove a IERC4671Enumerable contract from the caller's record
- /// @param token Address of the IERC4671Enumerable contract to remove
- function remove(address token) external;
-
- /// @notice Get all the IERC4671Enumerable contracts for a given owner
- /// @param owner Address for which to retrieve the IERC4671Enumerable contracts
- function get(address owner) external view returns (address[] memory);
-}
diff --git a/assets/eip-4675/.gitignore b/assets/eip-4675/.gitignore
deleted file mode 100644
index 4015467..0000000
--- a/assets/eip-4675/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-# Dependency directory
-node_modules
-
-# hardhat
-cache
-artifacts
-
-# macos
-.DS_Store
-
-# IntelliJ IDE
-.idea
\ No newline at end of file
diff --git a/assets/eip-4675/.solcover.js b/assets/eip-4675/.solcover.js
deleted file mode 100644
index e532fc1..0000000
--- a/assets/eip-4675/.solcover.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- skipFiles: ['contracts/ERC20Token.sol']
-};
\ No newline at end of file
diff --git a/assets/eip-4675/README.md b/assets/eip-4675/README.md
deleted file mode 100644
index 5a14c32..0000000
--- a/assets/eip-4675/README.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Multi-Fractional Non-Fungible Token
-Solidity Implementation of Multi-Fractional Non-Fungible Token.
-
-## Problem Trying to solve
-Before, ERC20 Token contract should be deployed every time when fractionalizing a specific NFT.
-
-To solve this problem, this standard proposes a token standard to cover multiple fractionalized nft in a contract without having to deploy each time.
-
-Issue : https://github.com/ethereum/EIPs/issues/4674
-
-PR : https://github.com/ethereum/EIPs/pull/4675
-
-## How to use
-```
-contracts/
- helper/
- interface/
- math/
- MFNFT.sol
- NFT.sol
- ERC20Token.sol
-```
-
-### Contracts
-``MFNFT.sol`` : Multi-Fractional Non-Fungible Token Contract
-
-``NFT.sol`` : Non-Fungible Token Contract
-
-``ERC20Token.sol`` : Sample ERC-20 Token Contract
-
-``helper/Verifier.sol`` : Contract that verifies the ownership of NFT before fractionalization
-
-``math/SafeMath.sol`` : Openzeppelin SafeMath Library
-
-``interface/IERC20.sol`` : ERC-20 Token Interface
-
-``interface/IERC721.sol`` : ERC-721 Token Interface
-
-``interface/IMFNFT`` : MFNFT Token Interface
-
-### Install & Test
-
-Installation
-```
-npm install
-```
-
-Test
-```
-npx hardhat test
-```
-
-Coverage
-```
-npx hardhat coverage
-```
diff --git a/assets/eip-4675/contracts/ERC20Token.sol b/assets/eip-4675/contracts/ERC20Token.sol
deleted file mode 100644
index 6b8f5fa..0000000
--- a/assets/eip-4675/contracts/ERC20Token.sol
+++ /dev/null
@@ -1,236 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./interface/IERC20.sol";
-import "./math/SafeMath.sol";
-
-/**
- * @title Standard RFT(ERC1633) token extending ERC20
- *
- * @dev Implementation of the basic standard token.
- * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
- * Originally based on code by FirstBlood:
- * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
- *
- * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
- * all accounts just by listening to said events. Note that this isn't required by the specification, and other
- * compliant implementations may not do it.
- */
-contract FT is IERC20 {
- using SafeMath for uint256;
-
- mapping(address => uint256) private _balances;
-
- mapping(address => mapping(address => uint256)) private _allowed;
-
- uint256 private _totalSupply;
-
- // NFT Contract Address
- address private _parentToken;
-
- // NFT ID of NFT(RFT) - TokenId
- uint256 private _parentTokenId;
-
- // Admin Address to Set the Parent NFT
- address private _admin;
-
- constructor(uint256 total_supply) {
- _totalSupply = total_supply;
- _balances[msg.sender] = total_supply;
- _admin = msg.sender;
- }
-
- /**
- * @dev Total number of tokens in existence
- */
- function totalSupply() public view override returns (uint256) {
- return _totalSupply;
- }
-
- /**
- * @dev Gets the balance of the specified address.
- * @param owner The address to query the balance of.
- * @return An uint256 representing the amount owned by the passed address.
- */
- function balanceOf(address owner) public view override returns (uint256) {
- return _balances[owner];
- }
-
- /**
- * @dev Function to check the amount of tokens that an owner allowed to a spender.
- * @param owner address The address which owns the funds.
- * @param spender address The address which will spend the funds.
- * @return A uint256 specifying the amount of tokens still available for the spender.
- */
- function allowance(address owner, address spender)
- public
- view
- override
- returns (uint256)
- {
- return _allowed[owner][spender];
- }
-
- /**
- * @dev Transfer token for a specified address
- * @param to The address to transfer to.
- * @param value The amount to be transferred.
- */
- function transfer(address to, uint256 value)
- public
- override
- returns (bool)
- {
- _transfer(msg.sender, to, value);
- return true;
- }
-
- /**
- * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
- * Beware that changing an allowance with this method brings the risk that someone may use both the old
- * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
- * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
- * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- * @param spender The address which will spend the funds.
- * @param value The amount of tokens to be spent.
- */
- function approve(address spender, uint256 value)
- public
- override
- returns (bool)
- {
- require(spender != address(0));
-
- _allowed[msg.sender][spender] = value;
- emit Approval(msg.sender, spender, value);
- return true;
- }
-
- /**
- * @dev Transfer tokens from one address to another.
- * Note that while this function emits an Approval event, this is not required as per the specification,
- * and other compliant implementations may not emit the event.
- * @param from address The address which you want to send tokens from
- * @param to address The address which you want to transfer to
- * @param value uint256 the amount of tokens to be transferred
- */
- function transferFrom(
- address from,
- address to,
- uint256 value
- ) public override returns (bool) {
- _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
- _transfer(from, to, value);
- emit Approval(from, msg.sender, _allowed[from][msg.sender]);
- return true;
- }
-
- /**
- * @dev Increase the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed_[_spender] == 0. To increment
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * Emits an Approval event.
- * @param spender The address which will spend the funds.
- * @param addedValue The amount of tokens to increase the allowance by.
- */
- function increaseAllowance(address spender, uint256 addedValue)
- public
- returns (bool)
- {
- require(spender != address(0));
-
- _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(
- addedValue
- );
- emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
- return true;
- }
-
- /**
- * @dev Decrease the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed_[_spender] == 0. To decrement
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * Emits an Approval event.
- * @param spender The address which will spend the funds.
- * @param subtractedValue The amount of tokens to decrease the allowance by.
- */
- function decreaseAllowance(address spender, uint256 subtractedValue)
- public
- returns (bool)
- {
- require(spender != address(0));
-
- _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(
- subtractedValue
- );
- emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
- return true;
- }
-
- /**
- * @dev Transfer token for a specified addresses
- * @param from The address to transfer from.
- * @param to The address to transfer to.
- * @param value The amount to be transferred.
- */
- function _transfer(
- address from,
- address to,
- uint256 value
- ) internal {
- require(to != address(0));
-
- _balances[from] = _balances[from].sub(value);
- _balances[to] = _balances[to].add(value);
- emit Transfer(from, to, value);
- }
-
- /**
- * @dev Internal function that mints an amount of the token and assigns it to
- * an account. This encapsulates the modification of balances such that the
- * proper events are emitted.
- * @param account The account that will receive the created tokens.
- * @param value The amount that will be created.
- */
- function _mint(address account, uint256 value) internal {
- require(account != address(0));
-
- _totalSupply = _totalSupply.add(value);
- _balances[account] = _balances[account].add(value);
- emit Transfer(address(0), account, value);
- }
-
- /**
- * @dev Internal function that burns an amount of the token of a given
- * account.
- * @param account The account whose tokens will be burnt.
- * @param value The amount that will be burnt.
- */
- function _burn(address account, uint256 value) internal {
- require(account != address(0));
-
- _totalSupply = _totalSupply.sub(value);
- _balances[account] = _balances[account].sub(value);
- emit Transfer(account, address(0), value);
- }
-
- /**
- * @dev Internal function that burns an amount of the token of a given
- * account, deducting from the sender's allowance for said account. Uses the
- * internal burn function.
- * Emits an Approval event (reflecting the reduced allowance).
- * @param account The account whose tokens will be burnt.
- * @param value The amount that will be burnt.
- */
- function _burnFrom(address account, uint256 value) internal {
- _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(
- value
- );
- _burn(account, value);
- emit Approval(account, msg.sender, _allowed[account][msg.sender]);
- }
-}
diff --git a/assets/eip-4675/contracts/MFNFT.sol b/assets/eip-4675/contracts/MFNFT.sol
deleted file mode 100644
index 098b4af..0000000
--- a/assets/eip-4675/contracts/MFNFT.sol
+++ /dev/null
@@ -1,346 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./interface/IMFNFT.sol";
-import "./interface/IERC721.sol";
-import "./math/SafeMath.sol";
-import "./helper/Verifier.sol";
-
-/**
- * @title TWIG_FNFT Contract
- */
-contract MFNFT is IMFNFT, Verifier {
- using SafeMath for uint256;
-
- mapping(uint256 => mapping(address => uint256)) private _balances;
-
- mapping(uint256 => mapping(address => mapping(address => uint256)))
- private _allowed;
-
- // uint256 private _totalSupply;
- mapping(uint256 => uint256) _totalSupply;
-
- // NFT Contract Address
- // address private _parentToken;
- mapping(uint256 => address) _parentToken;
-
- // NFT ID of NFT(RFT) - TokenId
- // uint256 private _parentTokenId;
- mapping(uint256 => uint256) _parentTokenId;
-
- //
- mapping(address => mapping(uint256 => uint256)) private _Ids;
-
- // Scalar value to distinguish fractionalized NFT
- uint256 public _id;
-
- // Admin Address to Set the Parent NFT
- address private _admin;
-
- // Event emitted when token is added
- event TokenAddition(
- address indexed token,
- uint256 tokenId,
- uint256 _id,
- uint256 totalSupply
- );
-
- constructor() {
- _admin = msg.sender;
- }
-
- /**
- * @dev onlyAdmin prohibits function calls arbitrary msg.sender
- * except _admin
- */
- modifier onlyAdmin() {
- require(msg.sender == _admin);
- _;
- }
-
- /**
- * @dev Mandatory function to receive NFT as a contract(CA)
- * @return Bytes4 which is the selector of this function
- */
- function onERC721Received(
- address _operator,
- address _from,
- uint256 _tokenId,
- bytes calldata _data
- ) external pure returns (bytes4) {
- return this.onERC721Received.selector;
- }
-
- /**
- * @dev (ERC165) Determines if this contract supports Re-FT(ERC1633).
- * @param interfaceID The bytes4 to query if it matches with the contract interface id.
- */
- function supportsInterface(bytes4 interfaceID)
- external
- pure
- returns (bool)
- {
- return
- interfaceID == this.supportsInterface.selector || // ERC165
- interfaceID == this.parentToken.selector || // parentToken()
- interfaceID == this.parentTokenId.selector || // parentTokenId()
- interfaceID ==
- this.parentToken.selector ^ this.parentTokenId.selector; // RFT
- }
-
- /**
- * @dev Sets the Address of NFT Contract Address & NFT Token ID
- * @param parentNFTContractAddress The address NFT Contract address.
- * @param parentNFTTokenId The token id of NFT.
- */
- function setParentNFT(
- address parentNFTContractAddress,
- uint256 parentNFTTokenId,
- uint256 totalSupply
- ) public onlyAdmin {
- require(
- parentNFTContractAddress != address(0),
- "MFNFT::setParentNFT: Parent NFT Contract should not be zero"
- );
- require(
- getTokenId(parentNFTContractAddress, parentNFTTokenId) == 0,
- "MFNFT::setParentNFT: Already owned(fractionalized) by this contract"
- );
-
- verifyOwnership(parentNFTContractAddress, parentNFTTokenId);
-
- _id++;
-
- _Ids[parentNFTContractAddress][parentNFTTokenId] = _id;
-
- _parentToken[_id] = parentNFTContractAddress;
- _parentTokenId[_id] = parentNFTTokenId;
-
- _totalSupply[_id] = totalSupply;
- _balances[_id][msg.sender] = totalSupply;
-
- emit TokenAddition(
- parentNFTContractAddress,
- parentNFTTokenId,
- _id,
- totalSupply
- );
- }
-
- /**
- * @dev Returns the tokenId of with the given NFT information
- * @return An uint256 value representing the tokenId of given NFT
- */
- function getTokenId(address token, uint256 tokenId)
- public
- view
- returns (uint256)
- {
- return _Ids[token][tokenId];
- }
-
- /**
- * @dev Returns if the NFT is owned(fractionalized) by this contract.
- * @return An bool representing whether the NFT is fractionalized by this contract
- */
- function isRegistered(address token, uint256 tokenId) public view returns (bool) {
- return (_Ids[token][tokenId] != 0);
- }
-
- /**
- * @dev Returns the Address of Parent Token Address
- * @return An Address representing the address of NFT Contract this Re-FT is pointing to.
- */
- function parentToken(uint256 tokenId) external view returns (address) {
- return _parentToken[tokenId];
- }
-
- /**
- * @dev Returns the Token ID of NFT
- * @return An uint256 representing the token id of the NFT this Re-FT is pointing to.
- */
- function parentTokenId(uint256 tokenId) external view returns (uint256) {
- return _parentTokenId[tokenId];
- }
-
- /**
- * @dev Total number of tokens in existence
- */
- function totalSupply(uint256 tokenId)
- public
- view
- override
- returns (uint256)
- {
- return _totalSupply[tokenId];
- }
-
- /**
- * @dev Gets the balance of the specified address.
- * @param owner The address to query the balance of.
- * @return An uint256 representing the amount owned by the passed address.
- */
- function balanceOf(address owner, uint256 tokenId)
- public
- view
- override
- returns (uint256)
- {
- return _balances[tokenId][owner];
- }
-
- /**
- * @dev Function to check the amount of tokens that an owner allowed to a spender.
- * @param owner address The address which owns the funds.
- * @param spender address The address which will spend the funds.
- * @return A uint256 specifying the amount of tokens still available for the spender.
- */
- function allowance(
- address owner,
- address spender,
- uint256 tokenId
- ) public view override returns (uint256) {
- return _allowed[tokenId][owner][spender];
- }
-
- /**
- * @dev Transfer token for a specified address
- * @param to The address to transfer to.
- * @param value The amount to be transferred.
- */
- function transfer(
- address to,
- uint256 tokenId,
- uint256 value
- ) public override returns (bool) {
- _transfer(msg.sender, to, tokenId, value);
- return true;
- }
-
- /**
- * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
- * Beware that changing an allowance with this method brings the risk that someone may use both the old
- * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
- * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
- * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- * @param spender The address which will spend the funds.
- * @param value The amount of tokens to be spent.
- */
- function approve(
- address spender,
- uint256 tokenId,
- uint256 value
- ) public override returns (bool) {
- require(spender != address(0));
-
- _allowed[tokenId][msg.sender][spender] = value;
- emit Approval(msg.sender, spender, tokenId, value);
- return true;
- }
-
- /**
- * @dev Transfer tokens from one address to another.
- * Note that while this function emits an Approval event, this is not required as per the specification,
- * and other compliant implementations may not emit the event.
- * @param from address The address which you want to send tokens from
- * @param to address The address which you want to transfer to
- * @param value uint256 the amount of tokens to be transferred
- */
- function transferFrom(
- address from,
- address to,
- uint256 tokenId,
- uint256 value
- ) public override returns (bool) {
- _allowed[tokenId][from][msg.sender] = _allowed[tokenId][from][
- msg.sender
- ].sub(value);
- _transfer(from, to, tokenId, value);
- emit Approval(
- from,
- msg.sender,
- tokenId,
- _allowed[tokenId][from][msg.sender]
- );
- return true;
- }
-
- /**
- * @dev Increase the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed_[_spender] == 0. To increment
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * Emits an Approval event.
- * @param spender The address which will spend the funds.
- * @param addedValue The amount of tokens to increase the allowance by.
- */
- function increaseAllowance(
- address spender,
- uint256 tokenId,
- uint256 addedValue
- ) public returns (bool) {
- require(spender != address(0));
-
- _allowed[tokenId][msg.sender][spender] = _allowed[tokenId][msg.sender][
- spender
- ].add(addedValue);
-
- emit Approval(
- msg.sender,
- spender,
- tokenId,
- _allowed[tokenId][msg.sender][spender]
- );
- return true;
- }
-
- /**
- * @dev Decrease the amount of tokens that an owner allowed to a spender.
- * approve should be called when allowed_[_spender] == 0. To decrement
- * allowed value is better to use this function to avoid 2 calls (and wait until
- * the first transaction is mined)
- * From MonolithDAO Token.sol
- * Emits an Approval event.
- * @param spender The address which will spend the funds.
- * @param subtractedValue The amount of tokens to decrease the allowance by.
- */
- function decreaseAllowance(
- address spender,
- uint256 tokenId,
- uint256 subtractedValue
- ) public returns (bool) {
- require(spender != address(0));
-
- _allowed[tokenId][msg.sender][spender] = _allowed[tokenId][msg.sender][
- spender
- ].sub(subtractedValue);
- emit Approval(
- msg.sender,
- spender,
- tokenId,
- _allowed[tokenId][msg.sender][spender]
- );
- return true;
- }
-
- /**
- * @dev Transfer token for a specified addresses
- * @param from The address to transfer from.
- * @param to The address to transfer to.
- * @param value The amount to be transferred.
- */
- function _transfer(
- address from,
- address to,
- uint256 tokenId,
- uint256 value
- ) internal {
- require(to != address(0));
-
- _balances[tokenId][from] = _balances[tokenId][from].sub(value);
- _balances[tokenId][to] = _balances[tokenId][to].add(value);
-
- emit Transfer(from, to, tokenId, value);
- }
-}
diff --git a/assets/eip-4675/contracts/NFT.sol b/assets/eip-4675/contracts/NFT.sol
deleted file mode 100644
index 2dd6edb..0000000
--- a/assets/eip-4675/contracts/NFT.sol
+++ /dev/null
@@ -1,35 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-
-contract NFT is ERC721, ERC721Enumerable, ERC721Burnable, Ownable {
- constructor() ERC721("MyToken", "MTK") {}
-
- function safeMint(address to, uint256 tokenId) public onlyOwner {
- _safeMint(to, tokenId);
- }
-
- function _baseURI() internal pure override returns (string memory) {
- return "Test";
- }
-
- function _beforeTokenTransfer(address from, address to, uint256 tokenId)
- internal
- override(ERC721, ERC721Enumerable)
- {
- super._beforeTokenTransfer(from, to, tokenId);
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- override(ERC721, ERC721Enumerable)
- returns (bool)
- {
- return super.supportsInterface(interfaceId);
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4675/contracts/helper/Verifier.sol b/assets/eip-4675/contracts/helper/Verifier.sol
deleted file mode 100644
index de3af4c..0000000
--- a/assets/eip-4675/contracts/helper/Verifier.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-contract Verifier {
-
- function verifyOwnership(
- address token,
- uint256 tokenId
- ) internal {
- // bytes(keccak256(bytes('ownerOf(uint256)')));
- (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x6352211e, tokenId));
- require(
- success && (data.length == 32 && bytesToAddress(data) == address(this)),
- "Verifier::verifyOwnership: NFT ownership verification failed"
- );
- }
-
- function getOwner(
- address token,
- uint256 tokenId
- ) internal returns(address) {
- // bytes(keccak256(bytes('ownerOf(uint256)')));
- (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x6352211e, tokenId));
- require(
- success && (data.length == 32),
- "Verifier::getOwner: NFT ownership verification failed"
- );
- return bytesToAddress(data);
- }
-
- function bytesToAddress(bytes memory bys) internal pure returns (address addr) {
- assembly {
- addr := mload(add(bys,32))
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4675/contracts/interface/IERC20.sol b/assets/eip-4675/contracts/interface/IERC20.sol
deleted file mode 100644
index 912040e..0000000
--- a/assets/eip-4675/contracts/interface/IERC20.sol
+++ /dev/null
@@ -1,24 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-/**
- * @title ERC20 interface
- * @dev see https://github.com/ethereum/EIPs/issues/20
- */
-interface IERC20 {
- function transfer(address to, uint256 value) external returns (bool);
-
- function approve(address spender, uint256 value) external returns (bool);
-
- function transferFrom(address from, address to, uint256 value) external returns (bool);
-
- function totalSupply() external view returns (uint256);
-
- function balanceOf(address who) external view returns (uint256);
-
- function allowance(address owner, address spender) external view returns (uint256);
-
- event Transfer(address indexed from, address indexed to, uint256 value);
-
- event Approval(address indexed owner, address indexed spender, uint256 value);
-}
\ No newline at end of file
diff --git a/assets/eip-4675/contracts/interface/IERC721.sol b/assets/eip-4675/contracts/interface/IERC721.sol
deleted file mode 100644
index ecc6976..0000000
--- a/assets/eip-4675/contracts/interface/IERC721.sol
+++ /dev/null
@@ -1,43 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-/**
- * Contract that exposes the needed erc20 token functions
- */
-
-abstract contract IERC721 {
-
- event Transfer(
- address indexed from,
- address indexed to,
- uint256 indexed tokenaId
- );
-
- event Approval(
- address indexed owner,
- address indexed approved,
- uint256 indexed tokenId
- );
-
- event ApprovalForAll(
- address indexed owner,
- address indexed operator,
- bool approved
- );
-
- function balanceOf(address owner) public virtual view returns (uint256 balance);
- function ownerOf(uint256 tokenId) public virtual view returns (address owner);
-
- function approve(address to, uint256 tokenId) public virtual;
- function getApproved(uint256 tokenId)
- public virtual view returns (address operator);
-
- function setApprovalForAll(address operator, bool _approved) public virtual;
- function isApprovedForAll(address owner, address operator)
- public virtual view returns (bool);
-
- function transferFrom(address from, address to, uint256 tokenId) public virtual;
- function safeTransferFrom(address from, address to, uint256 tokenId) public virtual;
-
-
-}
\ No newline at end of file
diff --git a/assets/eip-4675/contracts/interface/IMFNFT.sol b/assets/eip-4675/contracts/interface/IMFNFT.sol
deleted file mode 100644
index 1c36139..0000000
--- a/assets/eip-4675/contracts/interface/IMFNFT.sol
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IMFNFT {
- function transfer(address to, uint256 tokenId, uint256 value) external returns (bool);
-
- function approve(address spender, uint256 tokenId, uint256 value) external returns (bool);
-
- function transferFrom(address from, address to, uint256 tokenId, uint256 value) external returns (bool);
-
- function totalSupply(uint256 tokenId) external view returns (uint256);
-
- function balanceOf(address who, uint256 tokenId) external view returns (uint256);
-
- function allowance(address owner, address spender, uint256 tokenId) external view returns (uint256);
-
- event Transfer(address indexed from, address indexed to, uint256 tokenId, uint256 value);
-
- event Approval(address indexed owner, address indexed spender, uint256 tokenId, uint256 value);
-}
\ No newline at end of file
diff --git a/assets/eip-4675/hardhat.config.ts b/assets/eip-4675/hardhat.config.ts
deleted file mode 100644
index 044fd60..0000000
--- a/assets/eip-4675/hardhat.config.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { task } from "hardhat/config";
-import "@nomiclabs/hardhat-waffle";
-import "solidity-coverage";
-import "hardhat-deploy";
-import dotenv from "dotenv";
-import type { HardhatUserConfig, HttpNetworkUserConfig } from "hardhat/types";
-
-
-
-// Load environment variables.
-dotenv.config();
-const { NODE_URL, INFURA_KEY, MNEMONIC, ETHERSCAN_API_KEY, PK, SOLIDITY_VERSION, SOLIDITY_SETTINGS } = process.env;
-
-// Test mnemonic
-const DEFAULT_MNEMONIC =
- "candy maple cake sugar pudding cream honey rich smooth crumble sweet treat";
-
-const sharedNetworkConfig: HttpNetworkUserConfig = {};
-if (PK) {
- sharedNetworkConfig.accounts = [PK];
-} else {
- sharedNetworkConfig.accounts = {
- mnemonic: MNEMONIC || DEFAULT_MNEMONIC,
- };
-}
-
-const primarySolidityVersion = SOLIDITY_VERSION || "0.8.0"
-
-
-const userConfig: HardhatUserConfig = {
- paths: {
- artifacts: "artifacts",
- cache: "cache",
- deploy: "src/deploy",
- sources: "contracts",
- },
- solidity: {
- compilers: [
- { version: primarySolidityVersion },
- { version: "0.6.12" },
- { version: "0.5.17" },
- { version: "0.7.5" },
- ]
- },
- networks: {
- hardhat: {
- allowUnlimitedContractSize: true,
- blockGasLimit: 100000000,
- gas: 100000000
- },
- mainnet: {
- ...sharedNetworkConfig,
- url: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
- },
- xdai: {
- ...sharedNetworkConfig,
- url: "https://xdai.poanetwork.dev",
- },
- ewc: {
- ...sharedNetworkConfig,
- url: `https://rpc.energyweb.org`,
- },
- rinkeby: {
- ...sharedNetworkConfig,
- url: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
- },
- goerli: {
- ...sharedNetworkConfig,
- url: `https://goerli.infura.io/v3/${INFURA_KEY}`,
- },
- kovan: {
- ...sharedNetworkConfig,
- url: `https://kovan.infura.io/v3/${INFURA_KEY}`,
- },
- volta: {
- ...sharedNetworkConfig,
- url: `https://volta-rpc.energyweb.org`,
- },
- },
- namedAccounts: {
- deployer: 0,
- },
- mocha: {
- timeout: 2000000,
- },
- etherscan: {
- apiKey: ETHERSCAN_API_KEY,
- },
-}
-
-/**
- * @type import('hardhat/config').HardhatUserConfig
- */
-export default userConfig
diff --git a/assets/eip-4675/package.json b/assets/eip-4675/package.json
deleted file mode 100644
index e5728bf..0000000
--- a/assets/eip-4675/package.json
+++ /dev/null
@@ -1,39 +0,0 @@
-{
- "name": "multi-fnft",
- "version": "1.0.0",
- "description": "Solidity Implementation of Multi-Fractional Non Fungible Token",
- "main": "index.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/PowerStream3604/multi-fnft.git"
- },
- "keywords": [],
- "author": "",
- "license": "CC0-1.0",
- "bugs": {
- "url": "https://github.com/PowerStream3604/multi-fnft/issues"
- },
- "homepage": "https://github.com/PowerStream3604/multi-fnft#readme",
- "devDependencies": {
- "@nomiclabs/hardhat-ethers": "^2.0.4",
- "@nomiclabs/hardhat-waffle": "^2.0.1",
- "@openzeppelin/contracts": "^4.4.1",
- "@types/chai": "^4.3.0",
- "@types/mocha": "^9.0.0",
- "@types/node": "^17.0.8",
- "@types/yargs": "^17.0.8",
- "chai": "^4.3.4",
- "ethereum-waffle": "^3.4.0",
- "ethers": "^5.5.3",
- "hardhat": "^2.8.2",
- "hardhat-deploy": "^0.9.24",
- "solc": "^0.8.11",
- "solidity-coverage": "^0.7.17",
- "ts-node": "^10.4.0",
- "typescript": "^4.5.4",
- "yargs": "^17.3.1"
- }
-}
diff --git a/assets/eip-4675/src/deploy/deploy_contracts.ts b/assets/eip-4675/src/deploy/deploy_contracts.ts
deleted file mode 100644
index 297da1a..0000000
--- a/assets/eip-4675/src/deploy/deploy_contracts.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { DeployFunction } from "hardhat-deploy/types";
-import { HardhatRuntimeEnvironment } from "hardhat/types";
-
-const deploy: DeployFunction = async function (
- hre: HardhatRuntimeEnvironment,
-) {
- const { deployments, hardhatArguments, getNamedAccounts } = hre;
- const { deployer } = await getNamedAccounts();
- const { deploy } = deployments;
-
- await deploy("MFNFT", {
- from: deployer,
- args: [],
- log: true,
- deterministicDeployment: true,
- });
-
- await deploy("NFT", {
- from: deployer,
- args: [],
- log: true,
- deterministicDeployment: true,
- });
-
-};
-
-deploy.tags = ['contracts', 'MFNFT', 'NFT']
-export default deploy;
diff --git a/assets/eip-4675/test/MFNFT.General.spec.ts b/assets/eip-4675/test/MFNFT.General.spec.ts
deleted file mode 100644
index 25ab613..0000000
--- a/assets/eip-4675/test/MFNFT.General.spec.ts
+++ /dev/null
@@ -1,349 +0,0 @@
-import { expect } from "chai";
-import hre, { deployments, ethers, waffle } from "hardhat";
-import { BigNumber } from "ethers";
-import { AddressZero } from "@ethersproject/constants";
-import { parseEther } from "@ethersproject/units";
-import { setMFNFTwithNFT, deployFTContract, getMFContract, getNFTContract, mintNFT } from "./utils/setup";
-import { transferFrom ,balanceOf, transfer, safeTransferFrom, addToken, approve, increaseAllowance, decreaseAllowance } from "./utils/execution";
-
-
-describe("Multi-Fractional Non-Fungible Token", async () => {
-
- const [admin, user1, user2, user3] = waffle.provider.getWallets();
-
- // Scalar variable that gets incremented when token is added to MFNFT
- const scalar_tokenId = 1;
-
- // token ID of the NFT
- const tokenId = 1;
-
- // total supply of FT derived from NFT
- const totalSupply = 1000;
-
- const setupTests = deployments.createFixture(async ({deployments}) => {
- await deployments.fixture();
- return {
- MFNFT: await getMFContract(),
- NFT: await getNFTContract(),
- }
- });
-
- describe("NFT Ownership", async () => {
- it("should revert if NFT ownership is not given before token addition", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await NFT.safeMint(user1.address, tokenId);
-
- await expect(
- addToken(MFNFT, NFT.address, tokenId, totalSupply)
- ).to.be.revertedWith("Verifier::verifyOwnership: NFT ownership verification failed")
- });
-
- it("should accept NFT after taking the ownership", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await mintNFT(NFT, MFNFT.address, tokenId);
-
- await addToken(MFNFT, NFT.address, tokenId, totalSupply)
- });
-
- it("should emit event for token addition", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await mintNFT(NFT, MFNFT.address, tokenId);
-
- await expect(
- addToken(MFNFT, NFT.address, tokenId, totalSupply)
- ).to.emit(MFNFT, "TokenAddition").withArgs(NFT.address, tokenId, 1, totalSupply)
- });
-
- it("should revert if given parentNFTContractAddress is zero", async () => {
- const { MFNFT } = await setupTests()
-
- await expect(
- addToken(MFNFT, AddressZero, tokenId, totalSupply)
- ).to.be.revertedWith("MFNFT::setParentNFT: Parent NFT Contract should not be zero")
- });
-
- it("should revert if given parentNFTContractAddress doesn't support ERC-721", async() => {
- const { MFNFT } = await setupTests();
- const FT = await deployFTContract(totalSupply);
-
- await expect (
- addToken(MFNFT, FT.address, tokenId, totalSupply)
- ).to.be.reverted
- });
-
- it("should revert if setParentNFT() is called twice for the same NFT", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply);
-
- await expect(
- addToken(MFNFT, NFT.address, tokenId, totalSupply)
- ).to.be.revertedWith("MFNFT::setParentNFT: Already owned(fractionalized) by this contract")
- });
-
- it("should return true if NFT is owned & registered by MNFTContract -> isRegistered()", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply);
-
- expect(await MFNFT.isRegistered(NFT.address, tokenId)).to.be.eq(true)
- });
-
- it("should check if parentTokenContractAddress is set right", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- expect(await MFNFT.parentToken(scalar_tokenId)).to.be.eq(NFT.address)
- });
-
- it("should check if parentTokenId is set right", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- expect(await MFNFT.parentTokenId(scalar_tokenId)).to.be.eq(tokenId)
- });
-
- it("should check if totalSupply complys with designated value", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- expect(await MFNFT.totalSupply(scalar_tokenId)).to.be.equal(totalSupply)
- });
- it("should check if _id is a scalar value that increases when token is added", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- const _id = await MFNFT.getTokenId(NFT.address, tokenId);
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId+1, totalSupply)
-
- expect(await MFNFT.getTokenId(NFT.address, tokenId+1)).to.be.equal(BigNumber.from(_id).add(1));
- });
-
- });
-
- describe("Admin", async () => {
-
- it("should check if admin can add new token", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await mintNFT(NFT, MFNFT.address, tokenId)
-
- await addToken(MFNFT, NFT.address, tokenId, totalSupply, {from: admin});
- });
-
- it("should revert if non-admin tries to add token", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await mintNFT(NFT, MFNFT.address, tokenId)
-
- await expect(
- addToken(MFNFT, NFT.address, tokenId, totalSupply, {from: user1})
- ).to.be.reverted
- });
-
- });
-
- describe("onERC721Received", async () => {
-
- it("should be able to accept ERC-721 token with safeTransferFrom()", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- await mintNFT(NFT, admin.address, tokenId)
-
- expect(
- await safeTransferFrom(NFT, admin.address, MFNFT.address, tokenId)
- ).to.emit(NFT, "Transfer").withArgs(admin.address, MFNFT.address, tokenId)
-
- expect(await NFT.ownerOf(tokenId)).to.be.equal(MFNFT.address)
- });
-
- it("should return expected value for onERC721Received()", async () => {
- const { MFNFT } = await setupTests()
- expect(await MFNFT.onERC721Received(admin.address, user1.address, tokenId, 0x0)).to.be.equal("0x150b7a02")
- });
-
- it("should return true if supportsInterface() receives supporting interface ID", async () => {
- const { MFNFT } = await setupTests()
- expect(await MFNFT.supportsInterface(0x01ffc9a7)).to.be.equal(true)
- })
-
- });
-
- describe("Transfer & Allowance", async () => {
-
- const approvedValue = 100;
-
- it("should transfer exact amount of share to recipient", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const transferAmount = 100;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- transfer(MFNFT, user1.address, scalar_tokenId, transferAmount)
- ).to.emit(MFNFT, "Transfer").withArgs(admin.address, user1.address, scalar_tokenId, transferAmount)
-
- expect(await balanceOf(MFNFT, user1.address, scalar_tokenId)).to.be.equal(transferAmount)
- });
-
- it("should not be able to transfer more than balance", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const transferAmount = 100;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- transfer(MFNFT, user1.address, scalar_tokenId, transferAmount + totalSupply)
- ).to.be.reverted
- });
-
- it("should revert when trying to transfer to address zero", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const transferAmount = 100;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- transfer(MFNFT, AddressZero, scalar_tokenId, transferAmount)
- ).to.be.reverted
- });
-
- it("should check if approved user can spend on behalf", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = user1;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue)
-
- await expect(
- transferFrom(MFNFT, admin.address, user2.address, scalar_tokenId, approvedValue, {from: spender})
- ).to.emit(MFNFT, "Transfer").withArgs(admin.address, user2.address, scalar_tokenId, approvedValue)
- });
-
- it("should revert if user tries to approve address zero", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = AddressZero;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender, scalar_tokenId, approvedValue)
- ).to.be.reverted
- });
-
- it("should revert if user tries to use over approved amount", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = user1;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue)
-
- await expect(
- transferFrom(MFNFT, admin.address, user2.address, scalar_tokenId, approvedValue+100, {from: spender})
- ).to.be.reverted
- });
-
- it("should be able to increase allowance", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = user1;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue)
-
- await expect(
- increaseAllowance(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue * 2)
-
- expect(await MFNFT.allowance(admin.address, spender.address, tokenId)).to.be.equal(approvedValue * 2)
- });
-
- it("should revert if user tries to increase allowance for address zero", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = AddressZero;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- increaseAllowance(MFNFT, AddressZero, scalar_tokenId, approvedValue * 2)
- ).to.be.reverted
-
- expect(await MFNFT.allowance(admin.address, AddressZero, tokenId)).to.be.equal(0)
- })
-
- it("should be able to decrease allowance", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = user1;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue)
-
- await expect(
- decreaseAllowance(MFNFT, spender.address, scalar_tokenId, approvedValue / 2)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue / 2)
-
- expect(await MFNFT.allowance(admin.address, spender.address, tokenId)).to.be.equal(approvedValue / 2)
- });
-
- it("should revert if user tries to decrease allowance more than approved", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = user1;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- approve(MFNFT, spender.address, scalar_tokenId, approvedValue)
- ).to.emit(MFNFT, "Approval").withArgs(admin.address, spender.address, scalar_tokenId, approvedValue)
-
- await expect(
- decreaseAllowance(MFNFT, spender.address, scalar_tokenId, approvedValue * 2)
- ).to.be.reverted
-
- expect(await MFNFT.allowance(admin.address, spender.address, tokenId)).to.be.equal(approvedValue)
- })
-
- it("should revert if user tries to decrease allowance for address zero", async () => {
- const { MFNFT, NFT } = await setupTests()
-
- const spender = AddressZero;
-
- await setMFNFTwithNFT(MFNFT, NFT, tokenId, totalSupply)
-
- await expect(
- decreaseAllowance(MFNFT, AddressZero, scalar_tokenId, approvedValue)
- ).to.be.reverted
-
- expect(await MFNFT.allowance(admin.address, AddressZero, tokenId)).to.be.equal(0)
- })
- });
-
-});
\ No newline at end of file
diff --git a/assets/eip-4675/test/utils/execution.ts b/assets/eip-4675/test/utils/execution.ts
deleted file mode 100644
index 2d2a848..0000000
--- a/assets/eip-4675/test/utils/execution.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Contract, Wallet, utils, BigNumber, BigNumberish, Signer, PopulatedTransaction } from "ethers"
-import { TypedDataSigner } from "@ethersproject/abstract-signer";
-import { AddressZero } from "@ethersproject/constants";
-
-interface transOption {
- from: string;
- gas: BigInteger
-}
-
-export const addToken = async (MFNFT: Contract, token: string, tokenId: BigNumberish, totalSupply: BigNumberish, options: any = {}): Promise => {
- const tAddr = token || AddressZero;
- const tId = tokenId || 1;
- const tSupply = totalSupply || 1000;
-
- options.from == null ? options = null : (MFNFT = MFNFT.connect(options.from), options = null);
-
- return MFNFT.setParentNFT(tAddr, tId, tSupply, options);
-}
-
-
-export const safeTransferFrom = async (NFT: Contract, from: string, to: string, tokenId: BigNumberish) => {
- return await NFT["safeTransferFrom(address,address,uint256)"](from, to, tokenId)
-}
-
-export const transfer = async (MFNFT: Contract, to: string, _id: BigNumberish, value: BigNumberish, options: any = {}) => {
- options.from == null ? options = null : (MFNFT = MFNFT.connect(options.from), options = null);
-
- return await MFNFT.transfer(to, _id, value)
-}
-
-export const transferFrom = async (MFNFT: Contract, from: string, to: string, _id: BigNumberish, value: BigNumberish, options: any = {}) => {
- options.from == null ? options = null : (MFNFT = MFNFT.connect(options.from), options = null);
-
- return await MFNFT.transferFrom(from, to, _id, value)
-}
-
-export const balanceOf = async (MFNFT: Contract, owner: string, _id: BigNumberish) => {
- return await MFNFT.balanceOf(owner, _id)
-}
-
-export const approve = async (MFNFT: Contract, spender: string, tokenId: BigNumberish, value: BigNumberish) => {
- return await MFNFT.approve(spender, tokenId, value)
-}
-
-export const increaseAllowance = async (MFNFT: Contract, spender: string, tokenId: BigNumberish, value: BigNumberish) => {
- return await MFNFT.increaseAllowance(spender, tokenId, value)
-}
-
-export const decreaseAllowance = async (MFNFT: Contract, spender: string, tokenId: BigNumberish, value: BigNumberish) => {
- return await MFNFT.decreaseAllowance(spender, tokenId, value)
-}
\ No newline at end of file
diff --git a/assets/eip-4675/test/utils/setup.ts b/assets/eip-4675/test/utils/setup.ts
deleted file mode 100644
index 957e517..0000000
--- a/assets/eip-4675/test/utils/setup.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-import hre, { deployments } from "hardhat"
-import { Contract, Wallet, utils, BigNumber, BigNumberish, Signer, PopulatedTransaction } from "ethers"
-import { AddressZero } from "@ethersproject/constants";
-import { formatFixed, parseFixed } from "@ethersproject/bignumber";
-import { addToken } from "./execution";
-import { Address } from "cluster";
-
-const MFContract = () => {
- return "MFNFT";
-}
-
-export const getMFContract = async () => {
- // const MFDeployment = await deployments.get(MFContract());
- const MF = await hre.ethers.getContractFactory(MFContract());
- // return MF.attach(MFDeployment.address);
- return MF.deploy();
-}
-
-export const getNFTContract = async () => {
- // const NFTDeployment = await deployments.get("NFT");
- const NFT = await hre.ethers.getContractFactory("NFT");
- // return NFT.attach(NFTDeployment.address);
- return NFT.deploy();
-}
-
-export const deployFTContract = async (totalSupply: BigNumberish) => {
- const tSupply = totalSupply || 1000;
- const FT = await hre.ethers.getContractFactory("FT");
- return FT.deploy(tSupply);
-}
-
-export const mintNFT = async (token: Contract, tokenOwner: string, tokenId:BigNumberish) => {
- const NFT = token;
- const tId = tokenId || 1;
- const tOwner = tokenOwner || AddressZero;
- return await NFT.safeMint(tOwner, tId);
-}
-
-export const ownerOf = async (token: Contract, tokenId:BigNumberish) => {
- const NFT = token;
- const tId = tokenId || 1;
- return await NFT.ownerOf(tId);
-}
-
-export const setMFNFTwithNFT = async (MFNFT: Contract, NFT: Contract, tokenId: BigNumberish, totalSupply: BigNumberish) => {
- await mintNFT(NFT, MFNFT.address, tokenId);
- await addToken(MFNFT, NFT.address, tokenId, totalSupply);
-}
-
diff --git a/assets/eip-4675/tsconfig.json b/assets/eip-4675/tsconfig.json
deleted file mode 100644
index 8125850..0000000
--- a/assets/eip-4675/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "module": "commonjs",
- "strict": true,
- "esModuleInterop": true,
- "outDir": "dist"
- },
- "include": ["./scripts", "./test"],
- "files": ["./hardhat.config.ts"]
-}
\ No newline at end of file
diff --git a/assets/eip-4824/daostar_context.jsonld b/assets/eip-4824/daostar_context.jsonld
deleted file mode 100644
index d595fa6..0000000
--- a/assets/eip-4824/daostar_context.jsonld
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "@context": {
- "@vocab": "http://daostar.org/schemas/",
- "type": "@type"
- }
-}
diff --git a/assets/eip-4824/daostar_ontology.ttl b/assets/eip-4824/daostar_ontology.ttl
deleted file mode 100644
index 70b9116..0000000
--- a/assets/eip-4824/daostar_ontology.ttl
+++ /dev/null
@@ -1,262 +0,0 @@
-@prefix : .
-@prefix owl: .
-@prefix rdf: .
-@prefix xml: .
-@prefix xsd: .
-@prefix rdfs: .
-@base .
-
- rdf:type owl:Ontology .
-
-#################################################################
-# Object Properties
-#################################################################
-
-### http:/daostar.org/schemas/activities
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:label "activities"@en .
-
-
-### http:/daostar.org/schemas/calls
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:comment "list of calls, which a proposal proposes"^^xsd:string ;
- rdfs:label "calls"@en .
-
-
-### http:/daostar.org/schemas/from
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:label "from"@en .
-
-
-### http:/daostar.org/schemas/member
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ,
- ,
- .
-
-
-### http:/daostar.org/schemas/members
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ,
- ,
- ;
- rdfs:label "members"@en .
-
-
-### http:/daostar.org/schemas/proposal
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:comment "proposal, which an activity relates to"^^xsd:string ;
- rdfs:label "proposal"^^xsd:string .
-
-
-### http:/daostar.org/schemas/proposals
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:comment "list of the DAO's proposals"^^xsd:string ;
- rdfs:label "proposals"@en .
-
-
-### http:/daostar.org/schemas/to
- rdf:type owl:ObjectProperty ;
- rdfs:subPropertyOf owl:topObjectProperty ;
- rdfs:domain ;
- rdfs:range ;
- rdfs:label "to"@en .
-
-
-#################################################################
-# Data properties
-#################################################################
-
-### http:/daostar.org/schemas/activityLogURI
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:anyURI ;
- rdfs:label "activityLogURI"@en .
-
-
-### http:/daostar.org/schemas/address
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ,
- ;
- rdfs:range xsd:string ;
- rdfs:label "address"@en .
-
-
-### http:/daostar.org/schemas/callData
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:label "callData"@en .
-
-
-### http:/daostar.org/schemas/contentURI
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:anyURI ;
- rdfs:comment "URI pointing to the context of a proposal"^^xsd:string ;
- rdfs:label "contentURI"@en .
-
-
-### http:/daostar.org/schemas/data
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:comment "call data"^^xsd:string ;
- rdfs:label "data"@en .
-
-
-### http:/daostar.org/schemas/description
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:comment "a description of the DAO"^^xsd:string ;
- rdfs:label "description"@en .
-
-
-### http:/daostar.org/schemas/governanceURI
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:anyURI ;
- rdfs:label "governanceURI"@en .
-
-
-### http:/daostar.org/schemas/id
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ,
- ;
- rdfs:range xsd:string ;
- rdfs:comment "proposal ID"^^xsd:string ;
- rdfs:label "id"@en .
-
-
-### http:/daostar.org/schemas/membersURI
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:anyURI ;
- rdfs:label "membersURI"^^xsd:string .
-
-
-### http:/daostar.org/schemas/name
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ,
- ;
- rdfs:range xsd:string ;
- rdfs:comment "name of the DAO"^^xsd:string ;
- rdfs:label "name"@en .
-
-
-### http:/daostar.org/schemas/operation
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:label "call or delegate call"^^xsd:string ,
- "operation"@en .
-
-
-### http:/daostar.org/schemas/proposalsURI
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:anyURI ;
- rdfs:label "proposalsURI"@en .
-
-
-### http:/daostar.org/schemas/status
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:comment "status of a proposal"^^xsd:string ;
- rdfs:label "status"@en .
-
-
-### http:/daostar.org/schemas/value
- rdf:type owl:DatatypeProperty ;
- rdfs:subPropertyOf owl:topDataProperty ;
- rdfs:domain ;
- rdfs:range xsd:string ;
- rdfs:comment "call value"^^xsd:string ;
- rdfs:label "value"^^xsd:string .
-
-
-#################################################################
-# Classes
-#################################################################
-
-### http:/daostar.org/schemas/BlockchainAddress
- rdf:type owl:Class ;
- rdfs:comment "a blockchain address"^^xsd:string ;
- rdfs:label "BlockchainAddress"@en .
-
-
-### http:/daostar.org/schemas/CallDataEVM
- rdf:type owl:Class ;
- rdfs:comment "information regarding an EVM call"^^xsd:string ;
- rdfs:label "CallDataEVM"@en .
-
-
-### http:/daostar.org/schemas/DAO
- rdf:type owl:Class ;
- rdfs:label "DAO"@en .
-
-
-### http:/daostar.org/schemas/EthereumAddress
- rdf:type owl:Class ;
- rdfs:subClassOf ;
- rdfs:label "EthereumAddress"@en .
-
-
-### http:/daostar.org/schemas/Proposal
- rdf:type owl:Class ;
- rdfs:label "Proposal"@en .
-
-
-### http:/daostar.org/schemas/activity
- rdf:type owl:Class ;
- rdfs:comment "describes an interaction between a DAO member and a DAO proposal"^^xsd:string ;
- rdfs:label "activity"@en .
-
-
-### http:/daostar.org/schemas/member
- rdf:type owl:Class .
-
-
-#################################################################
-# Annotations
-#################################################################
-
- rdfs:comment "DAO member"^^xsd:string ;
- rdfs:label "member"@en .
-
-
-### Generated by the OWL API (version 4.5.13) https://github.com/owlcs/owlapi
diff --git a/assets/eip-4881/deposit_snapshot.py b/assets/eip-4881/deposit_snapshot.py
deleted file mode 100755
index 7c33275..0000000
--- a/assets/eip-4881/deposit_snapshot.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/env python3
-from __future__ import annotations
-from typing import List, Optional, Tuple
-from dataclasses import dataclass
-from abc import ABC,abstractmethod
-from eip_4881 import DEPOSIT_CONTRACT_DEPTH,Hash32,sha256,to_le_bytes,zerohashes
-
-@dataclass
-class DepositTreeSnapshot:
- finalized: List[Hash32, DEPOSIT_CONTRACT_DEPTH]
- deposit_root: Hash32
- deposit_count: uint64
- execution_block_hash: Hash32
- execution_block_height: uint64
-
- def calculate_root(self) -> Hash32:
- size = self.deposit_count
- index = len(self.finalized)
- root = zerohashes[0]
- for level in range(0, DEPOSIT_CONTRACT_DEPTH):
- if (size & 1) == 1:
- index -= 1
- root = sha256(self.finalized[index] + root)
- else:
- root = sha256(root + zerohashes[level])
- size >>= 1
- return sha256(root + to_le_bytes(self.deposit_count))
- def from_tree_parts(finalized: List[Hash32],
- deposit_count: uint64,
- execution_block: Tuple[Hash32, uint64]) -> DepositTreeSnapshot:
- snapshot = DepositTreeSnapshot(
- finalized, zerohashes[0], deposit_count, execution_block[0], execution_block[1])
- snapshot.deposit_root = snapshot.calculate_root()
- return snapshot
-
-@dataclass
-class DepositTree:
- tree: MerkleTree
- mix_in_length: uint
- finalized_execution_block: Optional[Tuple[Hash32, uint64]]
- def new() -> DepositTree:
- merkle = MerkleTree.create([], DEPOSIT_CONTRACT_DEPTH)
- return DepositTree(merkle, 0, None)
- def get_snapshot(self) -> DepositTreeSnapshot:
- assert(self.finalized_execution_block is not None)
- finalized = []
- deposit_count = self.tree.get_finalized(finalized)
- return DepositTreeSnapshot.from_tree_parts(
- finalized, deposit_count, self.finalized_execution_block)
- def from_snapshot(snapshot: DepositTreeSnapshot) -> DepositTree:
- # decent validation check on the snapshot
- assert(snapshot.deposit_root == snapshot.calculate_root())
- finalized_execution_block = (snapshot.execution_block_hash, snapshot.execution_block_height)
- tree = MerkleTree.from_snapshot_parts(
- snapshot.finalized, snapshot.deposit_count, DEPOSIT_CONTRACT_DEPTH)
- return DepositTree(tree, snapshot.deposit_count, finalized_execution_block)
- def finalize(self, eth1_data: Eth1Data, execution_block_height: uint64):
- self.finalized_execution_block = (eth1_data.block_hash, execution_block_height)
- self.tree.finalize(eth1_data.deposit_count, DEPOSIT_CONTRACT_DEPTH)
- def get_proof(self, index: uint) -> Tuple[Hash32, List[Hash32]]:
- assert(self.mix_in_length > 0)
- # ensure index > finalized deposit index
- assert(index > self.tree.get_finalized([]) - 1)
- leaf, proof = self.tree.generate_proof(index, DEPOSIT_CONTRACT_DEPTH)
- proof.append(to_le_bytes(self.mix_in_length))
- return leaf, proof
- def get_root(self) -> Hash32:
- return sha256(self.tree.get_root() + to_le_bytes(self.mix_in_length))
- def push_leaf(self, leaf: Hash32):
- self.mix_in_length += 1
- self.tree = self.tree.push_leaf(leaf, DEPOSIT_CONTRACT_DEPTH)
-
-class MerkleTree():
- @abstractmethod
- def get_root(self) -> Hash32:
- pass
- @abstractmethod
- def is_full(self) -> bool:
- pass
- @abstractmethod
- def push_leaf(self, leaf: Hash32, level: uint) -> MerkleTree:
- pass
- @abstractmethod
- def finalize(self, deposits_to_finalize: uint, level: uint) -> MerkleTree:
- pass
- @abstractmethod
- def get_finalized(self, result: List[Hash32]) -> uint:
- # returns the number of finalized deposits in the tree
- # while populating result with the finalized hashes
- pass
- def create(leaves: List[Hash32], depth: uint) -> MerkleTree:
- if not(leaves):
- return Zero(depth)
- if not(depth):
- return Leaf(leaves[0])
- split = min(2**(depth - 1), len(leaves))
- left = MerkleTree.create(leaves[0:split], depth - 1)
- right = MerkleTree.create(leaves[split:], depth - 1)
- return Node(left, right)
- def from_snapshot_parts(finalized: List[Hash32], deposits: uint, level: uint) -> MerkleTree:
- if not(finalized) or not(deposits):
- # empty tree
- return Zero(level)
- if deposits == 2**level:
- return Finalized(deposits, finalized[0])
- left_subtree = 2**(level - 1)
- if deposits <= left_subtree:
- left = MerkleTree.from_snapshot_parts(finalized, deposits, level - 1)
- right = Zero(level - 1)
- return Node(left, right)
- else:
- left = Finalized(left_subtree, finalized[0])
- right = MerkleTree.from_snapshot_parts(finalized[1:], deposits - left_subtree, level - 1)
- return Node(left, right)
- def generate_proof(self, index: uint, depth: uint) -> Tuple[Hash32, List[Hash32]]:
- proof = []
- node = self
- while depth > 0:
- ith_bit = (index >> (depth - 1)) & 0x1
- if ith_bit == 1:
- proof.append(node.left.get_root())
- node = node.right
- else:
- proof.append(node.right.get_root())
- node = node.left
- depth -= 1
- proof.reverse()
- return node.get_root(), proof
-
-@dataclass
-class Finalized(MerkleTree):
- deposit_count: uint
- hash: Hash32
- def get_root(self) -> Hash32:
- return self.hash
- def is_full(self) -> bool:
- return True
- def finalize(self, deposits_to_finalize: uint, level: uint) -> MerkleTree:
- return self
- def get_finalized(self, result: List[Hash32]) -> uint:
- result.append(self.hash)
- return self.deposit_count
-
-@dataclass
-class Leaf(MerkleTree):
- hash: Hash32
- def get_root(self) -> Hash32:
- return self.hash
- def is_full(self) -> bool:
- return True
- def finalize(self, deposits_to_finalize: uint, level: uint) -> MerkleTree:
- return Finalized(1, self.hash)
- def get_finalized(self, result: List[Hash32]) -> uint:
- return 0
-
-@dataclass
-class Node(MerkleTree):
- left: MerkleTree
- right: MerkleTree
- def get_root(self) -> Hash32:
- return sha256(self.left.get_root() + self.right.get_root())
- def is_full(self) -> bool:
- return self.right.is_full()
- def push_leaf(self, leaf: Hash32, level: uint) -> MerkleTree:
- if not(self.left.is_full()):
- self.left = self.left.push_leaf(leaf, level - 1)
- else:
- self.right = self.right.push_leaf(leaf, level - 1)
- return self
- def finalize(self, deposits_to_finalize: uint, level: uint) -> MerkleTree:
- deposits = 2**level
- if deposits <= deposits_to_finalize:
- return Finalized(deposits, self.get_root())
- self.left = self.left.finalize(deposits_to_finalize, level - 1)
- if deposits_to_finalize > deposits / 2:
- remaining = deposits_to_finalize - deposits / 2
- self.right = self.right.finalize(remaining, level - 1)
- return self
- def get_finalized(self, result: List[Hash32]) -> uint:
- return self.left.get_finalized(result) + self.right.get_finalized(result)
-
-@dataclass
-class Zero(MerkleTree):
- n: uint64
- def get_root(self) -> Hash32:
- if self.n == DEPOSIT_CONTRACT_DEPTH:
- # Handle the entirely empty tree case. This is included for
- # consistency/clarity as the zerohashes array is typically
- # only defined from 0 to DEPOSIT_CONTRACT_DEPTH - 1.
- return sha256(zerohashes[self.n - 1] + zerohashes[self.n - 1])
- return zerohashes[self.n]
- def is_full(self) -> bool:
- return False
- def push_leaf(self, leaf: Hash32, level: uint) -> MerkleTree:
- return MerkleTree.create([leaf], level)
- def get_finalized(self, result: List[Hash32]) -> uint:
- return 0
-
diff --git a/assets/eip-4881/deposit_tree_evolution.svg b/assets/eip-4881/deposit_tree_evolution.svg
deleted file mode 100644
index 24e2598..0000000
--- a/assets/eip-4881/deposit_tree_evolution.svg
+++ /dev/null
@@ -1,5209 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/eip-4881/eip_4881.py b/assets/eip-4881/eip_4881.py
deleted file mode 100755
index fbb74c5..0000000
--- a/assets/eip-4881/eip_4881.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-from dataclasses import dataclass
-from hashlib import sha256 as SHA256
-
-DEPOSIT_CONTRACT_DEPTH = 32
-Hash32 = bytes
-Root = bytes
-uint64 = int
-BLSPubkey = bytes
-Bytes32 = bytes
-Gwei = uint64
-BLSSignature = bytes
-
-@dataclass
-class DepositData:
- pubkey: BLSPubkey
- withdrawal_credentials: Bytes32
- amount: Gwei
- signature: BLSSignature
-
-@dataclass
-class Eth1Data:
- deposit_root: Root
- deposit_count: uint64
- block_hash: Hash32
-
-def sha256(x) -> Hash32:
- return SHA256(x).digest()
-def to_le_bytes(i: int) -> bytes:
- return i.to_bytes(32, byteorder='little')
-
-zerohashes = [b'\x00' * 32]
-for i in range(1, DEPOSIT_CONTRACT_DEPTH):
- zerohashes.append(sha256(zerohashes[i-1] + zerohashes[i-1]))
-
diff --git a/assets/eip-4881/test_cases.yaml b/assets/eip-4881/test_cases.yaml
deleted file mode 100644
index ccb4569..0000000
--- a/assets/eip-4881/test_cases.yaml
+++ /dev/null
@@ -1,11011 +0,0 @@
----
-- deposit_data:
- pubkey: "0xa99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97af5a5e14a033c35ec6489c585df8975026af431b2c5e9e3e6fd66089575bdffaf41c0a196d9b2ef822226c49d16214146f8a79b6ffa400109cd6c63c73afc7649d25533a3619547bc333b0cb3f303432fcd4951333b656d64d7b46a7ba764f"
- deposit_data_root: "0x7af7da533b0dc64b690cb0604f5a81e40ed83796dd14037ea3a55383b8f0976a"
- eth1_data:
- deposit_root: "0x253f73460b66ba0b490a8f17029566b03c0690a584e262acc2be97c969bc65a6"
- deposit_count: "1"
- block_hash: "0xab6f0411b911f0d66539663dc6b41ed58bb4870cd3ae879e25c7bee8cd6d6f22"
- block_height: 2
- snapshot:
- finalized:
- - "0x7af7da533b0dc64b690cb0604f5a81e40ed83796dd14037ea3a55383b8f0976a"
- deposit_root: "0x253f73460b66ba0b490a8f17029566b03c0690a584e262acc2be97c969bc65a6"
- deposit_count: 1
- execution_block_hash: "0xab6f0411b911f0d66539663dc6b41ed58bb4870cd3ae879e25c7bee8cd6d6f22"
- execution_block_height: 2
-- deposit_data:
- pubkey: "0xb89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb24d74bd23b52c41567305b6aecdc73dd53aea59fa997c0d6205531ce70cc32282dbf9963dde89297522fdc2c541eb0909472145805953a2298aa56160784c23b3905ed0ec17c4775b61cecb922a0d0e5241521387fc38184afe735c2ce399ad"
- deposit_data_root: "0xb7dfec33825ba4dd8f6f8c2498c7202f07cbcf995a6de4b0abc71f1b1c46b2b2"
- eth1_data:
- deposit_root: "0x072080f22bf66504d6aa2b978c581e34637912ac191442af4f090dc5773d8936"
- deposit_count: "2"
- block_hash: "0x4e41a313cb3461e3154e76f87ec1bda35a48876529eaf3b99e335f43280c8d66"
- block_height: 3
- snapshot:
- finalized:
- - "0xb6a04fb079b0153e6e555fd79bb89187c9386b2230f4020bd81558feca702982"
- deposit_root: "0x072080f22bf66504d6aa2b978c581e34637912ac191442af4f090dc5773d8936"
- deposit_count: 2
- execution_block_hash: "0x4e41a313cb3461e3154e76f87ec1bda35a48876529eaf3b99e335f43280c8d66"
- execution_block_height: 3
-- deposit_data:
- pubkey: "0xa3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae64ef1d479919aa5cbd146559f366877298757843112239646d75658dc89d066e401be202a3198ffb7261b393b7f8c01901e36e3bfa17f7ae2620d5e44750fd983e3b97d9c44248689f81d6a0508501f2dadfbbc1c7ddcec307a4d6da42c59f"
- deposit_data_root: "0x7b14766c0e7eddb146fc2a5bfd91e6d358d71995d2dc3c60d0c326607e39f7f2"
- eth1_data:
- deposit_root: "0x5e493befc0eb8dd0162eb48e5c3430882eefae51cb3fa757f11853b28387acdb"
- deposit_count: "3"
- block_hash: "0xb06534c2390ed7d7ec1d2630c6e8a340570a1a63df72c5cb81bb6ad65dce0692"
- block_height: 4
- snapshot:
- finalized:
- - "0xb6a04fb079b0153e6e555fd79bb89187c9386b2230f4020bd81558feca702982"
- - "0x7b14766c0e7eddb146fc2a5bfd91e6d358d71995d2dc3c60d0c326607e39f7f2"
- deposit_root: "0x5e493befc0eb8dd0162eb48e5c3430882eefae51cb3fa757f11853b28387acdb"
- deposit_count: 3
- execution_block_hash: "0xb06534c2390ed7d7ec1d2630c6e8a340570a1a63df72c5cb81bb6ad65dce0692"
- execution_block_height: 4
-- deposit_data:
- pubkey: "0x88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa0b938a2e4cd395ca6f24b410ac60af8af115f93d869839d76d8ef5aaeee52350636d72ef264c25b20442a55b24cc82d09a21d416a3e957bb0d35baf53efb18ac274e2e744644d42fa8f17beb7b2b6baae5342fa06eb394da73dd45b1643f3e2"
- deposit_data_root: "0x4760922c3a4ed6d321fc97355c4e8f7b7aa9e9771cb258095e52702c40170337"
- eth1_data:
- deposit_root: "0xe7d648159438c55bd12bbfea58ae16b9f9692d3fb05b0eac1729c67687dabe11"
- deposit_count: "4"
- block_hash: "0x63289eb1794f3ccd7536ce19023625e04777f84bd147c72b70eafcc6131b2f03"
- block_height: 5
- snapshot:
- finalized:
- - "0x33ac367f73d5318defd4d79d1b16c69046401691739f1aac0753a84e0ea28d22"
- deposit_root: "0xe7d648159438c55bd12bbfea58ae16b9f9692d3fb05b0eac1729c67687dabe11"
- deposit_count: 4
- execution_block_hash: "0x63289eb1794f3ccd7536ce19023625e04777f84bd147c72b70eafcc6131b2f03"
- execution_block_height: 5
-- deposit_data:
- pubkey: "0x81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaee3bec0f7786baae3a143131ea26d8ef62a8e17f7fade7355e42fb40a2717355d180c895f4de195523d3002d33ed60d10ba3b4285e8e712eb1612298051bdda70650966db509a104f374f45b16dfe06b21e6c385f0ff7d9c275b69dd193eef3"
- deposit_data_root: "0xfba947b41bd711feba3294ddaf1a6a87b888472f08a6c06d48afa702881409cd"
- eth1_data:
- deposit_root: "0x1004652bf7077a95c5a7ad7f2abd71565b750dcfbb1748d9489f3cae54c961fb"
- deposit_count: "5"
- block_hash: "0xc6aab9995fee61fde7d100a4f3aea2e8c9091501179943781dd50049ba57723d"
- block_height: 6
- snapshot:
- finalized:
- - "0x33ac367f73d5318defd4d79d1b16c69046401691739f1aac0753a84e0ea28d22"
- - "0xfba947b41bd711feba3294ddaf1a6a87b888472f08a6c06d48afa702881409cd"
- deposit_root: "0x1004652bf7077a95c5a7ad7f2abd71565b750dcfbb1748d9489f3cae54c961fb"
- deposit_count: 5
- execution_block_hash: "0xc6aab9995fee61fde7d100a4f3aea2e8c9091501179943781dd50049ba57723d"
- execution_block_height: 6
-- deposit_data:
- pubkey: "0xab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa28c8ad9d6cece980f888fe350f28ca3a4163f67f84c46053290e91134598fcba9fa7f4797c6cecdd435f44f65870e950a3b14c1d2ae162ee7958be3104e0489dd1a2f92482e30541abbd660e95d6476ad1373c19a64281b4057efdf36679758"
- deposit_data_root: "0x277ce49d97fb149180999892fe334e8d4701430aa5e76b7539e9593edc74209d"
- eth1_data:
- deposit_root: "0x82219812154553443de49dc85542aad6702f3b7ddb12e12be143a83028a5254a"
- deposit_count: "6"
- block_hash: "0x9ea53b7ec3ca5c5668b6b100e4463b93bd76d888ca846fbbb08d8db9596a3bf3"
- block_height: 7
- snapshot:
- finalized:
- - "0x33ac367f73d5318defd4d79d1b16c69046401691739f1aac0753a84e0ea28d22"
- - "0x9c8cf1935559cf32ca28a3677d41dea8cbc511ba16d99d7b5ab5610ee22c9eb2"
- deposit_root: "0x82219812154553443de49dc85542aad6702f3b7ddb12e12be143a83028a5254a"
- deposit_count: 6
- execution_block_hash: "0x9ea53b7ec3ca5c5668b6b100e4463b93bd76d888ca846fbbb08d8db9596a3bf3"
- execution_block_height: 7
-- deposit_data:
- pubkey: "0x9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91d3bbe5ec01f47565f1b62e93b78fe084216a875154a6cb21cc521be15a548d3e28446c82fcf7214f484433abb2a0bb07c951cd3af2e2849e9e2456b4e53afbc122016e9f87a76269d307e02c495ef189a9bb48bf8a042a3a06676f82689000"
- deposit_data_root: "0x7d552eeb22d6a4fa593784ebc22fbd2c400d922dc806def9d8899c06b301125d"
- eth1_data:
- deposit_root: "0x2e079bcdc6905fcdf19041d355d17dd5a74f0749ac2cb178e81b648aafef3908"
- deposit_count: "7"
- block_hash: "0x8b5a2c44e11f46011c61e43cd768efbfc5610381caea1968397dc3ef50e83d9f"
- block_height: 8
- snapshot:
- finalized:
- - "0x33ac367f73d5318defd4d79d1b16c69046401691739f1aac0753a84e0ea28d22"
- - "0x9c8cf1935559cf32ca28a3677d41dea8cbc511ba16d99d7b5ab5610ee22c9eb2"
- - "0x7d552eeb22d6a4fa593784ebc22fbd2c400d922dc806def9d8899c06b301125d"
- deposit_root: "0x2e079bcdc6905fcdf19041d355d17dd5a74f0749ac2cb178e81b648aafef3908"
- deposit_count: 7
- execution_block_hash: "0x8b5a2c44e11f46011c61e43cd768efbfc5610381caea1968397dc3ef50e83d9f"
- execution_block_height: 8
-- deposit_data:
- pubkey: "0xa8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3f76d7804668895192dd3fae3ccf101aa077da7c2678aefb8e92764e3bb0a32ef4592a62d8083aa0ca91f4cdefc745a0187fabd0f48fffc3213ccb9fca432a5c9c190d0d30f7c32f45e0ec4578eafad9a3f40e9a927e6cc1e0b5547cb54c0dc"
- deposit_data_root: "0xad041a1626deaccb4f11900595eaaab0f5b35d3ad16c3f1e5155181421348c11"
- eth1_data:
- deposit_root: "0xdd303f6f720a21ca45aebdaaf06a051ef6ad0b86b786b8a671e67652f5b32846"
- deposit_count: "8"
- block_hash: "0xe736c69176be57cfecb91f6e5c56fd5ed0b1537a9cac8229e30eb1b86abac543"
- block_height: 9
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- deposit_root: "0xdd303f6f720a21ca45aebdaaf06a051ef6ad0b86b786b8a671e67652f5b32846"
- deposit_count: 8
- execution_block_hash: "0xe736c69176be57cfecb91f6e5c56fd5ed0b1537a9cac8229e30eb1b86abac543"
- execution_block_height: 9
-- deposit_data:
- pubkey: "0xa6d310dbbfab9a22450f59993f87a4ce5db6223f3b5f1f30d2c4ec718922d400e0b3c7741de8e59960f72411a0ee10a7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8be64cfe0334b009be7c2d7c601e561976c201551d27b79747fc11fcbee6b22b9bd87552f8d492ec383e8bec11045b8f0c91ac28995f5c4b1c56b4953bb7fa0144d32f2464e8990342c907a42221b2a5ff69b8301259fa87e0bcb5f4bdaa16de"
- deposit_data_root: "0x9fb936887340fdde0663bc9811bc80c8939d4f1fda005a3d8d4d1e5803c65d43"
- eth1_data:
- deposit_root: "0x03d7883c2e63951bb4df714a7a0ceb389441999562dfa1fa98818b5791cf4c16"
- deposit_count: "9"
- block_hash: "0x597ffaa8cce4435d23a8f9dc28500422ce3d0e68fd5be5989eb032fb276b8293"
- block_height: 10
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x9fb936887340fdde0663bc9811bc80c8939d4f1fda005a3d8d4d1e5803c65d43"
- deposit_root: "0x03d7883c2e63951bb4df714a7a0ceb389441999562dfa1fa98818b5791cf4c16"
- deposit_count: 9
- execution_block_hash: "0x597ffaa8cce4435d23a8f9dc28500422ce3d0e68fd5be5989eb032fb276b8293"
- execution_block_height: 10
-- deposit_data:
- pubkey: "0x9893413c00283a3f9ed9fd9845dda1cea38228d22567f9541dccc357e54a2d6a6e204103c92564cbc05f4905ac7c493a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x938c03a718bf6e456ec84d88a118939dec03dbdce3697b8ef0f52208835d3221b4a103997264e064b13ecb05bb4b8ef910f4f3446a3b1524549f53ed9e744c41c3bf0350c4bc9b29f2b223ab1a91abe1a153d80bda8cee1b4f2f8fe3e6409ff9"
- deposit_data_root: "0xb6855e0bdbf1972d7a4571e6259cd589fe1baa3fa7ef569b9554c8e293b553dd"
- eth1_data:
- deposit_root: "0x2bba0e22d698d0e3cfa8374379f6c1a031a2aa0554cff8fa752936bc2ab8cdfd"
- deposit_count: "10"
- block_hash: "0x2e783a4e0b676caf552408ed8faf35f9e3e68dd2d82f71538ecf5c067dab6107"
- block_height: 11
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x30a5058eb6db4b120d6c07b995376d1e1f013ccd24d52b1327d7528d2e50c970"
- deposit_root: "0x2bba0e22d698d0e3cfa8374379f6c1a031a2aa0554cff8fa752936bc2ab8cdfd"
- deposit_count: 10
- execution_block_hash: "0x2e783a4e0b676caf552408ed8faf35f9e3e68dd2d82f71538ecf5c067dab6107"
- execution_block_height: 11
-- deposit_data:
- pubkey: "0x876dd4705157eb66dc71bc2e07fb151ea53e1a62a0bb980a7ce72d15f58944a8a3752d754f52f4a60dbfc7b18169f268"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7bffc1c83d9294af5df83f9889bd9c8d60f020b87d2a2a4235e8b0385b11b42a61432817210f7ca05cdfa074989fb57181a5a63b899402822c9f5dd33d1f199f441886cd6b753ff9fa87b72146f05c51b20d39c31a666dfdd00ea961accf1a3"
- deposit_data_root: "0xc27c2db393fa0a74669bb5d2148ead286bec2fffc8c993e24a1c633221b0a91a"
- eth1_data:
- deposit_root: "0x697b75797e3f93acb334632bcd4af10979b12e10fa3f1b2dd7813bc31963f2aa"
- deposit_count: "11"
- block_hash: "0x3b9b8b3100433523f9b04ad853d9772795403b9610f58c71746f18280e7f1c97"
- block_height: 12
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x30a5058eb6db4b120d6c07b995376d1e1f013ccd24d52b1327d7528d2e50c970"
- - "0xc27c2db393fa0a74669bb5d2148ead286bec2fffc8c993e24a1c633221b0a91a"
- deposit_root: "0x697b75797e3f93acb334632bcd4af10979b12e10fa3f1b2dd7813bc31963f2aa"
- deposit_count: 11
- execution_block_hash: "0x3b9b8b3100433523f9b04ad853d9772795403b9610f58c71746f18280e7f1c97"
- execution_block_height: 12
-- deposit_data:
- pubkey: "0xaec922bd7a9b7b1dc21993133b586b0c3041c1e2e04b513e862227b9d7aecaf9444222f7e78282a449622ffc6278915d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8f2128ebe0cfc2ca5b6df5071b2960717a0b068dc4694d697af2589307ff0c4502e9faa5f7c5093ab8c214bce4f820db12336ea8853704fa050442ed6b513d68c6c18a33734d558658662c39174bb69be31b78d87eea4602292cda97fc2651ea"
- deposit_data_root: "0x9ce8e449715c5c2b4f0d7da4de574f18ce429f44c4b1f648e23b8ece0c24bcc8"
- eth1_data:
- deposit_root: "0xa990ca5f9f41f0b305051de710d8b2fe78f63e369f408977a2cf19dcee718b60"
- deposit_count: "12"
- block_hash: "0xcec38f21aef8ce25842b3db7e9f5cb708a1aa9b3bad17c04f31ef963657f81b5"
- block_height: 13
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x660335330368071f958f6fa763caa16650c7e3051733f84ce6bfa410f2052bf9"
- deposit_root: "0xa990ca5f9f41f0b305051de710d8b2fe78f63e369f408977a2cf19dcee718b60"
- deposit_count: 12
- execution_block_hash: "0xcec38f21aef8ce25842b3db7e9f5cb708a1aa9b3bad17c04f31ef963657f81b5"
- execution_block_height: 13
-- deposit_data:
- pubkey: "0x9314c6de0386635e2799af798884c2ea09c63b9f079e572acc00b06a7faccce501ea4dfc0b1a23b8603680a5e3481327"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac36c7e15cd45f9f7c0e2672286513e03de301aff537460351bc1ccfa777139bfce29c6f441df8d7cbee4fdaea159cda1309a563ef28e9630ce1d022f8378046978fbb55e2f67dc708aa923e86bbfbd2487bf9f7b537a23ee1fd6c30043b6270"
- deposit_data_root: "0x079946bfcb7488e966144acd500b247b685896812cdb13c138742dfaad33ce88"
- eth1_data:
- deposit_root: "0x96906b941533a885ac57be9f765f90b0c880174286913c515552167b0154a116"
- deposit_count: "13"
- block_hash: "0xe9ebca52836019409c578724469684df7ddbf2a3f1a106c66e3af1dae3b24ad8"
- block_height: 14
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x660335330368071f958f6fa763caa16650c7e3051733f84ce6bfa410f2052bf9"
- - "0x079946bfcb7488e966144acd500b247b685896812cdb13c138742dfaad33ce88"
- deposit_root: "0x96906b941533a885ac57be9f765f90b0c880174286913c515552167b0154a116"
- deposit_count: 13
- execution_block_hash: "0xe9ebca52836019409c578724469684df7ddbf2a3f1a106c66e3af1dae3b24ad8"
- execution_block_height: 14
-- deposit_data:
- pubkey: "0x903e2989e7442ee0a8958d020507a8bd985d3974f5e8273093be00db3935f0500e141b252bd09e3728892c7a8443863c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86c8283b6c4c8c6f01ff005c62d0199583c99a81ca9207f3a539b63f1732a06eae9e16e601ebf7ac0ac6cb0c0d0f147d0e10c8a3f7877814ac6291ee8fe4c83591dc2a82680bcce53c09b0c41b71fa84be2f799257c020ae2c41c801953345db"
- deposit_data_root: "0x8fe2405c8ed0d927f7c71d710879a4037b27409d0939074d040e88153245c1ad"
- eth1_data:
- deposit_root: "0x5d9c3452b70ec17728332003cf3d2e11d4f16151aef226ed799a837f4453e7a9"
- deposit_count: "14"
- block_hash: "0xa868c9bc5ac184f30ac39df5e5a5fdf0778575aad44b10e835968170c2183b7d"
- block_height: 15
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x660335330368071f958f6fa763caa16650c7e3051733f84ce6bfa410f2052bf9"
- - "0xb9d45d47c8373b0a9a2fe9c21bca36bf2a5fa9609c22e7699107a7d4fe8d39f1"
- deposit_root: "0x5d9c3452b70ec17728332003cf3d2e11d4f16151aef226ed799a837f4453e7a9"
- deposit_count: 14
- execution_block_hash: "0xa868c9bc5ac184f30ac39df5e5a5fdf0778575aad44b10e835968170c2183b7d"
- execution_block_height: 15
-- deposit_data:
- pubkey: "0x84398f539a64cbe01cfcd8c485ea51cd6657b94df93ee9b5dc61e1f18f69da6ca9d4dba63c956a81c68d5d4d4277a60f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8268676a3c7170a291d346859266a729b205077f7bd6c3b73d32ef63e420422aff7137abd008b22ae77db39803ff1c2a16990fd382d9ac7ea535daf73510fb9ad7b11c678bbec586a01ab0072ec47abc5adb498e1e8bf7bd957184b2c73d2a95"
- deposit_data_root: "0x22d0b48ba191226ea3c0a8eb8f05dcc26a66678bd7b2e8f90e43b0a6afd57ab3"
- eth1_data:
- deposit_root: "0x17b149f19cec86287f4b6ff785698cc55366b29e5a3042df3548a6cc4b9256f8"
- deposit_count: "15"
- block_hash: "0xda2b6d573ca1a9f707971321b1a1c65ab93916f4b984d621f4368302e94ab102"
- block_height: 16
- snapshot:
- finalized:
- - "0x24b5bc14c80886b849880b846493fef7c12b8eb723461442d52129ffdf7af6a1"
- - "0x660335330368071f958f6fa763caa16650c7e3051733f84ce6bfa410f2052bf9"
- - "0xb9d45d47c8373b0a9a2fe9c21bca36bf2a5fa9609c22e7699107a7d4fe8d39f1"
- - "0x22d0b48ba191226ea3c0a8eb8f05dcc26a66678bd7b2e8f90e43b0a6afd57ab3"
- deposit_root: "0x17b149f19cec86287f4b6ff785698cc55366b29e5a3042df3548a6cc4b9256f8"
- deposit_count: 15
- execution_block_hash: "0xda2b6d573ca1a9f707971321b1a1c65ab93916f4b984d621f4368302e94ab102"
- execution_block_height: 16
-- deposit_data:
- pubkey: "0x872c61b4a7f8510ec809e5b023f5fdda2105d024c470ddbbeca4bc74e8280af0d178d749853e8f6a841083ac1b4db98f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9939cc7ccebfe4172d92680c74859e3f1d8de2e2a9bb494e9bec8306a5fb492bdab09f136f8f174d0bd5680991dc61970b5b7651ec3ffebe439b03df13e9259760bcfb1896795645796362856cd241b077d4d5e578bed13f7833cdee6135a7ce"
- deposit_data_root: "0x72d791ecc2dc99d82f29f4cebc5df93a493091b4cd6d6b92b31fc92cac128bad"
- eth1_data:
- deposit_root: "0x1eceb67da690c4ae9c9664c51630c2094e3dc517c7473f2659babbe496366483"
- deposit_count: "16"
- block_hash: "0x0698420ee3e7ac4f8c314c740c2df8ddd50e3de679bd57b55e62c53b1d00bbe6"
- block_height: 17
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- deposit_root: "0x1eceb67da690c4ae9c9664c51630c2094e3dc517c7473f2659babbe496366483"
- deposit_count: 16
- execution_block_hash: "0x0698420ee3e7ac4f8c314c740c2df8ddd50e3de679bd57b55e62c53b1d00bbe6"
- execution_block_height: 17
-- deposit_data:
- pubkey: "0x8f467e5723deac7659e1ca273e28410cbaa6d495ab66ae77014f4cd21c64b6b5ab9987c9b5537fe0279bd063fe609be7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x95c61f4b48792bf54197d2f5db308ae3315901f4419b5a1823784fc85190adf17824aa80d884b1813a1ca3792d55612d04e28951014e7e573b0baf51fe7c956c8c6e37e25d353187a1c8633c37cb1d91bf0a90544c26fe5bf562dc99f1a52bb2"
- deposit_data_root: "0x8df60288a3a0e60180b6026dcf71a62c5f88ae0714b433026155c49ab9f9a2b3"
- eth1_data:
- deposit_root: "0x6e612e99981156dbcf528144f5a661a3fec2092d32cf8276174a9f112d6f2694"
- deposit_count: "17"
- block_hash: "0x78f5fafef1f3dbc6ccde8362063b0ee74528976ef4f57407dbd3606fc87fa592"
- block_height: 18
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0x8df60288a3a0e60180b6026dcf71a62c5f88ae0714b433026155c49ab9f9a2b3"
- deposit_root: "0x6e612e99981156dbcf528144f5a661a3fec2092d32cf8276174a9f112d6f2694"
- deposit_count: 17
- execution_block_hash: "0x78f5fafef1f3dbc6ccde8362063b0ee74528976ef4f57407dbd3606fc87fa592"
- execution_block_height: 18
-- deposit_data:
- pubkey: "0x8dde8306920812b32def3b663f7c540b49180345d3bcb8d3770790b7dc80030ebc06497feebd1bcf017d918f00bfa88f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa055036c86894b46ef0ef8e734b0a93cbeae393db9de264e57f03766ac1126ce21371a49dbb3d19c1da17e4f1c80eb1103e48c4ad44b778991ade181955b39928ca274a0625fe21bdb1ac79d8046a37a6066afc2e1fad405271efb80c4cec998"
- deposit_data_root: "0x822c94e13fb37ecca034fabe44e24e06fd5e14685ffc98fc01dfb5d1b2ae8634"
- eth1_data:
- deposit_root: "0x4da8765913d4a494b45f34c4a4cc928e2be2e7e9c41dc13d69f5c0581f5bc628"
- deposit_count: "18"
- block_hash: "0xfdf087208f15f7cfbd0e777ee67d5a1224210c7095ec5a93201d1a042db10d27"
- block_height: 19
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xd834f7120ed8a3f465b6484186992815aef250168d7c624b508c177ecbddb102"
- deposit_root: "0x4da8765913d4a494b45f34c4a4cc928e2be2e7e9c41dc13d69f5c0581f5bc628"
- deposit_count: 18
- execution_block_hash: "0xfdf087208f15f7cfbd0e777ee67d5a1224210c7095ec5a93201d1a042db10d27"
- execution_block_height: 19
-- deposit_data:
- pubkey: "0xab8d3a9bcc160e518fac0756d3e192c74789588ed4a2b1debf0c78f78479ca8edb05b12ce21103076df6af4eb8756ff9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x923fcfc77cf65ae29aa7771f9152140af8dfdf7301889aa52d5f1221b3ef8e7186b3dce969db0b6824308c657978952f01a4b2193d385fdd42ed107332b6714e4e10f70ad07919aadbf51d4f50ce0da40317bf8bc5d55b7d2e1bd8a77ff24a67"
- deposit_data_root: "0x89be43c5944c2e25e15e930dd1c4572501359f2ae617eb829e96b83890517ae9"
- eth1_data:
- deposit_root: "0x2da633fb33c672f3348e994d49a8637935c8bf5db9c8e4524a19625f5c9bdb0f"
- deposit_count: "19"
- block_hash: "0x9b0e02e7dc57fb2c4178c55aa82cddd698a9eb91690a4ce1ce3508a3cb2589c0"
- block_height: 20
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xd834f7120ed8a3f465b6484186992815aef250168d7c624b508c177ecbddb102"
- - "0x89be43c5944c2e25e15e930dd1c4572501359f2ae617eb829e96b83890517ae9"
- deposit_root: "0x2da633fb33c672f3348e994d49a8637935c8bf5db9c8e4524a19625f5c9bdb0f"
- deposit_count: 19
- execution_block_hash: "0x9b0e02e7dc57fb2c4178c55aa82cddd698a9eb91690a4ce1ce3508a3cb2589c0"
- execution_block_height: 20
-- deposit_data:
- pubkey: "0x8d5d3672a233db513df7ad1e8beafeae99a9f0199ed4d949bbedbb6f394030c0416bd99b910e14f73c65b6a11fe6b62e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c0b2b26e5d9672cc95c0fa6d23ca6aa02a7163054a5492b95d5f4470083e4c2aca64e5d38972e13dceeea88996a1fca196e7e540fc05c96c195b3f27b421b38efa3c24f4fe6905c40eab900552531063f00b45718660179d36fa1daeb7e08e0"
- deposit_data_root: "0x8c75a76c9c9892a587d7b0bc8c224d8a6e49d0513ee7f65f59b668d9108deca3"
- eth1_data:
- deposit_root: "0x6dee02182764197fb5be9df0535dbe15ca556b26e628d5aba8b080de4b92049b"
- deposit_count: "20"
- block_hash: "0xf32ee96bf62b97336de0e8846fc0d5ad58cf5b5cf899790859545d40644d00c4"
- block_height: 21
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0x0e15a983c4aaa8cb3676b532c0dae58a86e1a329e2be55baa4e9bf8728bf7698"
- deposit_root: "0x6dee02182764197fb5be9df0535dbe15ca556b26e628d5aba8b080de4b92049b"
- deposit_count: 20
- execution_block_hash: "0xf32ee96bf62b97336de0e8846fc0d5ad58cf5b5cf899790859545d40644d00c4"
- execution_block_height: 21
-- deposit_data:
- pubkey: "0xa1c76af1545d7901214bb6be06be5d9e458f8e989c19373a920f0018327c83982f6a2ac138260b8def732cb366411ddc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9072a23d7159f70dcf6cda33337ded68b59d1caaa9b94b708d06736a8bdf9d414d126ccd9c53aa8baf5c3aa22163a1b013874c29db01d164c3a3632dc7ce73fdbd5d43ca64646418f4412f6d462122c115468faa4371836fcd43150daa696e1e"
- deposit_data_root: "0x428fe5a8d16366f972a52daa8e2eba40bedf30360ecfa2d81efc2d68ee21c80d"
- eth1_data:
- deposit_root: "0x46ffc1bb9ee82fcf871ecdd525f8db26a0616c46644a150ef293d3a969af249f"
- deposit_count: "21"
- block_hash: "0x551285bb963663cc97445ab83591ca6e33d02ae26092c1897804438be2afa704"
- block_height: 22
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0x0e15a983c4aaa8cb3676b532c0dae58a86e1a329e2be55baa4e9bf8728bf7698"
- - "0x428fe5a8d16366f972a52daa8e2eba40bedf30360ecfa2d81efc2d68ee21c80d"
- deposit_root: "0x46ffc1bb9ee82fcf871ecdd525f8db26a0616c46644a150ef293d3a969af249f"
- deposit_count: 21
- execution_block_hash: "0x551285bb963663cc97445ab83591ca6e33d02ae26092c1897804438be2afa704"
- execution_block_height: 22
-- deposit_data:
- pubkey: "0x8dd74e1bb5228fc1fca274fda02b971c1003a4f409bbdfbcfec6426bf2f52addcbbebccdbf45eee6ae11eb5b5ee7244d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8bc79ba412ff7d26f58dcfa5b7f6c2b05570e1ac9c3671a9e2f22f11615b9fa5658a4532a35f5c42b5ffa136f796e04218d279e01990d6591daac0b7cb1481b5c7efe1264f39919dcf56e4b155ba162b7096ba9dd44805868793ab8440eac0a7"
- deposit_data_root: "0x2862ae99f44e6fdb1d9ea652c10832e10334563e8873cc92af000703ee501849"
- eth1_data:
- deposit_root: "0xbb0311909b43eb5cc96107607d54315d84d24a552a27569a0992384417314e30"
- deposit_count: "22"
- block_hash: "0xd903cd669f26d87ed4d754ad13d3e8426505180dd67d9c3b44c3341fd2d33d8c"
- block_height: 23
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0x0e15a983c4aaa8cb3676b532c0dae58a86e1a329e2be55baa4e9bf8728bf7698"
- - "0xdf659f3a3a39eda83bcbebb3a7ce225bda424b28d47ad4fd78a187e94150474e"
- deposit_root: "0xbb0311909b43eb5cc96107607d54315d84d24a552a27569a0992384417314e30"
- deposit_count: 22
- execution_block_hash: "0xd903cd669f26d87ed4d754ad13d3e8426505180dd67d9c3b44c3341fd2d33d8c"
- execution_block_height: 23
-- deposit_data:
- pubkey: "0x954eb88ed1207f891dc3c28fa6cfdf8f53bf0ed3d838f3476c0900a61314d22d4f0a300da3cd010444dd5183e35a593c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x942f0eacead041b7fb92f1917f46e3a884beded26a90aed33b571ea20a88a2b6c2b3bfb39bb961e8d5a9003ae9f95d0e00f5c405ede3135de09749dae540fbd5bc3c89ff1c3494676298caca4a29277aa3f3633fa827fa3b32f3ce9fb71b2486"
- deposit_data_root: "0x171d4e93ba95da64b2a59446bcba72a5af8cb33cd002d8db1774111b851b4c2f"
- eth1_data:
- deposit_root: "0xe1367c132b2c346fb43358ed1d2c392c535070c065450c8cc45c387ba99eeb6a"
- deposit_count: "23"
- block_hash: "0x457a64cc460ff02516925473033c4f5a16a0be8c98f5db1c6cfd4aa9001ebaa9"
- block_height: 24
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0x0e15a983c4aaa8cb3676b532c0dae58a86e1a329e2be55baa4e9bf8728bf7698"
- - "0xdf659f3a3a39eda83bcbebb3a7ce225bda424b28d47ad4fd78a187e94150474e"
- - "0x171d4e93ba95da64b2a59446bcba72a5af8cb33cd002d8db1774111b851b4c2f"
- deposit_root: "0xe1367c132b2c346fb43358ed1d2c392c535070c065450c8cc45c387ba99eeb6a"
- deposit_count: 23
- execution_block_hash: "0x457a64cc460ff02516925473033c4f5a16a0be8c98f5db1c6cfd4aa9001ebaa9"
- execution_block_height: 24
-- deposit_data:
- pubkey: "0xaf344fce60dbd5fb850070e6e76a065e1a32485245ef4f413135a86ae703da88407c5d01c71f6bb06a151ff96cca7191"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x968b1f4d64fbec9c8b5599eb9f3ebf64ea9f5cda3cde3c463cd714022efad0653563a2f24581f2f6c019567abd4801400b79d097b925d363aed6e995f9d1869dbd4ae52ea3542a6a2258094867c767c7e9951e80df872dce35904b6d8eb13c49"
- deposit_data_root: "0x4f24e0bcfcbf2a0e0828b5b63fed6f175c939c6332d622d5959b683ff5a986ba"
- eth1_data:
- deposit_root: "0x75580add56b9161b8747e19faba42030d70994396de5ab95b6b86f61262d86ae"
- deposit_count: "24"
- block_hash: "0x8d44620a0a0ff3d00477c7735e28cfb742a10619664a017f8800ea13dcdcef9a"
- block_height: 25
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- deposit_root: "0x75580add56b9161b8747e19faba42030d70994396de5ab95b6b86f61262d86ae"
- deposit_count: 24
- execution_block_hash: "0x8d44620a0a0ff3d00477c7735e28cfb742a10619664a017f8800ea13dcdcef9a"
- execution_block_height: 25
-- deposit_data:
- pubkey: "0xae241af60691fda1cf8ca44d49573c55818c53b6141800cca2d488b9a3fba71c0f869179fff50c084657831fbeb42bf4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa439766948de7ba95f03ae54671d0c71bf34538405554f9a6b52e4b3672ab8f8b484841844652fa2573a3473fbd6d5d2046f6776ae161384da704df0b0dd8d800b4b0179e88ce193f84bf022fb81490bb4697f331eebdbfcab1c09b76c5f798a"
- deposit_data_root: "0x98c8fddae908c9740b1e57526c08791223bf0fa2d03cee0855a62ba3af995483"
- eth1_data:
- deposit_root: "0x17ab1dfcb9c9438066726df5d532f91d74290292887618fdb5392f7a4da88d3f"
- deposit_count: "25"
- block_hash: "0x0d92259ff68bc51a4dad01a711927f941fcde206c05ef405d37f44e602ca0513"
- block_height: 26
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0x98c8fddae908c9740b1e57526c08791223bf0fa2d03cee0855a62ba3af995483"
- deposit_root: "0x17ab1dfcb9c9438066726df5d532f91d74290292887618fdb5392f7a4da88d3f"
- deposit_count: 25
- execution_block_hash: "0x0d92259ff68bc51a4dad01a711927f941fcde206c05ef405d37f44e602ca0513"
- execution_block_height: 26
-- deposit_data:
- pubkey: "0x96746aaba64dc87835ba709332f4d5d7837ada092b439c49d251aecf92aab5dc132e917bf6f59799bc093f976a7bc021"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa147ee89efcadbe1c8ae5dd2309b9153966d57d0c69b47f33f1a2a0bfa47821956ea5b20ffdfd77602509e7c92b4cf70ac7e16593c9325e41869af6e6844a09f20273001cbd00f413690c913b8c61390e40181c3c78d0605db457b17165535b"
- deposit_data_root: "0xc220f1e62f775aa20f6783a08ede02364bb656aa3aea8a53b566cc3f5780ce20"
- eth1_data:
- deposit_root: "0x28533734876a9a4da9bc4518a561f124e9c09a3c52e727707cbbb2bae1a8afd4"
- deposit_count: "26"
- block_hash: "0xc11cc9313a9f6f28d1f4b6f06a0f4871efcc548df79c90c77b10b6bd6af073b7"
- block_height: 27
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0x16bdf648ff50bb5f33cab70a7cff595ba63caaff4fcb670610e802cc344dffc2"
- deposit_root: "0x28533734876a9a4da9bc4518a561f124e9c09a3c52e727707cbbb2bae1a8afd4"
- deposit_count: 26
- execution_block_hash: "0xc11cc9313a9f6f28d1f4b6f06a0f4871efcc548df79c90c77b10b6bd6af073b7"
- execution_block_height: 27
-- deposit_data:
- pubkey: "0xb9d1d914df3d4565465c3fd52b5b96e637f9980570cabf5b5d4aadf5a329ac36ad672819d997e735f5052e28b1f0c104"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2a21801a7ddd00d4b1df1c571b74b95b7cb92d484712349c612438183e4d486113f51e356343be7835a0f6c88e7de5a0978cb3815b3ca044fe741c25b02eade6fb36500b2264305b5954cc4f5ad451c6f43d552405def57a07411a32016097b"
- deposit_data_root: "0x6db78e60584351fc046ce86f6f56c1ec42ecc5526677d4a1b3bb720280277f38"
- eth1_data:
- deposit_root: "0xf18ab78c3cfee43fc0c09c7c1101d655b86b30809149134e0fd6603247b48650"
- deposit_count: "27"
- block_hash: "0x6381e5f3e249642bb56562bb2cd645d77578491d8b22b4de49976c606f10b275"
- block_height: 28
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0x16bdf648ff50bb5f33cab70a7cff595ba63caaff4fcb670610e802cc344dffc2"
- - "0x6db78e60584351fc046ce86f6f56c1ec42ecc5526677d4a1b3bb720280277f38"
- deposit_root: "0xf18ab78c3cfee43fc0c09c7c1101d655b86b30809149134e0fd6603247b48650"
- deposit_count: 27
- execution_block_hash: "0x6381e5f3e249642bb56562bb2cd645d77578491d8b22b4de49976c606f10b275"
- execution_block_height: 28
-- deposit_data:
- pubkey: "0x963528adb5322c2e2c54dc296ffddd2861bb103cbf64646781dfa8a3c2d8a8eda7079d2b3e95600028c44365afbf8879"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa52e6582b3f70257211e96a5023f5f860d6c9a236ddd1362f8bf354a3621cee74500682ef4e10f725f19a15527c086320fe2714745b54b4be4cbf1d6ff3f84821bd9e789717ad9fcfc36f9a96509fe4889c0c7824f4e0ce21108744f369d1c07"
- deposit_data_root: "0x7e238e9a9674ddc5e0913d2f698cb776a64392c390353e42287f7c5f4098168a"
- eth1_data:
- deposit_root: "0x4fa046ca0d14d29f272ee56ef063b382a46a04b30cf2826dd0c832152a48d476"
- deposit_count: "28"
- block_hash: "0xf6c4330660f686d3c0549237f8331f78fdb99653b72a25d5b88b7a26be512ae3"
- block_height: 29
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0xf7068f7d6c4ca26e61c3ea98cde4d5de184da7fba2f5a99ea5de37c719e27a07"
- deposit_root: "0x4fa046ca0d14d29f272ee56ef063b382a46a04b30cf2826dd0c832152a48d476"
- deposit_count: 28
- execution_block_hash: "0xf6c4330660f686d3c0549237f8331f78fdb99653b72a25d5b88b7a26be512ae3"
- execution_block_height: 29
-- deposit_data:
- pubkey: "0xb245d63d3f9d8ea1807a629fcb1b328cb4d542f35a3d5bc478be0df389dddd712fc4c816ba3fede9a96320ae6b24a7d8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a177ab3d2b199d3f8bd8dea6b896e1456559e2205064eca589ff1150ad4a4cefb3307fbe1eab515b1caae1d9bd4181f106e1371e3f11d22dd76d90589dcad6b9d9317c7a403dcee09b5074bed807fe6e57c85d688956ad439232d20bdcfc069"
- deposit_data_root: "0xe71a456a9faa68cca752c81c90d954138a586b0f8166c8870ea89b54b01313b3"
- eth1_data:
- deposit_root: "0xc71512461c08e8fab3ad7d23413a46e9c47f3d133ce181800484b6f4603bcd55"
- deposit_count: "29"
- block_hash: "0xd11a018e251c410ef7672f160087e677d29da1b591e14ac632fa2a1c9e00b62f"
- block_height: 30
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0xf7068f7d6c4ca26e61c3ea98cde4d5de184da7fba2f5a99ea5de37c719e27a07"
- - "0xe71a456a9faa68cca752c81c90d954138a586b0f8166c8870ea89b54b01313b3"
- deposit_root: "0xc71512461c08e8fab3ad7d23413a46e9c47f3d133ce181800484b6f4603bcd55"
- deposit_count: 29
- execution_block_hash: "0xd11a018e251c410ef7672f160087e677d29da1b591e14ac632fa2a1c9e00b62f"
- execution_block_height: 30
-- deposit_data:
- pubkey: "0xa98ed496c2f464226500a6ce04602ff9ef133ed6316f372f6c744aee165149f7e578b12780e0eacec307ae6907351d99"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa12d7c9738f2e443bb7226e03631847b82b84fa2a77426b101dd4c0574da816abfbd0905df5e00d4217ac9ea10b0213c09f6ed2fe8628f8e15c8e07d7d7809cefebb0d9dc515b2f2603e6fba7854c8c842b70137e0f5dea4e2f37ca6b116d8dc"
- deposit_data_root: "0x9e5bfab0b9bd4cbf7232f3a004074c87974e1e1c98838a99775355443426bb6c"
- eth1_data:
- deposit_root: "0xc0108c1784340504324dc235e2214f51603386e6d7d1a36a36adf67148a19a66"
- deposit_count: "30"
- block_hash: "0xf50b59b6a0f164a687d5388bc590467f68a874769b2e320a0c83f4a01dcd663c"
- block_height: 31
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0xf7068f7d6c4ca26e61c3ea98cde4d5de184da7fba2f5a99ea5de37c719e27a07"
- - "0x011f1eb3813fb8ee88932f9e3ab2781c9c085105658ba15559994d2e26a1d8dd"
- deposit_root: "0xc0108c1784340504324dc235e2214f51603386e6d7d1a36a36adf67148a19a66"
- deposit_count: 30
- execution_block_hash: "0xf50b59b6a0f164a687d5388bc590467f68a874769b2e320a0c83f4a01dcd663c"
- execution_block_height: 31
-- deposit_data:
- pubkey: "0xae00fc3de831b09661a0ac02873c45c84cb2b58cffb6430a3f607e4c3fa1e0932397f11307cd169cdc6f79c463527260"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84ea7a055239b25ec73f3ac4f12e92941c3cd05a35a72f9a1ee8267cdbc8b97e9ee32e52262b87563186d716ead86d2f01d7ae34575579a6348d9085154b0ea1f186374f169c251e621e1fd177a7fffcb1af3feac4555092ef628a090de37a85"
- deposit_data_root: "0x661bd0e0ddbd2ba4acb89aa575180637c85f5413ed1bcdc028ab1abd0cfc2b47"
- eth1_data:
- deposit_root: "0x832e7610fb4663859d3d72f21510c20aede5e3a5dfc5ac4434c5800ebfd78444"
- deposit_count: "31"
- block_hash: "0x5eceb3df2ef05c68164fa475e0e0e0e2ec5f5613dd8bfe1c486a172dbf0ae594"
- block_height: 32
- snapshot:
- finalized:
- - "0x5f652df37d6370cd7a4267959f0b885e201b293a69f57a8769c92d797050967e"
- - "0xf411283523e35f406ed67667dab5e352fc257052ddac82c3bb78c1cf157884aa"
- - "0xf7068f7d6c4ca26e61c3ea98cde4d5de184da7fba2f5a99ea5de37c719e27a07"
- - "0x011f1eb3813fb8ee88932f9e3ab2781c9c085105658ba15559994d2e26a1d8dd"
- - "0x661bd0e0ddbd2ba4acb89aa575180637c85f5413ed1bcdc028ab1abd0cfc2b47"
- deposit_root: "0x832e7610fb4663859d3d72f21510c20aede5e3a5dfc5ac4434c5800ebfd78444"
- deposit_count: 31
- execution_block_hash: "0x5eceb3df2ef05c68164fa475e0e0e0e2ec5f5613dd8bfe1c486a172dbf0ae594"
- execution_block_height: 32
-- deposit_data:
- pubkey: "0xa4855c83d868f772a579133d9f23818008417b743e8447e235d8eb78b1d8f8a9f63f98c551beb7de254400f89592314d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x95e0bd85c20f14f8eb05bb4f2d6a5a0297c78c6598fcc886fa93d2bee73b52c8913a848f690be3094883fbe31200bae90a1401d4c8b11dc82c635f63a3f42cef8fb19f04b27e7ec67c03811327614242d407b157b852e008df78fe482c3496ac"
- deposit_data_root: "0xc8d8e9014b8fd00b885838bd0e71fcec16dbdef5b5b5cae3b09176d8e6bf7883"
- eth1_data:
- deposit_root: "0x2def103e29ea70f435350e0a77e1f8cafe671db9d9f43a1d20621abc7f85c73a"
- deposit_count: "32"
- block_hash: "0x6476bebf6ce3c9e8cbc630a58962e9891b99320d548ea03e527ebd3d23f3c35c"
- block_height: 33
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- deposit_root: "0x2def103e29ea70f435350e0a77e1f8cafe671db9d9f43a1d20621abc7f85c73a"
- deposit_count: 32
- execution_block_hash: "0x6476bebf6ce3c9e8cbc630a58962e9891b99320d548ea03e527ebd3d23f3c35c"
- execution_block_height: 33
-- deposit_data:
- pubkey: "0xa9cf360aa15fb1d1d30ee2b578dc5884823c19661886ae8b892775ccb3bd96b7d7345569a2aa0b14e4d015c54a6a0c54"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x87e60e3980d5d71bcc9983c3317ea8a1a60862ea9f4a4d3c3c710ddbd90db3dac49d6ff7c9d2f8c447a02f9310d7e2eb119e06b83543bc0918c87199ba2724624ece384c336e69743850dd4b3b92f560423279bf50252546d612107a03bab3d8"
- deposit_data_root: "0x1051a6ad73280cee0f10ba9c5762e001a23aef44269a7eae9b2050d17ac1b2cd"
- eth1_data:
- deposit_root: "0x2260d0f4b57dd958fdc8badd66391e11e13bfdb64563ce7904bec1ddc4f8ece1"
- deposit_count: "33"
- block_hash: "0x0268dec10d6ad09835aa9a0a2fe971f4b4ef81f59aaf8a9d43d99f17c186964a"
- block_height: 34
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x1051a6ad73280cee0f10ba9c5762e001a23aef44269a7eae9b2050d17ac1b2cd"
- deposit_root: "0x2260d0f4b57dd958fdc8badd66391e11e13bfdb64563ce7904bec1ddc4f8ece1"
- deposit_count: 33
- execution_block_hash: "0x0268dec10d6ad09835aa9a0a2fe971f4b4ef81f59aaf8a9d43d99f17c186964a"
- execution_block_height: 34
-- deposit_data:
- pubkey: "0xaef9162ee6f29ee82fbfe387756d84f9ac472eb8709217aaf28f5ef0ea273f6210e531496470b30d2b7747216e3672d5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5dc53467b3e5826af953385e83f5a21858c7019c6c87aad005509038379db54e0d7d48453bb00394f78e1895a3af296147c45f766f4eafad06e60e7d2b206d628ba2cc61db59a472c68cf48b28979bfccf28a4cafac63271bfcce7461450b5e"
- deposit_data_root: "0x6c24e556eec47c66d6b2a3ec29e013ba206ea34e8d3685b90ff823b06aa80b4b"
- eth1_data:
- deposit_root: "0x9268f23209182ea5393b84731c67d205b50dd541b590548479d816be20fdee70"
- deposit_count: "34"
- block_hash: "0x69ef65f0294564315ef609e7b5bf76420ced3fe110c763dd8bcd348760b1a267"
- block_height: 35
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x70918d35011dbe3749fad7b8ca02046cb69b4893834ff0f71cfe11a17f2fde0c"
- deposit_root: "0x9268f23209182ea5393b84731c67d205b50dd541b590548479d816be20fdee70"
- deposit_count: 34
- execution_block_hash: "0x69ef65f0294564315ef609e7b5bf76420ced3fe110c763dd8bcd348760b1a267"
- execution_block_height: 35
-- deposit_data:
- pubkey: "0xb7e6e187ed813d950a9a17d1e70c03e4de2903596c4c5ff326848515c985deee38198efebc265300cd4f1d6bd7b5d264"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x886d08aca274c127f741d249a865851818a8bd387d1eec83f2d702c4ce78e6ba93d3ddc629d0269f43a91b2a56074797044f37c528b10344cd08808f829867577aa8aed839f6066922ed4953376b65ea14ba725478674bf32a37e337563774cc"
- deposit_data_root: "0x72c9a1bdb8a1deaae1c4007567257ebad96b664c27c9accfab8ad9f9d10b8ca1"
- eth1_data:
- deposit_root: "0x5261a6f04d75e281c1c83bd3a443746b643d0956a23cb2ce69d39c0504072038"
- deposit_count: "35"
- block_hash: "0xd54072d4f8010162a877d38f5d814d9a05ec3ffacdf04128c86205cbc9de92aa"
- block_height: 36
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x70918d35011dbe3749fad7b8ca02046cb69b4893834ff0f71cfe11a17f2fde0c"
- - "0x72c9a1bdb8a1deaae1c4007567257ebad96b664c27c9accfab8ad9f9d10b8ca1"
- deposit_root: "0x5261a6f04d75e281c1c83bd3a443746b643d0956a23cb2ce69d39c0504072038"
- deposit_count: 35
- execution_block_hash: "0xd54072d4f8010162a877d38f5d814d9a05ec3ffacdf04128c86205cbc9de92aa"
- execution_block_height: 36
-- deposit_data:
- pubkey: "0x81054bd51ce57a8415f0c8e0f2fbf94f5a8464552baa33263c20a4da062e5ed994a4d32c171106d2008cd063f48f6fe2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97cc963e23ecd9b21bdea8cfebaa2b4d1a47caef4f6c404ce40849fc20ac2337116fab977fc21104491435e6301d499203d6d33b70e389ff42264891d422a79f76d20ec6d501af2d03fdf2d44d00894db77955b19a91823e665a4fe7cff2e9a7"
- deposit_data_root: "0x4a985ca67543ab0f8e8510fc74fcd3efc4eb46e4590c60f415a568b4253701ad"
- eth1_data:
- deposit_root: "0x82c0b3acf41d802658accffa90b6991181cfe9ea6163104cffe745280e17831f"
- deposit_count: "36"
- block_hash: "0x3f9eb6bfe92c16a2bfd72bd6f5a7464255400c39a5ca46e0f50b91d3908fa0a8"
- block_height: 37
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x98b240f56117c7974d324f09c387e28e5acced1186003fe8df875e1c7377d7a5"
- deposit_root: "0x82c0b3acf41d802658accffa90b6991181cfe9ea6163104cffe745280e17831f"
- deposit_count: 36
- execution_block_hash: "0x3f9eb6bfe92c16a2bfd72bd6f5a7464255400c39a5ca46e0f50b91d3908fa0a8"
- execution_block_height: 37
-- deposit_data:
- pubkey: "0xaecc56f2b1c4011d450214d3e1254479d583a6a5c2c06fbc049512731f76227d140df9f36a3f76b4ccb4df1342403573"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb609cc73d220819290cb6f814295b01aeaa044a83105a7df712ab659e9368d3291b55f1b611bd28edc40c5694b5786a6068616edd2cdcac6104d0342b70b1aa0005bfb6828813d58fde482972f8c837d0650945b56e41ab157bbc4e1e7928351"
- deposit_data_root: "0x6466d5d6da2e21242c13f72238a6796c78b52decddb11ed4e3b5e489b96317f0"
- eth1_data:
- deposit_root: "0x1cfd89cb2db15e0811b5a9cf5047e0e0b561afced194bb0a102a2ba155319600"
- deposit_count: "37"
- block_hash: "0xbd8cb6544b20968a1b580dcc4f70cfd241f736bb1c399063a7c25e077e734d15"
- block_height: 38
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x98b240f56117c7974d324f09c387e28e5acced1186003fe8df875e1c7377d7a5"
- - "0x6466d5d6da2e21242c13f72238a6796c78b52decddb11ed4e3b5e489b96317f0"
- deposit_root: "0x1cfd89cb2db15e0811b5a9cf5047e0e0b561afced194bb0a102a2ba155319600"
- deposit_count: 37
- execution_block_hash: "0xbd8cb6544b20968a1b580dcc4f70cfd241f736bb1c399063a7c25e077e734d15"
- execution_block_height: 38
-- deposit_data:
- pubkey: "0x9243ef5ed3bd28892d1ef4f7aaf29faeb9c0e725673cd38e308bd756f20a9ee09de5cd9822e5e77bd03b734ef8a92695"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa19c19c9d1d616f7d3f57393d9ce5230dc2502f6764612a0911227811bea8688fb1f7ffcfb680ea21dd60a3a8faf596b0edaef49936901ae891d7f2266ef937731bb2fb34fd1e30bb161ab8b8e6ee389759519079ebdab9f1500fdb3b633d110"
- deposit_data_root: "0xe430fb5af8b28239457fecf2ea0106ca1cf1e68e5d22ddc64adbb4b5167254be"
- eth1_data:
- deposit_root: "0x7580110cf5b8a5450a42ea097b2fcab6ad4cdb58a2100f8274e486b62ce673e2"
- deposit_count: "38"
- block_hash: "0xed447968de652c510595235a85ad711d39cb1d767bb247d94e82b63be69155ba"
- block_height: 39
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x98b240f56117c7974d324f09c387e28e5acced1186003fe8df875e1c7377d7a5"
- - "0x5240648c484242305f1ff513c043647c24fc5e5d61cd4196ebf3c2c86402f1f0"
- deposit_root: "0x7580110cf5b8a5450a42ea097b2fcab6ad4cdb58a2100f8274e486b62ce673e2"
- deposit_count: 38
- execution_block_hash: "0xed447968de652c510595235a85ad711d39cb1d767bb247d94e82b63be69155ba"
- execution_block_height: 39
-- deposit_data:
- pubkey: "0x925b1fb57c06b5668567bd5aa196531032d6f8918dd4f702017c11b59288e3bdb98e3820ac22780f73580a4119de4bbc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81c25d6edbe71803bd57c92c073be629bae323c28ff1a6f30ed5c507493d8271591b46581467cdd92f5847d20a1bc2760bc351838dbf690d90e06af696c7e9e46b943189b2aef29115e1c6e4ea83ec724c7955736e42c611859afebaf622a1a1"
- deposit_data_root: "0xfa7f084e644997f1640e3568bd2400fa26cf9fd43e37275cc6578db139d9921a"
- eth1_data:
- deposit_root: "0xab72caf415667e76d99579f3cd9f5092c19470ce7e2267e9d7dc6d1c42c1401f"
- deposit_count: "39"
- block_hash: "0xd7ecbd540da29e0e617261e2b901815fc05c912a34d91df31de54e91eba6f49b"
- block_height: 40
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0x98b240f56117c7974d324f09c387e28e5acced1186003fe8df875e1c7377d7a5"
- - "0x5240648c484242305f1ff513c043647c24fc5e5d61cd4196ebf3c2c86402f1f0"
- - "0xfa7f084e644997f1640e3568bd2400fa26cf9fd43e37275cc6578db139d9921a"
- deposit_root: "0xab72caf415667e76d99579f3cd9f5092c19470ce7e2267e9d7dc6d1c42c1401f"
- deposit_count: 39
- execution_block_hash: "0xd7ecbd540da29e0e617261e2b901815fc05c912a34d91df31de54e91eba6f49b"
- execution_block_height: 40
-- deposit_data:
- pubkey: "0x9648b83a4f09b4ca2021f0c193c5c41df1465715761bca52671ca790a3e92d67686b97b3d54c6110409779df887bd9c6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4a58b0ccdc9ba7bd7ac424e1e8b961ffc3839ce06f200551b7302a33d96a8c047f1184889c21711fc2de482c8a9ac05043ff957bee33046cdb77ec386225bf885776275e0643b155d528ba24ceab1c96e2c2da2d64021f7a26f742341f1c6f4"
- deposit_data_root: "0x1edbb8a2956dd6fe52e14a004566f29757e212de7f64c8d98070f33ba78a78d6"
- eth1_data:
- deposit_root: "0x3c6fcce34339d0a97e566eb15d960c2b79440eb5a55a2a2e66dee1a3f63e515f"
- deposit_count: "40"
- block_hash: "0xfdb11831fe4c2fc8596455800b8420cce083f2ff92552d4255876432038a335c"
- block_height: 41
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- deposit_root: "0x3c6fcce34339d0a97e566eb15d960c2b79440eb5a55a2a2e66dee1a3f63e515f"
- deposit_count: 40
- execution_block_hash: "0xfdb11831fe4c2fc8596455800b8420cce083f2ff92552d4255876432038a335c"
- execution_block_height: 41
-- deposit_data:
- pubkey: "0xa34febc12af07316580b480364f90a76313ccce7927bbe263e27ea270853b02ad4d1428caf55363f3ebebac622cb9fd6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xadbf354b18eaaed15a3191ee9dc053d250fb54b59959eaba812b8a589797d5c310170da7b98b0448d4a3aaf3091305bc07b6c077b5973fcf0c7d5aefaacea5b6988b297f336841215a5bbed37f0271b325b178a4bf0835bfceae150ae6b3de37"
- deposit_data_root: "0xcde3ed824c06263d6e165d50f2781de0f8e4b36f6e4167427a3e9b90ff45f7be"
- eth1_data:
- deposit_root: "0x3fdfcce325e69c97df3b47c43925e4ff58f633e9c1a4fcd6997c98a4d6931406"
- deposit_count: "41"
- block_hash: "0x4b93ca227181f17fc7c4f95ec672f19a1485d4ebc1981de852066119ede6f989"
- block_height: 42
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0xcde3ed824c06263d6e165d50f2781de0f8e4b36f6e4167427a3e9b90ff45f7be"
- deposit_root: "0x3fdfcce325e69c97df3b47c43925e4ff58f633e9c1a4fcd6997c98a4d6931406"
- deposit_count: 41
- execution_block_hash: "0x4b93ca227181f17fc7c4f95ec672f19a1485d4ebc1981de852066119ede6f989"
- execution_block_height: 42
-- deposit_data:
- pubkey: "0xb8cd1cef89aa1567a6058957442a698cf1b267130606f749451152959a5dfb50d243890d4adc2c3309f7696d54af1260"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x95031abea421c3997538c779d67489c04c635449f753f8836400532d70e6c4c7d0e42117b773da9b365dd9590cd01ad6079cdaa62e7ce21911bd519218064200e3d15ad252a072eac4554da519bb23f609b63684045b209933a5398606ba8aaa"
- deposit_data_root: "0xdc998298cb82156f077de9a7289d8e92e3270653d4c5388f6ff11102dfa75a15"
- eth1_data:
- deposit_root: "0x60ad801fc6a68abf39ce5ee6db6913e019e9370ea744c3d4b7436f1bd1b7befe"
- deposit_count: "42"
- block_hash: "0xdd485eb08d480f2e25f7ae196f4eb69eaad495bf76be1c9c1d237f92ca6c0d40"
- block_height: 43
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0xe3897ec112ed55cfe802be2b7c9dfcc1b5a274736d0a8d8588d28b93bc2e26c9"
- deposit_root: "0x60ad801fc6a68abf39ce5ee6db6913e019e9370ea744c3d4b7436f1bd1b7befe"
- deposit_count: 42
- execution_block_hash: "0xdd485eb08d480f2e25f7ae196f4eb69eaad495bf76be1c9c1d237f92ca6c0d40"
- execution_block_height: 43
-- deposit_data:
- pubkey: "0x92a93728c252a45ef587ca53a037593912599d82e2b8aa1b734b99d500a0ac8c142092ea8b3c2c34a28dc8ddf337a249"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2efbb211e85d2a8cd924085571ab0637583a0fbe41a4f2f4e5b173631067f69fa0eebd2910673afe6bd59bb6f34fce60a974adacb5c1edf47bf8d81084a26e9cc16c553c1601594a393172613cdde131b96434801b6b77ca08f00db29294ecb"
- deposit_data_root: "0xd038d18b6d28712d26bfefef79e3df36a9f5502e066f1a6667b0a0aca21322f6"
- eth1_data:
- deposit_root: "0xf82bbce9e12b06f122b0c9db7b2a24484f78772401aaf5056610de1071de7829"
- deposit_count: "43"
- block_hash: "0x65a8f07cef0dc9e98a8b3c685ed6a36bd6ad5fb6e97b57d202074839fd857e10"
- block_height: 44
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0xe3897ec112ed55cfe802be2b7c9dfcc1b5a274736d0a8d8588d28b93bc2e26c9"
- - "0xd038d18b6d28712d26bfefef79e3df36a9f5502e066f1a6667b0a0aca21322f6"
- deposit_root: "0xf82bbce9e12b06f122b0c9db7b2a24484f78772401aaf5056610de1071de7829"
- deposit_count: 43
- execution_block_hash: "0x65a8f07cef0dc9e98a8b3c685ed6a36bd6ad5fb6e97b57d202074839fd857e10"
- execution_block_height: 44
-- deposit_data:
- pubkey: "0xb7ee0ef26144de04d9cc80864b869b7ecafbf1b7c0050403cc3c3b514368713b8bb708c464568a18c837e1fd21d09063"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa356193c75dfb2c15995650552d0ca9df6d9adc19dd19dcd26d79e88420fd0b1ad7a923e6c44ec5de81b5306b93f36040341b2393d40a3b0cd70f6f71dabac60bf2d1948a8e2da190316b56ebd84d9ecb7fd6d894380331070885da41c9b6277"
- deposit_data_root: "0x433ac5e37040ef1005e56991ecc42a7207b1557a9d446e5b56a3bb8a617f52fb"
- eth1_data:
- deposit_root: "0x9d13195b240044e78fe982d51b31223feef1d8997e9f8231ac727a05343c55cc"
- deposit_count: "44"
- block_hash: "0x3615ed6ba3c2eac9dfb051aa571d6275395111b6eb80f82acd4da05cfd687f5b"
- block_height: 45
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0x7d41f8f8048c87f844b352ae9a9900997fe13c3cb8786346e55ba2c5affb00d2"
- deposit_root: "0x9d13195b240044e78fe982d51b31223feef1d8997e9f8231ac727a05343c55cc"
- deposit_count: 44
- execution_block_hash: "0x3615ed6ba3c2eac9dfb051aa571d6275395111b6eb80f82acd4da05cfd687f5b"
- execution_block_height: 45
-- deposit_data:
- pubkey: "0xafc0fa2ed6a270de6122a19d4600380b7f9b5e974d16f095f1702f55792ecab0128b155a69f17ad64a6de0a7063642ec"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c256c7242c520d646b3cb21d1fbf19097b8131857e7dc246fc81dfe8389b2335d9e1c2e394051a8293ec33bddb006c018696be5402901b5f9446d97cb9f8c5fe48c501e13382801e4e96dfae1df99471df39cc82741590c6915624f63d8bfaf"
- deposit_data_root: "0x2522ea9a8f9dd6862e56af3f38827a80813082b521d43b7e21903c5b81fc1290"
- eth1_data:
- deposit_root: "0x1815da8f5d53ed18c0db0942e6e06bbc1e1e87cc21dd186b66d3a654fbb2aae4"
- deposit_count: "45"
- block_hash: "0x2ee3c9a0d2109d8544754a4d3771e393d9f15c55211c92be0f486e7478840805"
- block_height: 46
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0x7d41f8f8048c87f844b352ae9a9900997fe13c3cb8786346e55ba2c5affb00d2"
- - "0x2522ea9a8f9dd6862e56af3f38827a80813082b521d43b7e21903c5b81fc1290"
- deposit_root: "0x1815da8f5d53ed18c0db0942e6e06bbc1e1e87cc21dd186b66d3a654fbb2aae4"
- deposit_count: 45
- execution_block_hash: "0x2ee3c9a0d2109d8544754a4d3771e393d9f15c55211c92be0f486e7478840805"
- execution_block_height: 46
-- deposit_data:
- pubkey: "0xa5869ba554d1432b09ee677c117511291b9901f169e870831f457caa6ccfab376cb1fe33813bdb495cf4afec9ea35fdf"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91cd39a6714d4851e7927c03e5039fed3725573cc1e6005bb20ba21e47ee63ead1defd93963ad5905c6f8074b1197c131011daa8be473190c83523e3028db2f8dae5ff7daf1f708f2830b0ab70916a20154e8135a20972109cfcc1f76bb05caa"
- deposit_data_root: "0xd716729370e1d97244f1758c3f5540e29461b31686c30dd333abbbae979e43a4"
- eth1_data:
- deposit_root: "0xda383b51baf43274f4bc3a1f6573a660a0f49feda6d3cfedf3aec0050a8bff02"
- deposit_count: "46"
- block_hash: "0xdc9667ffa9917e167974cac3e67dd0845657c81556dbf51e77b6915a2741bbb2"
- block_height: 47
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0x7d41f8f8048c87f844b352ae9a9900997fe13c3cb8786346e55ba2c5affb00d2"
- - "0xbd3a8edc6db6b9fe322ca4af975e44750c273e56b1a6730a29adc004939ae9a8"
- deposit_root: "0xda383b51baf43274f4bc3a1f6573a660a0f49feda6d3cfedf3aec0050a8bff02"
- deposit_count: 46
- execution_block_hash: "0xdc9667ffa9917e167974cac3e67dd0845657c81556dbf51e77b6915a2741bbb2"
- execution_block_height: 47
-- deposit_data:
- pubkey: "0x92f43d79d9f488010b310a54f3fc2e7f4be191ca06d93e588c30c8abf59a52190e060b285ac626eb13cd95bbcc3a0a2a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x921608298683b15a514c05fb08f39958123498b48d8bbfad1fdd62fc84556aaba3b363e3a20c8423c9b8a157690241bb0ecfeeff3393f4502a2cd14cd8e2fa2373ddba64b573e1ec4c6941ba7cc423248878b9d46444ad8c10bd6f4bea2234e6"
- deposit_data_root: "0xd5d100cccf8847fdf9b03e33e030d4a7dfc868e3c3b6107c4849bd78140bb87b"
- eth1_data:
- deposit_root: "0x62b97e8c2969a6f0d48a9f61a762561a8c7189af1c178b9215771e614909e7f8"
- deposit_count: "47"
- block_hash: "0x75bd1deec6fafccc3cf68485f19eba3c5e0edbeec29ae9f7c59b44f5c44a6f0b"
- block_height: 48
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xd499ae9a9b57a50ee29e23a5f5130a7ae9dd46ac336b2741be8f300c7ff363e4"
- - "0x7d41f8f8048c87f844b352ae9a9900997fe13c3cb8786346e55ba2c5affb00d2"
- - "0xbd3a8edc6db6b9fe322ca4af975e44750c273e56b1a6730a29adc004939ae9a8"
- - "0xd5d100cccf8847fdf9b03e33e030d4a7dfc868e3c3b6107c4849bd78140bb87b"
- deposit_root: "0x62b97e8c2969a6f0d48a9f61a762561a8c7189af1c178b9215771e614909e7f8"
- deposit_count: 47
- execution_block_hash: "0x75bd1deec6fafccc3cf68485f19eba3c5e0edbeec29ae9f7c59b44f5c44a6f0b"
- execution_block_height: 48
-- deposit_data:
- pubkey: "0x9698d9519a02b64f230e5a2520401799c2ca7d69ab23a6d9817943147264bf00d409264b928718245efff4f7ee97dd5c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae3dcc94f04909fa6d3c8b56c6af1e037064eea73a5ee9300b2bb4655cd50e4e082108b3009c13d1deb4b94f7ff4c7cf028cb95f86c1e354892263d43826de017601f20c5fd99eadf42e1cacae7c2698715be3582d3cba2d2962891fb1dc58bd"
- deposit_data_root: "0xbc47514e4e62c58f75742971af992d758dad75cf523eccbdaa33bee01a290794"
- eth1_data:
- deposit_root: "0xc36afe52bbbc41a91a58ee9e37deb448edd44992b00cb0bc8b5a32d46ce5dfff"
- deposit_count: "48"
- block_hash: "0x296842ff1c8cdd3e7729800191fe9a1da0209b1f554709867dadc6942510d3ab"
- block_height: 49
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- deposit_root: "0xc36afe52bbbc41a91a58ee9e37deb448edd44992b00cb0bc8b5a32d46ce5dfff"
- deposit_count: 48
- execution_block_hash: "0x296842ff1c8cdd3e7729800191fe9a1da0209b1f554709867dadc6942510d3ab"
- execution_block_height: 49
-- deposit_data:
- pubkey: "0xa852816b8e463178eea5acebb4b86d0acb6d8c6812cf313296bd271ea4d2fd89d281e5fc296df4df49019169bdf96922"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa562944e5476538903b89274c26eebf2bf87547968022140c4c950fcf9c02140ca064cdfa79aeb3bb0d0f738b2f56f401501fe791231633153ce1a56ccec8b8ba3b3d104b00b6477c89cf887b65d4ebc32c7f8d4d692288068941131d50c286"
- deposit_data_root: "0x15e2e2026f0b8722f28569cf3752f02eec3d115c7a58947559fb0d40bc70f211"
- eth1_data:
- deposit_root: "0xe8659b62077801e4e285d99cb0f7df9eee6332af5d7173211c5119e89bfe98c7"
- deposit_count: "49"
- block_hash: "0x2ad547b4552b0d033398b10c76a224ea4e27af714a7d40208a1bcad524bd3de9"
- block_height: 50
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0x15e2e2026f0b8722f28569cf3752f02eec3d115c7a58947559fb0d40bc70f211"
- deposit_root: "0xe8659b62077801e4e285d99cb0f7df9eee6332af5d7173211c5119e89bfe98c7"
- deposit_count: 49
- execution_block_hash: "0x2ad547b4552b0d033398b10c76a224ea4e27af714a7d40208a1bcad524bd3de9"
- execution_block_height: 50
-- deposit_data:
- pubkey: "0x8a298ee1ac0466ecaa04d5798048c6e192409af63217f32fd7e07794cfcdcd8deca055b9782dd1ad45a578a9ec10606c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa14f099ef773a2282a7c0d664557897c48aa594015e05373a5fef26c8dc848ae0c25718d3a9be982117159c908abcc1e0aab94110824c8410ea08039398a8569a844cafd9002ef319a2e6a0717a5b340a4d153e6f136be7a57ee5abd73cf7017"
- deposit_data_root: "0xc46f9746cf62672d7d8ed56c05a7dc880f2475a6bd8a73151abef6f88907d53c"
- eth1_data:
- deposit_root: "0xc30f240a494e623caab8bc918828d31feea930902c6e3dca2c3a423f3f0bf102"
- deposit_count: "50"
- block_hash: "0xdcf96433eba5c4c5877afce8ecd730c943b0b3b02c6b36593fda5839cc095d7d"
- block_height: 51
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xe74828c6edb30e3e4bf54de63aeab6c3f97f7d6f3a558705eaedef064b8645ce"
- deposit_root: "0xc30f240a494e623caab8bc918828d31feea930902c6e3dca2c3a423f3f0bf102"
- deposit_count: 50
- execution_block_hash: "0xdcf96433eba5c4c5877afce8ecd730c943b0b3b02c6b36593fda5839cc095d7d"
- execution_block_height: 51
-- deposit_data:
- pubkey: "0xae4d49364e4a36760cc74a675500055b9aed99bc19d31abb953ea156bb5a76dcf36769d15341b850114a30ffc8057780"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8fd33d2856c669b84efb3465006ba799fd3c680a56b104edc738107913fe0f91a6f99b7a69c337a493d8ea43791127211de5d964d1840fc403151a92d7b28cf8b141caa76807a06b673421effffa1d4e718ebe7fd27e59f1525126a01ab4bc4"
- deposit_data_root: "0x9330e615cf2658bb9b5039e5c6eea90714a76b3b8f3759dff1e295c364f695db"
- eth1_data:
- deposit_root: "0x0e258dde53879f7f68ee782954ca2b25d222447991919c685f637409175252be"
- deposit_count: "51"
- block_hash: "0x9678505c7aacb038cfe8edc0a224c5eb2d1abfdd5775bc6d6260189c247e3443"
- block_height: 52
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xe74828c6edb30e3e4bf54de63aeab6c3f97f7d6f3a558705eaedef064b8645ce"
- - "0x9330e615cf2658bb9b5039e5c6eea90714a76b3b8f3759dff1e295c364f695db"
- deposit_root: "0x0e258dde53879f7f68ee782954ca2b25d222447991919c685f637409175252be"
- deposit_count: 51
- execution_block_hash: "0x9678505c7aacb038cfe8edc0a224c5eb2d1abfdd5775bc6d6260189c247e3443"
- execution_block_height: 52
-- deposit_data:
- pubkey: "0xb397692ccbf442bfe078174c85dbad7fd605e4ff1caf2904b31e4a4c79d6444813ad9b2093ac8fbd4dd59ec7a4c8c006"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa10cd137f49972e2e2a053abc96a1e356a4a65b9beac4b910a867c5e150e77a8b66cf7e32dae3ddcc1be9643a1ed775d0e6ab93def5f8685f756a014d6d6b721ce5b7d17cc85d8fefdf89276bbf67cf0b5775ef535bdea61a5fbe40b32d318ae"
- deposit_data_root: "0x3170a57af6642be1e018dba7471b811acfb9ec1b9a66eddd3f28666e0001c492"
- eth1_data:
- deposit_root: "0x1b23c0123f7e5de30edcc56f34eef43f3dec1cee9374fc72a9f8d92b34111b1c"
- deposit_count: "52"
- block_hash: "0x2d4a16997b0e306d3e8f22dfd9b465ec6532273d54608973da7900e7223be426"
- block_height: 53
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0x7d1f34ae9db53b9a029e24b8d766e0e54a464ac4eade9210f96eb71d77dbe9c0"
- deposit_root: "0x1b23c0123f7e5de30edcc56f34eef43f3dec1cee9374fc72a9f8d92b34111b1c"
- deposit_count: 52
- execution_block_hash: "0x2d4a16997b0e306d3e8f22dfd9b465ec6532273d54608973da7900e7223be426"
- execution_block_height: 53
-- deposit_data:
- pubkey: "0x87c9f7605d07550b46c79add5ea4e39de5014c03833669257bd6666b7ec838f53800104779940d8cdd884275a0f6a3ef"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb6a8b8d4ea3c51c1e53f1eb8eaca900db9c70a2c7c11f555856b6aff737c972c9f5871bbc8fb46d6ca3f33b271c8a7e20976ca805666b41bbe38a576167466db0f8beaa28995aba1ff250fa3e4f87a0843d3941ff477528dc7daad37f5a720a1"
- deposit_data_root: "0x0c0f4d2950ee7d4b8062761154cfe0c1d6f13d9a4d5e2fef701ea38614add54b"
- eth1_data:
- deposit_root: "0x89aeb5a6e924afe40fa404ce4c31a09ad222c9f3dddfa1df9f4946ba81243754"
- deposit_count: "53"
- block_hash: "0x5279517c77c4fbf7e0c19cae59db917ff0ec55bc62ec2254df5cc945eb415daf"
- block_height: 54
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0x7d1f34ae9db53b9a029e24b8d766e0e54a464ac4eade9210f96eb71d77dbe9c0"
- - "0x0c0f4d2950ee7d4b8062761154cfe0c1d6f13d9a4d5e2fef701ea38614add54b"
- deposit_root: "0x89aeb5a6e924afe40fa404ce4c31a09ad222c9f3dddfa1df9f4946ba81243754"
- deposit_count: 53
- execution_block_hash: "0x5279517c77c4fbf7e0c19cae59db917ff0ec55bc62ec2254df5cc945eb415daf"
- execution_block_height: 54
-- deposit_data:
- pubkey: "0xb08f7feb86786c37661afb9951a959c9b465fd11ca98fcbc908fcf49144084051f6c363e2eb4459da2c2d03d84175692"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86fb9f4c6ca3c5453646471e6393f1260f04f25bae62541203f6dfbfaf226dee57b0b6a1b2d698d3630a4ae418f7986b0273299006e4488f835612311eccb1fecaf576e1740d29b0c26478ec11eaf644b3e3c696ebe562e6942d282bef29f82b"
- deposit_data_root: "0x04e2ccad9538abe82e053c1414dcd8083d20206e84a3ce294036e271bf391e7a"
- eth1_data:
- deposit_root: "0xd749a15bc781e795b4e88adce9dbd068f0350586391f8170e025a4a671c7be06"
- deposit_count: "54"
- block_hash: "0x7a5b1937cf1cf319c059b24ac4d7a905d841d3c725da9597f32cd609159f1e04"
- block_height: 55
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0x7d1f34ae9db53b9a029e24b8d766e0e54a464ac4eade9210f96eb71d77dbe9c0"
- - "0x45ae70157fb3f9a80f56cedf94dd1211a7bb8fe79527c7077097c766dc4fcc92"
- deposit_root: "0xd749a15bc781e795b4e88adce9dbd068f0350586391f8170e025a4a671c7be06"
- deposit_count: 54
- execution_block_hash: "0x7a5b1937cf1cf319c059b24ac4d7a905d841d3c725da9597f32cd609159f1e04"
- execution_block_height: 55
-- deposit_data:
- pubkey: "0xa48cc260df1df875176cb17493a5b53d669c091da74d5075acb8952a641b1b7ef68d01f009c1a365d2fa80937c79dd6b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3c12fa96e2938a28f872bdf1e62a037dcbe3d5fb0e7cee58bcd2d2c6d82ffdc6428a5ec997a8ae26d113f30959fddb407f319ef49f989fdee215aa96d2fcf30b6154590ee9f856daaccd20c344fa5d4b4cb6678a3409aa619af35bed6f5259e"
- deposit_data_root: "0xfefb7de90e7a23e87b7df79ef2b97df376a89aab301014112ce01f2362515d7e"
- eth1_data:
- deposit_root: "0x92e91d9cb729330a946dea613ffd50ed1911c3b7cdb92a7e400d486310a77c6a"
- deposit_count: "55"
- block_hash: "0xfb4bb38d9560af55e012e04dc652fe291826bbd4dd8fdc350300f9d97e463ec1"
- block_height: 56
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0x7d1f34ae9db53b9a029e24b8d766e0e54a464ac4eade9210f96eb71d77dbe9c0"
- - "0x45ae70157fb3f9a80f56cedf94dd1211a7bb8fe79527c7077097c766dc4fcc92"
- - "0xfefb7de90e7a23e87b7df79ef2b97df376a89aab301014112ce01f2362515d7e"
- deposit_root: "0x92e91d9cb729330a946dea613ffd50ed1911c3b7cdb92a7e400d486310a77c6a"
- deposit_count: 55
- execution_block_hash: "0xfb4bb38d9560af55e012e04dc652fe291826bbd4dd8fdc350300f9d97e463ec1"
- execution_block_height: 56
-- deposit_data:
- pubkey: "0xac9f4df3f20a16a9fefad08817fcbc9a6ee17f7512db006414b4aa6f234c2313585ef72c5776df55fa6284af4bc3f631"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa5d0be0b159b75f2524e1bc1243bb8f1272716daa2a1c635f0b34004b30d9038450cbd9b72f29a17d1fb4d99857fdbd710e2edb2036aa89589d1344b6e3984fbaa44ee0409fa048d0dd86aa1aa0164663b187e0ec9f798b490dc4b34b095152f"
- deposit_data_root: "0x5568cb23722d865d414baf5f7ee92234383e175fb3e5b7cae390244f9735987b"
- eth1_data:
- deposit_root: "0x565ce384ec4ca0d45ab8c20b895996f4dd15f01f00497b24cdaf6378602efed7"
- deposit_count: "56"
- block_hash: "0x13a0c8bcd47c1e4d208515dfb6e9773ee2d5f894691e7986bb8d8699f33d9495"
- block_height: 57
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- deposit_root: "0x565ce384ec4ca0d45ab8c20b895996f4dd15f01f00497b24cdaf6378602efed7"
- deposit_count: 56
- execution_block_hash: "0x13a0c8bcd47c1e4d208515dfb6e9773ee2d5f894691e7986bb8d8699f33d9495"
- execution_block_height: 57
-- deposit_data:
- pubkey: "0x94f0c8535601596eb2165adb28ebe495891a3e4ea77ef501e7790cccb281827d377a5a8d4c200e3595d3f38f8633b480"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x87d4271630df8e3780900e5171d3642a781205154f11be812e923c87d19a3224213b9dad62ed42f1126a0b52157afa9e16acfecf96c7f8c2345bc1f744e491136cb100d82f549467f595fa6393ff0f8d0dd83cf5c95d88c47d0023bf0796fd6f"
- deposit_data_root: "0x6adfa7ccc8b757b108c02b37ee27bc04e83e9c7538b1c07ebcf342d564c56135"
- eth1_data:
- deposit_root: "0x352eee8320a9c83dc4f9b5086b92df7ab3d1844f77cde7f3c3daf8905d91c4d0"
- deposit_count: "57"
- block_hash: "0x1023685ab1df034f7762e46035d995d87f972c29ffaa097a5b6301da756398cf"
- block_height: 58
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0x6adfa7ccc8b757b108c02b37ee27bc04e83e9c7538b1c07ebcf342d564c56135"
- deposit_root: "0x352eee8320a9c83dc4f9b5086b92df7ab3d1844f77cde7f3c3daf8905d91c4d0"
- deposit_count: 57
- execution_block_hash: "0x1023685ab1df034f7762e46035d995d87f972c29ffaa097a5b6301da756398cf"
- execution_block_height: 58
-- deposit_data:
- pubkey: "0xb5bb0162a4f27d1bab4c7dc3d20f5a75d6ee98c56bcd309a1f0f307685ad47ffb8a35bfdf8431b9b954b59662a74c478"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb091cd5476b2bceec9f6cba38b3787fb080d9ea63cd6ed19eebd72be7ab0887e44f233e993b9ded4fe33353a9aba5a9206b8a9da387d222e58bf05cf333b25f6559557cf95645c785c75683317a1c97dec807770e57d581107e9fbca03069eff"
- deposit_data_root: "0x9fad5a196b6ac7c47a1fd191fe4eac56bd9b9fed5d275ad0311e165059d7d40e"
- eth1_data:
- deposit_root: "0x349bbbc8e21e10251fcfceec3821ea9dd2806526e71fe472bb8b84d8d5458f5f"
- deposit_count: "58"
- block_hash: "0xdeaa8a27fbc74fcbda0b7a30da9c4e4392a9f961b90c45a272a204bbfb5d8d4e"
- block_height: 59
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0x2ef9c25463a9664b369b20321671d2fec217ea4c64ee3a714e5983a0be95acd0"
- deposit_root: "0x349bbbc8e21e10251fcfceec3821ea9dd2806526e71fe472bb8b84d8d5458f5f"
- deposit_count: 58
- execution_block_hash: "0xdeaa8a27fbc74fcbda0b7a30da9c4e4392a9f961b90c45a272a204bbfb5d8d4e"
- execution_block_height: 59
-- deposit_data:
- pubkey: "0x8826e820179fd321819e78ffee16f50ac528db2da71ad8c269f60b878bc4887c79c0545b3d750e86e490d5ba9083cb70"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x95622cabae0c3d62f58fba1302e207d5ce92aa3df653968f020dce42b84d49ac928f7ebce159b2b5fa55115bcd0895820269879dd4ebea6359d5c9d8b9c209cac6891552985da1e64a60e6b0959b2bf0ed81d97381ef9b1e0aa59217e9dbd280"
- deposit_data_root: "0x80ecb93497e9a21c4e6d48528adc8d32ec4808a275fcdb2ecab6fc052e6936a3"
- eth1_data:
- deposit_root: "0x56f2b33a48de69dc2f0652bb1d6d4a63de86b9db2319b51f59f93225d93787e8"
- deposit_count: "59"
- block_hash: "0xecfb4b768d48d31ac3d30f640d00d0afb9c932ba7316c9f21ede2ece7e4a65c1"
- block_height: 60
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0x2ef9c25463a9664b369b20321671d2fec217ea4c64ee3a714e5983a0be95acd0"
- - "0x80ecb93497e9a21c4e6d48528adc8d32ec4808a275fcdb2ecab6fc052e6936a3"
- deposit_root: "0x56f2b33a48de69dc2f0652bb1d6d4a63de86b9db2319b51f59f93225d93787e8"
- deposit_count: 59
- execution_block_hash: "0xecfb4b768d48d31ac3d30f640d00d0afb9c932ba7316c9f21ede2ece7e4a65c1"
- execution_block_height: 60
-- deposit_data:
- pubkey: "0x92977e71396633d442f61e16a0cfcf8ffad0af93c9f1b7fdf4f7ccb816de052925fc192922d6252d325ef9fa2e0595d2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8645569a7d2c3a844a0215c163fb2e247b4201161e2399f213c0985b568ac98961398f0c712c05892857cddf384a12e007ad9412dbbc26b18b7e76b9a5d5735db8dd0142e879b7b46f8d42dc05be19ec9cc9bd42b741cffbbc250d576f86232f"
- deposit_data_root: "0xb4fc5adc460335413f7ddc9f38007ca12c841212a86961b3190b566e371b6fcd"
- eth1_data:
- deposit_root: "0x2badea58e40583186b7ad89ed366eb9fe85cd849309ca43bf5f4703b45c7c9bd"
- deposit_count: "60"
- block_hash: "0xb6a0eed143a5b2bd2ccace6a5f28ec0b9ef819eb82a781b12f82ff9e717077c7"
- block_height: 61
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0xc7acab11e9b20b4a85bafee152a8fc5314df74b63c324dd84a917f89c3c5bf0a"
- deposit_root: "0x2badea58e40583186b7ad89ed366eb9fe85cd849309ca43bf5f4703b45c7c9bd"
- deposit_count: 60
- execution_block_hash: "0xb6a0eed143a5b2bd2ccace6a5f28ec0b9ef819eb82a781b12f82ff9e717077c7"
- execution_block_height: 61
-- deposit_data:
- pubkey: "0x91ae4686b0d20470409f020eaca826c3efc6c1926ed25d05e6f0f7916391ec89c2341917277c437ac8fffffe94b68111"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa88873293cce3d3e180c98a6e973057873578ee51480e5d2a821c6137aa143ab8ccf64dcb131013b6203fdbbbb848efe015949a431ff7b401b131ab6d33ce9dcc698c00e3503c5cd98d935d2040952dc9a863fa7e8ff60e52088ae198773b740"
- deposit_data_root: "0x75dac1ed3a104cdfa3e93c4b91e85ff6bd7a309a3f881fedf48219657ba71993"
- eth1_data:
- deposit_root: "0x243b61a30048fd9847aa0c1424feffee5876462556952e6120800137cdfca8cc"
- deposit_count: "61"
- block_hash: "0x3febb45aaa3b77bf4190c51f349ae02ab28df9c090a727294f2d6850feaf71fd"
- block_height: 62
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0xc7acab11e9b20b4a85bafee152a8fc5314df74b63c324dd84a917f89c3c5bf0a"
- - "0x75dac1ed3a104cdfa3e93c4b91e85ff6bd7a309a3f881fedf48219657ba71993"
- deposit_root: "0x243b61a30048fd9847aa0c1424feffee5876462556952e6120800137cdfca8cc"
- deposit_count: 61
- execution_block_hash: "0x3febb45aaa3b77bf4190c51f349ae02ab28df9c090a727294f2d6850feaf71fd"
- execution_block_height: 62
-- deposit_data:
- pubkey: "0x8a0d241955104bedacb3b829162f2b457915c2beb9018ede8ef8ea80f401b471c42354358da9e62b51c38d54263a78a9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa073c1da30c9555dde136f86879936cbf247828ad39b688058b8dad95781651379dfce772fb5aa93d60e50d0d2374ada00e3ebc42e2b1d732512f990dafa34dc7dd1553bff38a171b06f0b215f40bcf5fb354d914bb595acb8dc49d042896ff7"
- deposit_data_root: "0x3274fb1171cb037b6242c298f1680eaf23f01ef807669e9b00f65eafe0640a1a"
- eth1_data:
- deposit_root: "0x52e5a1f96b0f8c69423bfbeb7ed3888cfb9c9098eafd0eeb14a9a8c21d77d245"
- deposit_count: "62"
- block_hash: "0x8fbc1f4ff163d89df6143c66f1df08196d0313df09ff0b062925ec33e48415bf"
- block_height: 63
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0xc7acab11e9b20b4a85bafee152a8fc5314df74b63c324dd84a917f89c3c5bf0a"
- - "0x997db7123f404f063da7db4a2d3952d11f30820ec8445b5da03eccfde69e946f"
- deposit_root: "0x52e5a1f96b0f8c69423bfbeb7ed3888cfb9c9098eafd0eeb14a9a8c21d77d245"
- deposit_count: 62
- execution_block_hash: "0x8fbc1f4ff163d89df6143c66f1df08196d0313df09ff0b062925ec33e48415bf"
- execution_block_height: 63
-- deposit_data:
- pubkey: "0x80a2be2c7dbce8ddc2eba03522697587c375a5a9e92d4b31ed9e3c34bee047095d93e3c70b1662b3faa301f5b19978e5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81e2f7ffe007e2d6b121ec976d7a9d3cd053d82cf07f2411184522664755306185dbb3352c5bd7e83154fafb34a56f2601c164f280e447e64655ba7e9457f5967f15eb4d6080af7ef971b9067a498266fb3afd979a251169402cb4d80205b9e0"
- deposit_data_root: "0x75169d67108dcd4c68492847c39c0f7b24ecbb2a0240e62dd5f72518e142df11"
- eth1_data:
- deposit_root: "0x8ffd6666bccbb0269e2df5e53b91844c9bdbac57d3089d6d9a4d91c1963a61c9"
- deposit_count: "63"
- block_hash: "0x4d7818aafb46a6f055359d6d7c664c3b36599a2dcab8cf332ff896345bc0cab1"
- block_height: 64
- snapshot:
- finalized:
- - "0x378775a69829a0b8467bf331f4815d2ab91c796f5eb14cd9c08347421a245f2f"
- - "0xdb1b9444d0f397f37f74bfcd3cc45beb343c4fe728174c624eaeb3647745b17b"
- - "0xcc3b81ef99612124c28a53fdad6aef205b53c82843c080b9f269b80313fe7481"
- - "0xc7acab11e9b20b4a85bafee152a8fc5314df74b63c324dd84a917f89c3c5bf0a"
- - "0x997db7123f404f063da7db4a2d3952d11f30820ec8445b5da03eccfde69e946f"
- - "0x75169d67108dcd4c68492847c39c0f7b24ecbb2a0240e62dd5f72518e142df11"
- deposit_root: "0x8ffd6666bccbb0269e2df5e53b91844c9bdbac57d3089d6d9a4d91c1963a61c9"
- deposit_count: 63
- execution_block_hash: "0x4d7818aafb46a6f055359d6d7c664c3b36599a2dcab8cf332ff896345bc0cab1"
- execution_block_height: 64
-- deposit_data:
- pubkey: "0x86a73886aa0114bbdbba346cb7c07376c81b549a4802c24d98ebbc54a6a1b5d2ac874ef657cfb27c3644fcb85f97a2b5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb697a8a9e4d724302efb08e88ec4308b803fe8544cd5d53324dce4b601a18a66fd612318734d520d5909051f62e9e9e90823a7bcb951c2b5b9d349f0c5b57ff748ec93a1750df96e212f39900eac541d0753683d46a375a421300c0434c3fa88"
- deposit_data_root: "0x1418de3c263fa52285b93a809f16134cf4e008bebd2d81da7eb7d6f2a22c61a2"
- eth1_data:
- deposit_root: "0x5c7e3d0e9ac6cd2613e89748ec650d1ec5d44bf936c7761a0f5fc9526f263e17"
- deposit_count: "64"
- block_hash: "0xab873b4514bca399da91a00dc630df65bf37f53517b54c075f2f40a01e47661c"
- block_height: 65
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- deposit_root: "0x5c7e3d0e9ac6cd2613e89748ec650d1ec5d44bf936c7761a0f5fc9526f263e17"
- deposit_count: 64
- execution_block_hash: "0xab873b4514bca399da91a00dc630df65bf37f53517b54c075f2f40a01e47661c"
- execution_block_height: 65
-- deposit_data:
- pubkey: "0xa98c264dfc3bc3ed635df5dbfd54909e77600cd68480ec201d9f5c416580591daaa9735b04743e10e7fc6370a8189775"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa946b360375c6dea0c890263ccdefeb4f4a815bea7ebb6513de80f7932fb34ed36f3d5e41f26a9ef1550531d7ae807cc1094b7b5cdf2682ca713658ee8ffe4de45a0a20d8ea3a10b141e4d831030339e78936f04363529be77fcee46d4a9642a"
- deposit_data_root: "0xb484b20a0bc7eb410b062c857ecce9460c3aa86b2b81133ef727507bb60c6f9e"
- eth1_data:
- deposit_root: "0x5744f4e817aaa5221b70a045adde9f74069f40880a4646630c0417afc759a267"
- deposit_count: "65"
- block_hash: "0x9f358a6ec47032ba2fd6e11f79da1ef89cde8d1cdfdc3f8f21006fc056a1ad61"
- block_height: 66
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xb484b20a0bc7eb410b062c857ecce9460c3aa86b2b81133ef727507bb60c6f9e"
- deposit_root: "0x5744f4e817aaa5221b70a045adde9f74069f40880a4646630c0417afc759a267"
- deposit_count: 65
- execution_block_hash: "0x9f358a6ec47032ba2fd6e11f79da1ef89cde8d1cdfdc3f8f21006fc056a1ad61"
- execution_block_height: 66
-- deposit_data:
- pubkey: "0x8bb7aa61aa8bbd2b7825d28c340da89b625381232dcf2742276b4e3a2e4a0f42ef68794fdf005d94014636732fba2f40"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8adda613ebf39f91333958b18dfb271b5b75d97342a9447e5371e31af7fdbec354687868cbf1f2e57a71c3aee43e623f0a6161ff94eebb064cf57aec311e0f638b24b864c1433622b5236e5d33e410626c34784e8409a90bcf855192fc1ae0b5"
- deposit_data_root: "0xebac12ca39e81dcea9e7c2de29be0ffed4b4b560c5cf4539f3c3d7789ddf03df"
- eth1_data:
- deposit_root: "0xce3f915b2665672a9e96e35249fd4a07a0ff010b8f455995fb4d9d4d383d5921"
- deposit_count: "66"
- block_hash: "0x4fe81ed058f82fd3308a29454b21d44d977963ab016f3aa161803a909fe20768"
- block_height: 67
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xb74da2b05b56d5a84748b4616151668e0b0bf38c880acdbe71451e62bd7306f9"
- deposit_root: "0xce3f915b2665672a9e96e35249fd4a07a0ff010b8f455995fb4d9d4d383d5921"
- deposit_count: 66
- execution_block_hash: "0x4fe81ed058f82fd3308a29454b21d44d977963ab016f3aa161803a909fe20768"
- execution_block_height: 67
-- deposit_data:
- pubkey: "0x8bb9e1693eab1496d7583bf22fb1f2a475934c63b4d94118940617aa187bc277f738223e0ec1ce8a5566035d9bcc5470"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb00b5a95db40dd1b1bdbd364519b03447ed232d3c88dfad68203892523509831131f21b819260be2554d0e627f113f831477f83c9fc1948a451f4dab078c05376608168964fda9b8d033f8768f008fa1db2d0c61c47a9adb3812ef5e25f42889"
- deposit_data_root: "0xedbc4b624f488b096f5cce8386dc735682a0d890193dddc47273a3f8e9587c4f"
- eth1_data:
- deposit_root: "0x8039f6582e426da6ad47fa64f2b0c5927b11f9980914d12174d0d4c883ab1c21"
- deposit_count: "67"
- block_hash: "0x3dbbf6de20c3b31947160ee99b05fca4cb77b35ef72f7bd5ef183b57dde0f4bd"
- block_height: 68
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xb74da2b05b56d5a84748b4616151668e0b0bf38c880acdbe71451e62bd7306f9"
- - "0xedbc4b624f488b096f5cce8386dc735682a0d890193dddc47273a3f8e9587c4f"
- deposit_root: "0x8039f6582e426da6ad47fa64f2b0c5927b11f9980914d12174d0d4c883ab1c21"
- deposit_count: 67
- execution_block_hash: "0x3dbbf6de20c3b31947160ee99b05fca4cb77b35ef72f7bd5ef183b57dde0f4bd"
- execution_block_height: 68
-- deposit_data:
- pubkey: "0xafe6eface52fb6de91055a81abf9aa6e42ce2ef36fd8ae0d09aec6e5d8bd40a065dfccda6104af94df3f7a5854559ef4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x966e020128302f799fa32f954776a47b6e40fbf346c8055427254918a88c39609ead584b770a03a4425dfcf57fd79aff17f0ac1e364a383823fef8a7aaa06d3a252c6c8843ab9bd156bbb5ce8ecb542c5459c9d587e5e29e90f640c8fb1a16bb"
- deposit_data_root: "0x678f9a3c3a59f9118d5f278fefa238950ea26786faaf42d3d17096c81c89a78e"
- eth1_data:
- deposit_root: "0x4e422cc0aaad3a3a9f4e415a68f1286df79ea6a95326f73b6822bad8eeae6508"
- deposit_count: "68"
- block_hash: "0x64bb0a98a090f4763a6709b870b3366512db0c089547e1d2bfdefb531e7d08ba"
- block_height: 69
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x59fc60d715f9f381f553928b5bab510c59f2b5763bc27115827930abc8fa06e1"
- deposit_root: "0x4e422cc0aaad3a3a9f4e415a68f1286df79ea6a95326f73b6822bad8eeae6508"
- deposit_count: 68
- execution_block_hash: "0x64bb0a98a090f4763a6709b870b3366512db0c089547e1d2bfdefb531e7d08ba"
- execution_block_height: 69
-- deposit_data:
- pubkey: "0xaa241b2afbb33f92a5d281aec9c8bac8997c1dddc051455fc0f334de48320f160b5029b552495aed21ed9ce252aab499"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96e8e6ad4c9339471b4133f16fa80c48183a4bb54ae9f7097766112005375693dcbc459050d4a20a88a4d72601ea171402dbb3b934fecfc4e90c8aa8d9a20818086b126f0c72bf8eff58008aabec8834f8b252660289b818c1724b8fe6f75fbb"
- deposit_data_root: "0x27dfc1b46bf479c37bdfd8fdd34ab1f760dd118b031edd608a5b09e217f67bc1"
- eth1_data:
- deposit_root: "0x1878ee9b4d268fd60d60bbfa65e807f1e45331dfb13dcacc489de9dfc27f4a23"
- deposit_count: "69"
- block_hash: "0x899a35f3d719b2eb46085aea5820429a4ea164cc9092f096418df37fc8d5b3c4"
- block_height: 70
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x59fc60d715f9f381f553928b5bab510c59f2b5763bc27115827930abc8fa06e1"
- - "0x27dfc1b46bf479c37bdfd8fdd34ab1f760dd118b031edd608a5b09e217f67bc1"
- deposit_root: "0x1878ee9b4d268fd60d60bbfa65e807f1e45331dfb13dcacc489de9dfc27f4a23"
- deposit_count: 69
- execution_block_hash: "0x899a35f3d719b2eb46085aea5820429a4ea164cc9092f096418df37fc8d5b3c4"
- execution_block_height: 70
-- deposit_data:
- pubkey: "0x974b2aed17665e51c1c091998ca9649875330947de3d2733a5bd2eda69b0c593cdac2e416993a87f9a17aec1ccdc2368"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9695b7d689cb75c10edc7a6e7b9e03b802ed7e9256d589a7f5f2d192454a4b58000972109d812ca067b62caace91281714a783bcd8233414a5ca9abd3ff3e8b59d51b383079a61e3a5f9529f279d9e1f4fd818ad3daea046e883a9c0bbdd1b6c"
- deposit_data_root: "0xa827f1f12751ca75d95a814694177e948d61bb11d675d3730f8cdc8889329c71"
- eth1_data:
- deposit_root: "0x93fe27d7e2eb9366225f56a794563f4dfcf3696253dc58eb25eb54d0c0eb9def"
- deposit_count: "70"
- block_hash: "0x1ba29709a4d5765dd8ffdee19aa7407fd25c7173a3f71e5c7920f3f5ca941b49"
- block_height: 71
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x59fc60d715f9f381f553928b5bab510c59f2b5763bc27115827930abc8fa06e1"
- - "0xee50b240458527c727db7672bbeebac6a3d40f017fabafb80c39bc12ad50df21"
- deposit_root: "0x93fe27d7e2eb9366225f56a794563f4dfcf3696253dc58eb25eb54d0c0eb9def"
- deposit_count: 70
- execution_block_hash: "0x1ba29709a4d5765dd8ffdee19aa7407fd25c7173a3f71e5c7920f3f5ca941b49"
- execution_block_height: 71
-- deposit_data:
- pubkey: "0xa3177a98f653cea646f525f0f13348efb27e0d3d0cd824704c91d8d959096d259c9e577298f444acc629920c9619be50"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9985fe391e73d35c8044754de668b3113d8c341bcb04acbd6eddf8b683ea0fe5dc163b434243cb6ff5588a2d4146b1151851bd39edfe532a31a3b81afc644f3ae781ff2f6e73bca955fe47fa4029f8759ab2a6784e1eade8f34c97223bab6af2"
- deposit_data_root: "0x679b8078ff958c2a06ded461b6891f5a8038dc16adc475ba5867998a7d14adfa"
- eth1_data:
- deposit_root: "0x5173afe39bf20d7f26ab0d805059f50e0024f037cbc446e12171978d8d87e863"
- deposit_count: "71"
- block_hash: "0x7ed23cf2347fbaf8084d0c9b4acd2a88a5b793a68c7dd50d00627d4d6ad91457"
- block_height: 72
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x59fc60d715f9f381f553928b5bab510c59f2b5763bc27115827930abc8fa06e1"
- - "0xee50b240458527c727db7672bbeebac6a3d40f017fabafb80c39bc12ad50df21"
- - "0x679b8078ff958c2a06ded461b6891f5a8038dc16adc475ba5867998a7d14adfa"
- deposit_root: "0x5173afe39bf20d7f26ab0d805059f50e0024f037cbc446e12171978d8d87e863"
- deposit_count: 71
- execution_block_hash: "0x7ed23cf2347fbaf8084d0c9b4acd2a88a5b793a68c7dd50d00627d4d6ad91457"
- execution_block_height: 72
-- deposit_data:
- pubkey: "0xa8a18565733e70663c77bc0c80e08f50de908cc048152f1e7dae85d8cc218afbdd337d7d33a44e25400be2f06907c64a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x905cb27fd1bed206b261cb543ffd3fbed57f5b9d938c4dc488e1bd34d198395bbaf1237cf183cc73f5c8e2e31d20d4c40e191278661c85adfb507024b5e9a5dc3ebbed92e8aaa85c0cfc6df6b05375c26b2f49a8f695ac156bff342bf16fc4cc"
- deposit_data_root: "0x8bc78f4a029e716370a431e7034b9fa1991e36246d00fbf41a1dfeaba5748f67"
- eth1_data:
- deposit_root: "0xd09cddcb5675f6c5affff8a42f1fe425994bbe9133443d3f5516f8b34a9d0ba9"
- deposit_count: "72"
- block_hash: "0x16925bb1988c358148331ce34f247a985c829d8c14bed9481998942083cfe783"
- block_height: 73
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- deposit_root: "0xd09cddcb5675f6c5affff8a42f1fe425994bbe9133443d3f5516f8b34a9d0ba9"
- deposit_count: 72
- execution_block_hash: "0x16925bb1988c358148331ce34f247a985c829d8c14bed9481998942083cfe783"
- execution_block_height: 73
-- deposit_data:
- pubkey: "0x902ff56a7a4c5b6cc57708ea7b0b72cb54e4b821c95373f503648185f15208f6ca6281677fa0ecc14f911d7b7ca04f4e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84b716bac859e61b80e0cfd3fc484d59c2865794d11e3264d58d6c4d2af2e2eef12a94944f331a4b3c83221a5d1fba2e10fa236515db3d9eaf92c4ff9c118cf73f0cb59b4c7b14f253e7c7b7b2cd0d23f659c24bd4f37a99ac82bed18c56e8cb"
- deposit_data_root: "0xa23bbf261e1427b5532adfeba387f89d35f66f776af44be7f183d06af0e55828"
- eth1_data:
- deposit_root: "0x44c70c125786b9ab6f938ecab3227d21da2ed26f1a1677f8f78e4058dc721403"
- deposit_count: "73"
- block_hash: "0x869606a66fc329f9076cc7257a61018e04b6a6c658298c65de81f67bf6990a4c"
- block_height: 74
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0xa23bbf261e1427b5532adfeba387f89d35f66f776af44be7f183d06af0e55828"
- deposit_root: "0x44c70c125786b9ab6f938ecab3227d21da2ed26f1a1677f8f78e4058dc721403"
- deposit_count: 73
- execution_block_hash: "0x869606a66fc329f9076cc7257a61018e04b6a6c658298c65de81f67bf6990a4c"
- execution_block_height: 74
-- deposit_data:
- pubkey: "0x98f011f9a4dff94eb0352ff6e21b7df45e2a112bd5d789b5729111b89b368e7ed554e4d1c16b72f4d105090173cafed2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89641c38182c333a0485aeb0c4eb6f399a3581d19b33370522623d4c827de1cd5dc79c510a7e5bcd33f4d7a12bc6ef101630d2e4bfdf28c89b974c3927c314d118a345a3c424d0b3680c2de454e0e95f1d9c96565c2a7d771af7e8baddd25f02"
- deposit_data_root: "0x65569e8f6db92744dd0abfbbc30a083986f842aa23cc02408099f2b586a3ed1d"
- eth1_data:
- deposit_root: "0x727ba31c7148e93fea338887cb4cc053a8eaa60dbd3dfc15607e837a845b38e8"
- deposit_count: "74"
- block_hash: "0xa68c064f8ee59d1857ae8a3a8eea5b59bce083fcde164fed763ac2ab30e51f90"
- block_height: 75
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0x8b4eb1bbcf79beaf6350d27870239dac66f0155fb7f8807a1f2b96afbba18f03"
- deposit_root: "0x727ba31c7148e93fea338887cb4cc053a8eaa60dbd3dfc15607e837a845b38e8"
- deposit_count: 74
- execution_block_hash: "0xa68c064f8ee59d1857ae8a3a8eea5b59bce083fcde164fed763ac2ab30e51f90"
- execution_block_height: 75
-- deposit_data:
- pubkey: "0xabef42538a17a55804b634aac9d211b92b5768c4cc1263342ca287323bb3d5c768080451d1b5d652e9f8646fbb35f57c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7bc665e4424cf5e48e6b1dcc5f9d85e9f44ccb12690969a548fc0835b2fcdb6d587c997696e19fdc16ecb8c9b8a9d4810795c716232c2a2839845cabb70ff78aedab16d3ae55751c4b75a64dcbd5b630b652308300313457176c99889436d94"
- deposit_data_root: "0x2da83bfca1b961cbe477157ccb844db21392e1fb44822b1b330c686984e85586"
- eth1_data:
- deposit_root: "0xc7a1f21839a10b008b4503cfd0e8f57dc67b83642e8ed9aa1d9f042821f22b01"
- deposit_count: "75"
- block_hash: "0xf7b4c7f12fe8c83d3546300a2bbf4a01034fc10eaf79295db8dc9e1b36c9a20e"
- block_height: 76
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0x8b4eb1bbcf79beaf6350d27870239dac66f0155fb7f8807a1f2b96afbba18f03"
- - "0x2da83bfca1b961cbe477157ccb844db21392e1fb44822b1b330c686984e85586"
- deposit_root: "0xc7a1f21839a10b008b4503cfd0e8f57dc67b83642e8ed9aa1d9f042821f22b01"
- deposit_count: 75
- execution_block_hash: "0xf7b4c7f12fe8c83d3546300a2bbf4a01034fc10eaf79295db8dc9e1b36c9a20e"
- execution_block_height: 76
-- deposit_data:
- pubkey: "0xa8e3c2d3ac4e0e3c83380577ff7b7b5b2a98571e0d04ddebc0a6c472ce3bc5cc6a6733be728a0ee17da74b7691d2679d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2719b1ed9259b55d519158388e8cfd749a186c6247c2a637848e133d761ad6b105e27d3f1a950455d8abaaccb756e6016c838c3ed0abbb9a0bc966ef6f58e681d232cedd792c2b19cb3d17a5240a16b97c62ce29682c078131b67143878d02f"
- deposit_data_root: "0xbd2182e7a29009df9034c125e8e09f7f6e3b862944aab607f84d64545ab002e4"
- eth1_data:
- deposit_root: "0xee5ee677dd7394ae7c9548383112262e9af48b1f84a109a1e42ca1a1fc57e527"
- deposit_count: "76"
- block_hash: "0xdd2ed41e4e3336c4afb390d9c8572db1a2d5d403b470eb88a3a85df3bbbd107f"
- block_height: 77
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0xee021dc6246d96e341b4df28f5db26a62e2d9716eb92394f5bd7fa7e246fa85e"
- deposit_root: "0xee5ee677dd7394ae7c9548383112262e9af48b1f84a109a1e42ca1a1fc57e527"
- deposit_count: 76
- execution_block_hash: "0xdd2ed41e4e3336c4afb390d9c8572db1a2d5d403b470eb88a3a85df3bbbd107f"
- execution_block_height: 77
-- deposit_data:
- pubkey: "0x98f620aadc4e58392b5b583fed96c452b54c39ba3a9fe8c277f625fae7e1317d034f732995fd88c1461463edd0f2b86d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xabd8b07d34a93e4dc68fe6115af72218e56ad477e848d0d1036114aee03cba10ab561d1570bae237d94ff4d6aa029c760cf2ceda174bbce181ca2e9ede9b7f6a466d2e2d4a38b7367124bc70c887b69770938d3f82c7263b70d0ab960438afa8"
- deposit_data_root: "0xdaa5f5480bd46b815e89b67e6ccb84dab0b44ccdc687017785f0b26647eb2da9"
- eth1_data:
- deposit_root: "0x85ee92997d8c724afd6bfd6078f6b2fa8aacf96a8e98018ea21832f3b4df7d56"
- deposit_count: "77"
- block_hash: "0xf3f609e1b0e8c5ce0c404929cf2146d97e053f2a7c4dc186701fca3c81c79424"
- block_height: 78
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0xee021dc6246d96e341b4df28f5db26a62e2d9716eb92394f5bd7fa7e246fa85e"
- - "0xdaa5f5480bd46b815e89b67e6ccb84dab0b44ccdc687017785f0b26647eb2da9"
- deposit_root: "0x85ee92997d8c724afd6bfd6078f6b2fa8aacf96a8e98018ea21832f3b4df7d56"
- deposit_count: 77
- execution_block_hash: "0xf3f609e1b0e8c5ce0c404929cf2146d97e053f2a7c4dc186701fca3c81c79424"
- execution_block_height: 78
-- deposit_data:
- pubkey: "0xa7f5d408af436d71ec7acfe9a4592679649d326c00ac92c6f3332423be30c3601d232f265078f1f2a5d6d6cde08de7d7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3b301cd266d7dd40fed80f8f1609ca35256d263b00b16eed767dfe5ea8116eef1f6cb7f25028c98a9b28357b56ae1890b418858a4500034887ef60b7cf0f8b0f7a8718d450687316f7397632a3c167ecdb2db26694a8608ae06b0dc782e9c7b"
- deposit_data_root: "0x19f237b217967fe4d2ddbc826bf6e2c33687cea82a120e7b85e412d7e137d579"
- eth1_data:
- deposit_root: "0x5ad46efc2ae1bd120b59461c83d8799b741ad5000b754d6f9c20de9115890054"
- deposit_count: "78"
- block_hash: "0xbf4d50dea5661ab07e15967d8fa2c51cc55395749405ccb6a252ee68f8be1e01"
- block_height: 79
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0xee021dc6246d96e341b4df28f5db26a62e2d9716eb92394f5bd7fa7e246fa85e"
- - "0x1d7bb861e983c4afb9abbd3c0f7546b0b8e381c2d7679f6993d4ef95f55f8127"
- deposit_root: "0x5ad46efc2ae1bd120b59461c83d8799b741ad5000b754d6f9c20de9115890054"
- deposit_count: 78
- execution_block_hash: "0xbf4d50dea5661ab07e15967d8fa2c51cc55395749405ccb6a252ee68f8be1e01"
- execution_block_height: 79
-- deposit_data:
- pubkey: "0xa8be337b3d0e6be415dcb037b246831f9966aacef62b69d6b609e4ff8208bc536c6473bc9fe9e3bec9a8665c8caa05c5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac120d0e117e12d4af2ed041f4f7bac11ccafbdfdc4047808b83defc328196994afab43ec6581e6e88ce3eade65dab2a11618290151258cfb017fe15ea630f10d3c388c8b8e86a391a82f34c58974509e1b476876bba5b9d5f2c2a6b4682418d"
- deposit_data_root: "0xaf7bcef44525d9887a3a9982947bcf876e369190201ca2ea096bedf13edf353f"
- eth1_data:
- deposit_root: "0x8949d7d74a871960abf40a678878aa93c2d2a3e38bb9fcc9a055d19f434d9cbc"
- deposit_count: "79"
- block_hash: "0x881de104237f77e44ad277325f56e42735a577d9ea660124ecb08597585991ee"
- block_height: 80
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0xa1e9ca708d13a0c759703ba39fd1bcb39b5114273ca6dfff1e76d5c2c687b2c9"
- - "0xee021dc6246d96e341b4df28f5db26a62e2d9716eb92394f5bd7fa7e246fa85e"
- - "0x1d7bb861e983c4afb9abbd3c0f7546b0b8e381c2d7679f6993d4ef95f55f8127"
- - "0xaf7bcef44525d9887a3a9982947bcf876e369190201ca2ea096bedf13edf353f"
- deposit_root: "0x8949d7d74a871960abf40a678878aa93c2d2a3e38bb9fcc9a055d19f434d9cbc"
- deposit_count: 79
- execution_block_hash: "0x881de104237f77e44ad277325f56e42735a577d9ea660124ecb08597585991ee"
- execution_block_height: 80
-- deposit_data:
- pubkey: "0x93bb1c86717fa7303f65cb8c45c9fcc8fecb88428b7cd1dd59967a132109c25ab5c97888e46c5d471ff911c573f45a34"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb4ac35f3fb67d9a5ee84dbafbbe9fc2cc173b4198d3369a3ea40b745ff645c269ab3e8742b4033763d59aa88042ed040189f8093e55e38d0e202093c73bf469a35af5a340647247ce3377b213c6b2505bba028436173fd09ee845305a906af95"
- deposit_data_root: "0x65440def2a2b71e4e27356ec9dc2a661d5f937f8f0543a8e76c7a8dcb7d8e500"
- eth1_data:
- deposit_root: "0x2a8a1fb507e33b36be62ba505ce068295dbf1d40538474fb1446b02643b8dd4f"
- deposit_count: "80"
- block_hash: "0x53a3edf49a1a316d10285385209c510be04cde3a50f816beeb5da44196e426ac"
- block_height: 81
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- deposit_root: "0x2a8a1fb507e33b36be62ba505ce068295dbf1d40538474fb1446b02643b8dd4f"
- deposit_count: 80
- execution_block_hash: "0x53a3edf49a1a316d10285385209c510be04cde3a50f816beeb5da44196e426ac"
- execution_block_height: 81
-- deposit_data:
- pubkey: "0x815042c33c1a43c1ee58a58ee074bc93a13c23a035dedee6879730220379d0c03ff4a3829240b6c34e56feb55cd322df"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x951ce0fb4767567fdc4ac1c2b999d39624eb1915b3f74939685a99a30b99212f57eb17b163e3544d1524ada89d3d4fc9195163d5877a53b1d62fa210327eddb6b42150527df562ac5a67a0de3e59e3696a129c3c71c21240b584fe60cae66142"
- deposit_data_root: "0x6a9f3213a02e902c041ba8261f093e6c100dceca1ce46fc91420ca0c0a900f20"
- eth1_data:
- deposit_root: "0xcec66765569321e99f2a977b9ea2864097333eed6bc258e903142b60a8605ea8"
- deposit_count: "81"
- block_hash: "0x4a84e0118e1e4ec671bc23c123591f08b2ad83363a68941d1fcc2073a50d715f"
- block_height: 82
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0x6a9f3213a02e902c041ba8261f093e6c100dceca1ce46fc91420ca0c0a900f20"
- deposit_root: "0xcec66765569321e99f2a977b9ea2864097333eed6bc258e903142b60a8605ea8"
- deposit_count: 81
- execution_block_hash: "0x4a84e0118e1e4ec671bc23c123591f08b2ad83363a68941d1fcc2073a50d715f"
- execution_block_height: 82
-- deposit_data:
- pubkey: "0x8be11e9ead2e1bb5be7e2ec066ff83589558a5d9373666b3fc518a6a6639b3baecb87f8f34895f63e8d09d270d93ce04"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a9863487be81d3b7a8fb0ce2d141843c43751e3f030529f2cd271968671da68c520bf86e8ad56786cf4df9023bd80380bbe0bf6eea87b99a2dc70d3de0d4bb1507fd4fb8f3aca17ac37b71bb11c0cb003cea26a38fd84a2da2e6a9922ef8472"
- deposit_data_root: "0x27dc8639ac98670dc00960901ffe78d2ac05ef71bebf1734b839f89f24137300"
- eth1_data:
- deposit_root: "0xf34475554a62ca5b35a9a0c54a8abab231ae1f7db3098144154435c6d5d51d23"
- deposit_count: "82"
- block_hash: "0xdc459617e7f73073e5134da264c9ddad3ea4fed09245b90f13ba139a899bbb85"
- block_height: 83
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe1af0aab0c08eb08233a563ec4bff65ad501d92c9a40ce2dc785d145c76117b2"
- deposit_root: "0xf34475554a62ca5b35a9a0c54a8abab231ae1f7db3098144154435c6d5d51d23"
- deposit_count: 82
- execution_block_hash: "0xdc459617e7f73073e5134da264c9ddad3ea4fed09245b90f13ba139a899bbb85"
- execution_block_height: 83
-- deposit_data:
- pubkey: "0x8bf2630491d2a480ec243b00d65d76e69615e67d3df5d8c14ca7506edd8e896a9083e8ee9e4129af0f6d896a3225c08c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa12d975029e83dba3b911bea41a5f1090fbd2129472a2244171f57ad1fe0f44043d36cd99501aade7f9ed8ce2b36b567025b63e075edf6ebfa4ea3b262ada83fa8872244bb5fcd4f61faf576bfd704bbbf7c1729610a10f1b316a2edcab8f2a1"
- deposit_data_root: "0x1657e7e852988d74eadcdd365213af142142f68dfb32ae071af7b9640a7b1724"
- eth1_data:
- deposit_root: "0xfcaec4c59f62d7cb9fdc1539228db986aaeaf6ce6182e9356d0d7ac9554cc5b7"
- deposit_count: "83"
- block_hash: "0x1b1fcd8f43efc0746a5c9a5e6069bcad198f4fb06ea4aa27fb2099886f74ea92"
- block_height: 84
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe1af0aab0c08eb08233a563ec4bff65ad501d92c9a40ce2dc785d145c76117b2"
- - "0x1657e7e852988d74eadcdd365213af142142f68dfb32ae071af7b9640a7b1724"
- deposit_root: "0xfcaec4c59f62d7cb9fdc1539228db986aaeaf6ce6182e9356d0d7ac9554cc5b7"
- deposit_count: 83
- execution_block_hash: "0x1b1fcd8f43efc0746a5c9a5e6069bcad198f4fb06ea4aa27fb2099886f74ea92"
- execution_block_height: 84
-- deposit_data:
- pubkey: "0x914b56f41c411fbfca9dc9763f44daf253c103b162457d07954fd0af768b5e74692b4639c22455fb81d71f7ed6144514"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xabbd26d91fb83232422509d6ca45b721185fa61fe610027a06c510dec708eea6cf54d1d955b676f5b77b141a6696f18d18b7336ede4da02504ca96e3363ce3c91698ffcf904c9f3c9d31648c79263acacb9747d7069d79016791b4facce83555"
- deposit_data_root: "0x4123a31554edb843e51c2c6d3d608693fda4d5def338ade6425f1790fb511774"
- eth1_data:
- deposit_root: "0x15754d151c1cae6449d10e2e95489aeab66d5defa0f19c29635f0319ff830a28"
- deposit_count: "84"
- block_hash: "0xa18fcf7a630b971e354e7c3661f21b45306ba7ff6d02a67a7a9fdce708a97805"
- block_height: 85
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0x78b501b3fa5475f83b94eafea06a4d859d98ca9dd9efb1f7c9f440868791c620"
- deposit_root: "0x15754d151c1cae6449d10e2e95489aeab66d5defa0f19c29635f0319ff830a28"
- deposit_count: 84
- execution_block_hash: "0xa18fcf7a630b971e354e7c3661f21b45306ba7ff6d02a67a7a9fdce708a97805"
- execution_block_height: 85
-- deposit_data:
- pubkey: "0x8794388915e86e4988363cdd4289ad19182209c873cbbbf5a80ff5c99f93acb839807787a77ad2b603f074405d7ed08b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x87e0e8c98f9e186d31d992634611b6d08376911636fd1d689b01330e70b4a9c819ddaef93128bb333bfdaf9e6e2697550897b9be994b5033b6397989e1db1b7db9d889083f4ad1c763192da282943f571d77781ef46364757151aeae27740ac8"
- deposit_data_root: "0x55aa7b5a4c6d119979913fa560116bd32289f6636e12f6056017cdef97b55682"
- eth1_data:
- deposit_root: "0xfa36dc4e7091338e1af1a655d7f73c8a4a31453769962a8335196409cdd05552"
- deposit_count: "85"
- block_hash: "0x6706a23dd2a500b2856ef97cdee6757a46ab118f06df889d50afc259c7938558"
- block_height: 86
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0x78b501b3fa5475f83b94eafea06a4d859d98ca9dd9efb1f7c9f440868791c620"
- - "0x55aa7b5a4c6d119979913fa560116bd32289f6636e12f6056017cdef97b55682"
- deposit_root: "0xfa36dc4e7091338e1af1a655d7f73c8a4a31453769962a8335196409cdd05552"
- deposit_count: 85
- execution_block_hash: "0x6706a23dd2a500b2856ef97cdee6757a46ab118f06df889d50afc259c7938558"
- execution_block_height: 86
-- deposit_data:
- pubkey: "0xa3862121db5914d7272b0b705e6e3c5336b79e316735661873566245207329c30f9a33d4fb5f5857fc6fd0a368186972"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86fc69a33aaa4221dd112b9c1d69633430d803b55fd0e046d17e9ecc02a53d05429034baeb7d235bc76573449bdd7d0d05c80a3cb7e785f1a06b40cea3fbf66ceefc0a542983a92a609051580f48980a42f3cd43703b810f0f5ee8b5c2a5e556"
- deposit_data_root: "0xead7c5895bcb78cb6bf3b7dd8c3e984cd33de92cedafcbfb11821d725a1a7008"
- eth1_data:
- deposit_root: "0x55993260810877f669acb1d186a3b2e6715d9ff9d948cdc4da03a0515dd3fb03"
- deposit_count: "86"
- block_hash: "0xa2ec2792a7481050df8e4c66e3049fa01b122a59b4b0da16eefb2160122bd887"
- block_height: 87
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0x78b501b3fa5475f83b94eafea06a4d859d98ca9dd9efb1f7c9f440868791c620"
- - "0x05fdfe681bbf2653770a5add8d5a186497090b0852abfc6d2b5c7cd9c2cd48b4"
- deposit_root: "0x55993260810877f669acb1d186a3b2e6715d9ff9d948cdc4da03a0515dd3fb03"
- deposit_count: 86
- execution_block_hash: "0xa2ec2792a7481050df8e4c66e3049fa01b122a59b4b0da16eefb2160122bd887"
- execution_block_height: 87
-- deposit_data:
- pubkey: "0x96ef954b331a534199f4f113d993a50ec7a781fc5aa2a181ea0bdbfd4c5c557abfebfcc02604d5aef52ba64afbe0ff18"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb64dc6b6527edca3c16cf0dd04aeda244d69cb84a96e951ed1a7286c0a8ee24b56d4651e14e03d472ae3ed0cc9928dc40c5947e185e67716db8e8bd4c85bb5ee4bd14102347117b90276620bda17f0a68b6ff225842814a7e0f15e920350725a"
- deposit_data_root: "0xf962e2d35918b11c748e47d10d66e0e052bfb45965a88ca185044e820b33f0e4"
- eth1_data:
- deposit_root: "0x1e14f4e10d68971bf523b164e176f135b1304cfa07c88a57233d8b39a6c83456"
- deposit_count: "87"
- block_hash: "0x3a5d185a584fc74290efc7f9f7781c00d96708e925061731d5e083d44ee009f7"
- block_height: 88
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0x78b501b3fa5475f83b94eafea06a4d859d98ca9dd9efb1f7c9f440868791c620"
- - "0x05fdfe681bbf2653770a5add8d5a186497090b0852abfc6d2b5c7cd9c2cd48b4"
- - "0xf962e2d35918b11c748e47d10d66e0e052bfb45965a88ca185044e820b33f0e4"
- deposit_root: "0x1e14f4e10d68971bf523b164e176f135b1304cfa07c88a57233d8b39a6c83456"
- deposit_count: 87
- execution_block_hash: "0x3a5d185a584fc74290efc7f9f7781c00d96708e925061731d5e083d44ee009f7"
- execution_block_height: 88
-- deposit_data:
- pubkey: "0x96c8d3dd08724624017f178393d176b425dab9dfa1cc3f62c7669337446baa601e0aa261c00c76bde07ba9a1a3582c0a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb37b23e995a74a1c72a6e5d0dc75aa44d3e560c5c3aeaac78648ccdd38380e68b321cfc39555af65cdc2dbaadf3eace20011622070f90f2e782e5edff8330c8b3d8623fbf58fb878e0645f3588b3f75b293fc5f8051d7c324ccb9df12b48a07c"
- deposit_data_root: "0x0b8d152337bd30a81e3353cd2ef3767d4a3f6b84c124010ec8eb784591158e17"
- eth1_data:
- deposit_root: "0x4800ae85e0ddc8eb4927b7c3ac52f3718e7a47eee6b9490d4d974deff6b09f16"
- deposit_count: "88"
- block_hash: "0x6bf5193552720db315898ec262ab1cfd7590e13a88ae86efc702243acfc001b8"
- block_height: 89
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- deposit_root: "0x4800ae85e0ddc8eb4927b7c3ac52f3718e7a47eee6b9490d4d974deff6b09f16"
- deposit_count: 88
- execution_block_hash: "0x6bf5193552720db315898ec262ab1cfd7590e13a88ae86efc702243acfc001b8"
- execution_block_height: 89
-- deposit_data:
- pubkey: "0x92bd81b8e9099b9ca87a2033fdd84475752dc34a0fae0a8e50aabf4d3baff9cd45ed56508c837023944350f53dbc4ac7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x88835cc0416f137bf06133717762b9bda8e31f66b6910eb55a8eae0a4d97bb8d51284a8c4038da5e2b15b77e3beaee6b09d1561bb5bf1ff2cd2f7e6396cb80c520f161f43fb01dc259f5e2c2f33dc632ff1a6a14b46cade75b0850d3841e666c"
- deposit_data_root: "0xd3fbf626f2db8d53f0cfa2e8ab199e5633cbc1b1bc01dd5579000ae8b4c59525"
- eth1_data:
- deposit_root: "0xe83ff8243a690675111ffaa012be7ff8931efd74d0d29c99f7c543db94fb2e68"
- deposit_count: "89"
- block_hash: "0x1b93e72ce9ac8a2eaf1c6b6e8ceb0d413e084b62ab3b65a33414f794c6bca144"
- block_height: 90
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xd3fbf626f2db8d53f0cfa2e8ab199e5633cbc1b1bc01dd5579000ae8b4c59525"
- deposit_root: "0xe83ff8243a690675111ffaa012be7ff8931efd74d0d29c99f7c543db94fb2e68"
- deposit_count: 89
- execution_block_hash: "0x1b93e72ce9ac8a2eaf1c6b6e8ceb0d413e084b62ab3b65a33414f794c6bca144"
- execution_block_height: 90
-- deposit_data:
- pubkey: "0x83802cd575a3cea7e3e38fc1a73d94a9e4fdb999b8494e7929309c009d79a23edb1ba091ac02588f130e0585fb106540"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x90b696dc285957fee877e14c40dcd159622b4522ddb9e31d10f5d89d83af25c7a65de87deb816ec3fea86251c38247bd03e0e4e083e8ce7b63ed5917fd5b7a8bcea01ed61b3234b62eb0baeaf253cc04655cd5b64e7d642a3bc7be5e4a32634a"
- deposit_data_root: "0x58ea01dac688f2b29e401e7edb6319c7017d12c8adc57b372865b40d907be8d6"
- eth1_data:
- deposit_root: "0xd8b0fc873ba2d2d52ef3e7985d6ef0cc924ce56c852970823814b95892805127"
- deposit_count: "90"
- block_hash: "0x666278a6a24e797f1040470692822b240b2630b0af2a38c26da23f727af7780d"
- block_height: 91
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xe2fdce2d1fdc2fe192bb4aa9293cebebd50dc5e78e38a1bbc1b9b4fd39e22985"
- deposit_root: "0xd8b0fc873ba2d2d52ef3e7985d6ef0cc924ce56c852970823814b95892805127"
- deposit_count: 90
- execution_block_hash: "0x666278a6a24e797f1040470692822b240b2630b0af2a38c26da23f727af7780d"
- execution_block_height: 91
-- deposit_data:
- pubkey: "0xb451eb0ff4990917aba6e3d80c34aee91ea1ce49053f38ae174cef107cb9acc595d0ca3fefcb804c9dd04510c630cabe"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa5e3f58c8249a0d3c8269f16af4a8fb42b20b821c1554e51443c897ff00389cb8b85cd953236bc22430ddb49e3b1d8b018926d1e5b87a614e1b9257838cecf59eac47ecfb8648c930d839b8524ade0b68036e9e9987c554cfa24417a00ffc40"
- deposit_data_root: "0xf11f85f05b6d4b0d8ff3bfdc09e03ece905ba6452e2e45f20c78e62652a71f6e"
- eth1_data:
- deposit_root: "0xc1dc1c55036f14ded17a34c5d6c82a3df5c704a067ab5d0f9d50481679c9345b"
- deposit_count: "91"
- block_hash: "0xcf447d1821972d4a820ab84a95dafa442735e577290d6f110ee498567a0a1662"
- block_height: 92
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xe2fdce2d1fdc2fe192bb4aa9293cebebd50dc5e78e38a1bbc1b9b4fd39e22985"
- - "0xf11f85f05b6d4b0d8ff3bfdc09e03ece905ba6452e2e45f20c78e62652a71f6e"
- deposit_root: "0xc1dc1c55036f14ded17a34c5d6c82a3df5c704a067ab5d0f9d50481679c9345b"
- deposit_count: 91
- execution_block_hash: "0xcf447d1821972d4a820ab84a95dafa442735e577290d6f110ee498567a0a1662"
- execution_block_height: 92
-- deposit_data:
- pubkey: "0xa7f711233af57440e9ea700113fc4dbaef97e7da7741dd2e38ae668a7f2685d4585d54a9e6712ff1b87c69dbb181abf7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa2e034a05c1d3cac573a3cd1a4d76584fe1c12dc828aa85fe6b14958efb476d2e5afe6df9f7f7b8af02f19c0f74d93fc0e94911f2152659c11246ad51e5174d1fbcd9335c60fb3097c8168793238d0e0ff710b70f7bfe7f321131271bdff8dc7"
- deposit_data_root: "0x548e5a3a2012b86724762a43fc45047e7e8092914d1b2188a583ca9903f96ca0"
- eth1_data:
- deposit_root: "0x6d4e79bc326336e3a6c8e6c421a29d877c8daa3956aa1e55a63257ab6f5f43af"
- deposit_count: "92"
- block_hash: "0x631ee71ad7fec6f24ca2a56cd1c45f6c860b4ca487b28365f65860caed0614fd"
- block_height: 93
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xf5e222e2ec0403f08a8f04b439d8af9798f665fcc237f672d6e5e7484a024866"
- deposit_root: "0x6d4e79bc326336e3a6c8e6c421a29d877c8daa3956aa1e55a63257ab6f5f43af"
- deposit_count: 92
- execution_block_hash: "0x631ee71ad7fec6f24ca2a56cd1c45f6c860b4ca487b28365f65860caed0614fd"
- execution_block_height: 93
-- deposit_data:
- pubkey: "0xaca5e4979f281b5ab0ea0f549d6dcc34989607c335e94efedeffc7e73b393f42c7b11d76144a750f82600b21d10b6777"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x90374711b91d6b7385cf3f099f5ed3a93d79383968645d9bdbb191bc461b3559df4a7bef411c33a692590ffa1aaaa91f1870a5c0d20df79f2cfaf2d5482f49f380679168f47affe35a4fac018692f5f0f007031bb3d8fef31e23a922a444d8b5"
- deposit_data_root: "0xfd4f2e7d7c027a545467d3a3295b2ab5ccfebc669330a533243db77cd3e8cf4c"
- eth1_data:
- deposit_root: "0xdda9d42bf636ae45f5c4376a0cb0b56e15846bc9119dffda44e196de5ba747e4"
- deposit_count: "93"
- block_hash: "0xcb69ea6fddd200d561ac5e304e8b08abc9b6ec65c3f0e4cccdda7f523facdd6f"
- block_height: 94
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xf5e222e2ec0403f08a8f04b439d8af9798f665fcc237f672d6e5e7484a024866"
- - "0xfd4f2e7d7c027a545467d3a3295b2ab5ccfebc669330a533243db77cd3e8cf4c"
- deposit_root: "0xdda9d42bf636ae45f5c4376a0cb0b56e15846bc9119dffda44e196de5ba747e4"
- deposit_count: 93
- execution_block_hash: "0xcb69ea6fddd200d561ac5e304e8b08abc9b6ec65c3f0e4cccdda7f523facdd6f"
- execution_block_height: 94
-- deposit_data:
- pubkey: "0x984620db3658a19769475080998db9e7f5bcd4255a89a70b5ecf7db01226f213836d091a3b37eb96e4937966b094a291"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96f074fc891b637e18eb0b3c5908f94d4e71f76243914e3b3a88348b7a7ec85289d322e24f14ce75a7d193dece4c7cb5150aca3dae194839807c09039304a894c9e5b70735b88c437f9c6043e495201f58a28683d2eb528e3e81fe14b3ce867c"
- deposit_data_root: "0xeaad4c2435c42339d3f2248def6f6d44a0da2237d6eb6092016e5b9a47b3fa9f"
- eth1_data:
- deposit_root: "0x026d58bd6b7169617f62fc8725cebcafd8b3f352d63060d3b3326ff6e9d2d3da"
- deposit_count: "94"
- block_hash: "0x562a78b2c5ec97a0b4fa413f57885311a457155372bbf630a434d8c243d21036"
- block_height: 95
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xf5e222e2ec0403f08a8f04b439d8af9798f665fcc237f672d6e5e7484a024866"
- - "0x621b699cf7502853da163711315ae56eac3eca5afb2c480325bb9a35e3c9f37f"
- deposit_root: "0x026d58bd6b7169617f62fc8725cebcafd8b3f352d63060d3b3326ff6e9d2d3da"
- deposit_count: 94
- execution_block_hash: "0x562a78b2c5ec97a0b4fa413f57885311a457155372bbf630a434d8c243d21036"
- execution_block_height: 95
-- deposit_data:
- pubkey: "0x8f1ef3639aea57fef705847e251b785bb608a848f42d9107c494cbc696be35642f6552fb83174ca2e73632568a5667f4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa733bafcafc2ba319538ce6af3de20976c5ebd8040a8a3628f7e69a16baeb95566b0cefc55472fba696aa023001b52f605d8824f7dbf2dba9ff2a53554c155815da39e3f27ebd7022a52412b9a793468cb1a1c6469aae7750a1d36a0010fc8b8"
- deposit_data_root: "0x93614f1ff88e971226eb167a407e0afe4d236a82e2eaf43259946edbc8af576d"
- eth1_data:
- deposit_root: "0x511e1b6a894a5783751f3eac7f79d3f52c94a76f29686ebe7eaac7a854d490d1"
- deposit_count: "95"
- block_hash: "0x723848008dec04dc63b5a521c38e95c5f2598053fb5a756022d3a85906128eee"
- block_height: 96
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x9cdee5c9ecd1ef9a54feb904550ef7271277dcbc43318688b0b0f4b0454c5a95"
- - "0xe78ee87ce4f2c19b2b27b0e4d875fb21bf9580e9b8e683f34db124274f263dc5"
- - "0xf5e222e2ec0403f08a8f04b439d8af9798f665fcc237f672d6e5e7484a024866"
- - "0x621b699cf7502853da163711315ae56eac3eca5afb2c480325bb9a35e3c9f37f"
- - "0x93614f1ff88e971226eb167a407e0afe4d236a82e2eaf43259946edbc8af576d"
- deposit_root: "0x511e1b6a894a5783751f3eac7f79d3f52c94a76f29686ebe7eaac7a854d490d1"
- deposit_count: 95
- execution_block_hash: "0x723848008dec04dc63b5a521c38e95c5f2598053fb5a756022d3a85906128eee"
- execution_block_height: 96
-- deposit_data:
- pubkey: "0x8967da3c8071ba2bf632cd40ae08fbbf0a203c47c02af1948fc232a7a743c0c0cfbe51606b89f102f2f6de7f039fb155"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x913fdc3ce1efa57fc787572b38a1682a411548e5707daf8e7b9e6a6126ab172c33226e21dff8bbd48b2a8d22f1a8b0e51540166b4c6f8cdf978f69a04a3ec48ebbf64d9640e20b834b56362b0bab8ad1793f72bce5d6afe74588a6f6efdd7267"
- deposit_data_root: "0x6b4666b947e91abcf56197ff3e4c918aee6289bb0dade7a5788d7032ac026acc"
- eth1_data:
- deposit_root: "0x083b92e2d2cee3120c5fdc9d2ab492d7563bec65eb27aa5013465136f7eebe41"
- deposit_count: "96"
- block_hash: "0xc566f29d941053e9c2881d01fc9b1314c714fdc6d6ef63d842e557e6a347884b"
- block_height: 97
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- deposit_root: "0x083b92e2d2cee3120c5fdc9d2ab492d7563bec65eb27aa5013465136f7eebe41"
- deposit_count: 96
- execution_block_hash: "0xc566f29d941053e9c2881d01fc9b1314c714fdc6d6ef63d842e557e6a347884b"
- execution_block_height: 97
-- deposit_data:
- pubkey: "0x8d58f7e2e58471b46d20a66a61f4cde3c78ab6c0505517c615e08d8ef5adf59b65fa2b01ea2395c84584a6f10d6cee2f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x892b60039b6e05f3f82b460d9360e1f1121adc5974a7c75f8cb723d597f764fb26aaf21bbd6a08b36078d6acc00a355607888b4838f9a1d007a4d0d0db5650e36ca498d6d074bf14a0a33ef13c34a419d7f99c6ebe0eca5001263cbb26f299b4"
- deposit_data_root: "0x34e3e3e0c13a79cd9e7e8826d9d20c106a9401f253750a68869eb8d31fd8d03a"
- eth1_data:
- deposit_root: "0xc33b108e1f20262d0bd6dde0604c39e305ecf07eb8c390070cf586395b6050ff"
- deposit_count: "97"
- block_hash: "0x01a6a54f02fad6d7168ef158896c42874a9696b7d6b33b6a90fba4e9892723a2"
- block_height: 98
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x34e3e3e0c13a79cd9e7e8826d9d20c106a9401f253750a68869eb8d31fd8d03a"
- deposit_root: "0xc33b108e1f20262d0bd6dde0604c39e305ecf07eb8c390070cf586395b6050ff"
- deposit_count: 97
- execution_block_hash: "0x01a6a54f02fad6d7168ef158896c42874a9696b7d6b33b6a90fba4e9892723a2"
- execution_block_height: 98
-- deposit_data:
- pubkey: "0x8db9f236d3483af79703244c7034b5267a0546c3c840d4e91fdcdd466373d62d960553982225ca5f7666dd7375a29c19"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9395087be80e3bc55d623f4d5bdfe6de200064e27d862d731c0c3dcf60a7c73fc6ad5c59177f788b5ce4ad6c2053fcea0950ec9196c8deae651f8cf3042a87b234bb4f201fe0d852708c332d0efe4323a7f6b3782ee919b365479cb5aa90bcc3"
- deposit_data_root: "0x57a75df5bd0f09fbaa3bbd2ad872fd0704d94d51ddcefad7ad9af438b9d63ce2"
- eth1_data:
- deposit_root: "0x99b08e97b9635d5ce40146efae53e688f53a8910a0357fe211440987b63f86c9"
- deposit_count: "98"
- block_hash: "0xff6e581a1f58dd834e095b5dc6cd14940a0b5148a7d0b6d94944ee324750abeb"
- block_height: 99
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x9c30281da5fd2d7a8bd8e4c8c3a19ee28bb8a08c97e386825abf49429dfc8492"
- deposit_root: "0x99b08e97b9635d5ce40146efae53e688f53a8910a0357fe211440987b63f86c9"
- deposit_count: 98
- execution_block_hash: "0xff6e581a1f58dd834e095b5dc6cd14940a0b5148a7d0b6d94944ee324750abeb"
- execution_block_height: 99
-- deposit_data:
- pubkey: "0xb7721412ae5a793f34ac8866698b221c67ef8272eba44d3030512ec3f7ed8ffcb620b58f17809690d5276423e849827f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8967a6b4490020cee91b6554b3aadb730da19f1dc9ab10629014f1b6221bb3f5827dafab1c48d97a5e0f55577708dad613724b60700424854c38a14aae340d8fd20ed7145e95dc458cc3d298192aad68c112bccd7f5574594a6d5a5b5401bd63"
- deposit_data_root: "0xc14a33eb96c6282e934f2944a23bafc7813ab96c21dee6ec6b2ad8c4c10ec4e4"
- eth1_data:
- deposit_root: "0xcaa6c2f895d078431ed03bc0d16ff9cae6eab44c2675a42de52820216f647f0e"
- deposit_count: "99"
- block_hash: "0xaf681b414bf20e9775a4c897373013a58d6db4e23c2a394b25cd9dab40ca6c53"
- block_height: 100
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x9c30281da5fd2d7a8bd8e4c8c3a19ee28bb8a08c97e386825abf49429dfc8492"
- - "0xc14a33eb96c6282e934f2944a23bafc7813ab96c21dee6ec6b2ad8c4c10ec4e4"
- deposit_root: "0xcaa6c2f895d078431ed03bc0d16ff9cae6eab44c2675a42de52820216f647f0e"
- deposit_count: 99
- execution_block_hash: "0xaf681b414bf20e9775a4c897373013a58d6db4e23c2a394b25cd9dab40ca6c53"
- execution_block_height: 100
-- deposit_data:
- pubkey: "0x99f6e5b80dc52407f0436d3474bd5da5ff23a19cb188b933af6312d9793cbfd54f9e72596c5d481a1ed8d705b81c1f0e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa0de9fe9ab9d8fa0b287ca0c7335bca94a79a888e67a7e0a933d38b5dfca2cb30d77f75398652a3c787af48b0707ebb20d3fd2e3f78c459235bd0eb17f550964e6d2638470728499f59cca4c041846d433e9095b5d2cc83c633cc728f3683db8"
- deposit_data_root: "0xc6f502475ac7546b770905653f9c9da144d8721ebf626232259099df44d67793"
- eth1_data:
- deposit_root: "0xe346f5cfac0d8834bbdf80742e9de3418f612bc03fa79a9be61a9a201070673e"
- deposit_count: "100"
- block_hash: "0x40078f8026a5491a9530ebc2bdc366535d4c6a7c37c1df6515c4074508849187"
- block_height: 101
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x2c03f5ec194e16617790b85ceb15755990f694b3fb90b74d26812f265b90d33d"
- deposit_root: "0xe346f5cfac0d8834bbdf80742e9de3418f612bc03fa79a9be61a9a201070673e"
- deposit_count: 100
- execution_block_hash: "0x40078f8026a5491a9530ebc2bdc366535d4c6a7c37c1df6515c4074508849187"
- execution_block_height: 101
-- deposit_data:
- pubkey: "0x8931cd39ec3133b6ec91f26eec4de555cd7966086b1993dfe69c2b16e80adc62ce82d353b3356d8cc249e4e2d4254122"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa1e9f2cddc66b67063b4caecedc4093ecb9241a751da05b6219b5062a5311590d0b4f8b258377a6696316d7808e10c6502542f3a14c00693a70ea8adf2bb74b79d0a15613058c521b50882007b85a0ca26b0bf888695d0a03dcdf0139364c849"
- deposit_data_root: "0x61a0ce23d0255c07b5f1f85771735ffc18dd898b056d00d5e72431c9ab4526c8"
- eth1_data:
- deposit_root: "0xd5db7d15947a7d071f2809c8e827e9ca01511010e1af5e50e59ed2eae150fab5"
- deposit_count: "101"
- block_hash: "0xbfa88dac097016410b459589b3d5703070fb2da3419661138f0e3e9bc868e49b"
- block_height: 102
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x2c03f5ec194e16617790b85ceb15755990f694b3fb90b74d26812f265b90d33d"
- - "0x61a0ce23d0255c07b5f1f85771735ffc18dd898b056d00d5e72431c9ab4526c8"
- deposit_root: "0xd5db7d15947a7d071f2809c8e827e9ca01511010e1af5e50e59ed2eae150fab5"
- deposit_count: 101
- execution_block_hash: "0xbfa88dac097016410b459589b3d5703070fb2da3419661138f0e3e9bc868e49b"
- execution_block_height: 102
-- deposit_data:
- pubkey: "0xad01d0f23cb74fcc4c39a2d0827d22f4722f02076196350dff5dcc6be765009c66e29001001959d77b277c2f0fba0425"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3ffc0107b268976d973c779f1682eb3b92fa5988a72a169d6b959472a72b9ea48c30132bbfac1dbde2a1b658007025011969607d97747e6bca0a852a0c0a03d0fdee3550f22f4052fae270a373b92d40f14c86ff0f79d7570335e16269b034a"
- deposit_data_root: "0x7fbb1660d3859504d5652fb48a640e3a0852b9087209abc9e9a641a3b0bc526c"
- eth1_data:
- deposit_root: "0x2a0a58d87c8644cff8c8b70ca8c8e698376bed37ba7f9b4ed5f5e9058b3e4017"
- deposit_count: "102"
- block_hash: "0x2617746c889290b55facaa523ef25b1bf1bfad0be77797ffa78bf2fd44217fad"
- block_height: 103
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x2c03f5ec194e16617790b85ceb15755990f694b3fb90b74d26812f265b90d33d"
- - "0xde2e3c85af638e1c1b8581fd99aafbb0b9e0e2d638a96c2037814fba4940ddad"
- deposit_root: "0x2a0a58d87c8644cff8c8b70ca8c8e698376bed37ba7f9b4ed5f5e9058b3e4017"
- deposit_count: 102
- execution_block_hash: "0x2617746c889290b55facaa523ef25b1bf1bfad0be77797ffa78bf2fd44217fad"
- execution_block_height: 103
-- deposit_data:
- pubkey: "0xb300303a03b8eff26a25449169d1946b208d5240f011ca6f5db23cd7f2c004b63f60afe3c9e047b67f9e4c8970c71cf0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x88d4150448307f43753ee083124754d8c18b2c4eadb170e741e828b61b356b8cf3c69caadbdcae96f3353ba068f2c2da00596d5ba1f5dae9ec4c305ee7c5069ba5c71ea6ac5cde50bdee887233c18a85928a066802d5b4b38f3295c706860d93"
- deposit_data_root: "0xaccb652fae17e3c73511c9d3065377183aa4cc46b7f0f57b0e7d821b2b2ce99d"
- eth1_data:
- deposit_root: "0x7154ee203a0ef6d25aba1c8473290a20ff6db1147cf850f848d8641e25d872ac"
- deposit_count: "103"
- block_hash: "0xb082be3f6319b71f9235dd3320af6ac53a7211bd652c673eecd70fa2443d9b76"
- block_height: 104
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x2c03f5ec194e16617790b85ceb15755990f694b3fb90b74d26812f265b90d33d"
- - "0xde2e3c85af638e1c1b8581fd99aafbb0b9e0e2d638a96c2037814fba4940ddad"
- - "0xaccb652fae17e3c73511c9d3065377183aa4cc46b7f0f57b0e7d821b2b2ce99d"
- deposit_root: "0x7154ee203a0ef6d25aba1c8473290a20ff6db1147cf850f848d8641e25d872ac"
- deposit_count: 103
- execution_block_hash: "0xb082be3f6319b71f9235dd3320af6ac53a7211bd652c673eecd70fa2443d9b76"
- execution_block_height: 104
-- deposit_data:
- pubkey: "0xaca096c7f41cfa6b9317dff26c6c96878c9e5d5eed50afde44d8df206372ad4b4c45568f6671552029f4c3509e295bef"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa200bef0c9ca2a3efafb7d75dd19be1f621a50b1f5d3eaa688a6d02119a1c08125c4d9dd71cc388e2dfac5544d466bf618293c90e396b56e0d7ab9714a386e0f9685cd4aa07de369cee98ef3912281f438c7ae29146a199c94d2542889d9f898"
- deposit_data_root: "0x70ee28dadd98103e531ac6f411f1798bec743246fe66be847efe6fc26bf530bf"
- eth1_data:
- deposit_root: "0x548bfd5b5eced68eb9fdbabb484a6145d518a234cd7626ab7bcde2752dc878eb"
- deposit_count: "104"
- block_hash: "0x1cf1756c5ffc73b0f80fc2a242fedcdeed357eff548826f5b81a765f69f98a9b"
- block_height: 105
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- deposit_root: "0x548bfd5b5eced68eb9fdbabb484a6145d518a234cd7626ab7bcde2752dc878eb"
- deposit_count: 104
- execution_block_hash: "0x1cf1756c5ffc73b0f80fc2a242fedcdeed357eff548826f5b81a765f69f98a9b"
- execution_block_height: 105
-- deposit_data:
- pubkey: "0x87bbd5574c17dbf80463d11f812a77306f67913c510b1b234f5bd80478c7da8e69476cd6711cd1f4c0e228a4e2e99636"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x982d4f21d196dd1c646180e68e831f730e596980de02297deb7a91a2d1b5fdf82fe7bd7dd9e2d301ef25481814e763b505f8183b996e08e363c27fc6e6d08538ee37898ac5ea10f9ab9b6f70265ad3b214613e643c9c047333bbaf95053eb3f6"
- deposit_data_root: "0x16c89707a34efa444cf234654f40c446d1dc61cd8f9868668df3b1ab87eaea8e"
- eth1_data:
- deposit_root: "0xef70ec141be46e60cb179e2b7dfa8f061a0ed3cdf8b1f8b67e0f410f3a6af678"
- deposit_count: "105"
- block_hash: "0xda9c4714b0ab8c1befb967e12d9f677e7c536aca4750647e6302a6c5687460f2"
- block_height: 106
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0x16c89707a34efa444cf234654f40c446d1dc61cd8f9868668df3b1ab87eaea8e"
- deposit_root: "0xef70ec141be46e60cb179e2b7dfa8f061a0ed3cdf8b1f8b67e0f410f3a6af678"
- deposit_count: 105
- execution_block_hash: "0xda9c4714b0ab8c1befb967e12d9f677e7c536aca4750647e6302a6c5687460f2"
- execution_block_height: 106
-- deposit_data:
- pubkey: "0x89a80c9263a21ebb9b7b99e59e53edc9ac766a55da86a52d1098d57572999ebad7cb92800b1f15be8d7c43889ab71c5d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb6ca12b56b3beb9f9c785f8f865ae5d33ae5d432c34b580907c56ea252be219553c87e3a6d2eb3d93bf29b16c0c522b303c289933ace190bcc666cf3cbcc22f5f516d2ecad7bf29ceef55f8911b33a9c9f7bdde58876e6c02522925d0de0e444"
- deposit_data_root: "0xe9b136c1ca2fcb6d303f551b646a882b36d377989a217239b68534d1afc9fca0"
- eth1_data:
- deposit_root: "0xaeae251b14d94efe7aa55639a1387528a1e5ef2769b05e8286a661d147e06cb3"
- deposit_count: "106"
- block_hash: "0x5669324d92acbdd26d268054be610287bae0b19c33fc941fd3096db48833448d"
- block_height: 107
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0xa2000cb687523633d740002d63b1deb735701652a6d1053a8e859b2a2b17ca0b"
- deposit_root: "0xaeae251b14d94efe7aa55639a1387528a1e5ef2769b05e8286a661d147e06cb3"
- deposit_count: 106
- execution_block_hash: "0x5669324d92acbdd26d268054be610287bae0b19c33fc941fd3096db48833448d"
- execution_block_height: 107
-- deposit_data:
- pubkey: "0x802408c2a1901d316637a3ec6d20447bb9ee105c8c088510bfbcf8cda3ffa9376779f36e12e960e7efa5f2aba45e6483"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91efe4ad425f9226a32e6c2bb04e47bd7adb4ebbbfcb20bf4119e046f22aa714264dcfaa8a1744d02d959e6719fbb245013230f209524365c2b2f418abb365a439883f89abce8896f4463dee7e9b08629b06bf1a1e8704cee65bad429c0a5757"
- deposit_data_root: "0x43e5a791b6ea536132e9b7c2e9e154eb7228704fb1749d76474dccf2cffb2c2e"
- eth1_data:
- deposit_root: "0x97284fc411333bd602aef2ebd5cf41ced3b2d7b27ae5de0d97a0b23f1a352ee6"
- deposit_count: "107"
- block_hash: "0xb1f82e537255e3d8c6607a9e5acf26cab9c71cc10145c2295012c650f67a3476"
- block_height: 108
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0xa2000cb687523633d740002d63b1deb735701652a6d1053a8e859b2a2b17ca0b"
- - "0x43e5a791b6ea536132e9b7c2e9e154eb7228704fb1749d76474dccf2cffb2c2e"
- deposit_root: "0x97284fc411333bd602aef2ebd5cf41ced3b2d7b27ae5de0d97a0b23f1a352ee6"
- deposit_count: 107
- execution_block_hash: "0xb1f82e537255e3d8c6607a9e5acf26cab9c71cc10145c2295012c650f67a3476"
- execution_block_height: 108
-- deposit_data:
- pubkey: "0xaccc213c82702adfd5c32b24a68863f16ab6ab46947d1d7b3829bc62cd5f2a87bcd0d3ef27d442f07ad4363be9fc12f8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa2e689452fd1534510fd42ff1e2dab4addf50492d66518836649ddf9ca206953fbd0ada1f727d14fb05e2041e3d786e308f06f5cb5f610fb8c8bea08730f4f35cf4ce8e12dbfe2d86f5be234b765373fccf1d2e167d2e14051aabf6c563822d5"
- deposit_data_root: "0x834c7ef796fc324ee3d09a5c35fdc887d317b6e6fb166403b37f9672736f83c8"
- eth1_data:
- deposit_root: "0x0d890ddd7f83f43cdc1bd1888b4b514892240f854310148d31fd0cd36e577d0e"
- deposit_count: "108"
- block_hash: "0x3859945b847ee6c8bda15345167cd845984f63fa80b59abd02e47f305ab1859b"
- block_height: 109
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0x3f0c046faed71f3fab856fcaf43a55a7865e4f8054998ea1b7b0ac4b2ec62d03"
- deposit_root: "0x0d890ddd7f83f43cdc1bd1888b4b514892240f854310148d31fd0cd36e577d0e"
- deposit_count: 108
- execution_block_hash: "0x3859945b847ee6c8bda15345167cd845984f63fa80b59abd02e47f305ab1859b"
- execution_block_height: 109
-- deposit_data:
- pubkey: "0xb0af0bfa83f0922e6cbfd2bc8ec19ff0f692fcb87c4e35f30e1353b342ae2fdaea6056bc2759970fc2a1f561826f564e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac48afbc00ea959cf42b12f84d934ebaa6411c2ef6543b9551795d44b9c0ad242892330217978991c010250104e9b3d702107985f4f3f470ea555d9995fdf2c53549f3f4577e1893cccce684b9f13961730dccab982e8ffc56013ddec229e145"
- deposit_data_root: "0xa366a29df760de23293716136774c56eb8d31fc5c2ab2ad91235305fffff9ab2"
- eth1_data:
- deposit_root: "0x4c52ffd886c8668450508977adb286c525f48706688f364dcd0a7197b08b6dc0"
- deposit_count: "109"
- block_hash: "0xd5bebc34ca9da5a4ee194fec1c3efdf56a070520be6dbfd87f08862e7909ad5e"
- block_height: 110
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0x3f0c046faed71f3fab856fcaf43a55a7865e4f8054998ea1b7b0ac4b2ec62d03"
- - "0xa366a29df760de23293716136774c56eb8d31fc5c2ab2ad91235305fffff9ab2"
- deposit_root: "0x4c52ffd886c8668450508977adb286c525f48706688f364dcd0a7197b08b6dc0"
- deposit_count: 109
- execution_block_hash: "0xd5bebc34ca9da5a4ee194fec1c3efdf56a070520be6dbfd87f08862e7909ad5e"
- execution_block_height: 110
-- deposit_data:
- pubkey: "0xa626de0451397075bf145e720691c9d5ed92eddf1f4e48155b455aac7a8e920d042f5635c7a74fe3a9175ffbfb7ce12e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb34e59e6935eafbe65e52e28c5f311f381b303f479ec2a6e9fba488e514de0eb6e1079f033cc8dcdd839675a6ef00869132aaa13dae6179fa88d01620af6cdf890258219b7bd4e374f82712cab8aec4de54ea403f2807c20ff8587ba9740de6c"
- deposit_data_root: "0x225e8673c5a0ede3e15885c408c04c2468c223f1fff0a87b08cc74887dd3a56f"
- eth1_data:
- deposit_root: "0x7c63909e1401449ed1e5773863d7629fbc8396468b85476a75d7e637b5f9f7a0"
- deposit_count: "110"
- block_hash: "0xfdee2ad0a738d5c9a2f063b80fce04b5e61df04fd595155dc5509d45ee6495b5"
- block_height: 111
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0x3f0c046faed71f3fab856fcaf43a55a7865e4f8054998ea1b7b0ac4b2ec62d03"
- - "0xac07404027d09239f2784ec2873ccb9baf4212a432cce6626f56e80f1e99ea5f"
- deposit_root: "0x7c63909e1401449ed1e5773863d7629fbc8396468b85476a75d7e637b5f9f7a0"
- deposit_count: 110
- execution_block_hash: "0xfdee2ad0a738d5c9a2f063b80fce04b5e61df04fd595155dc5509d45ee6495b5"
- execution_block_height: 111
-- deposit_data:
- pubkey: "0xb0933ec64b73c49071fb92028a8e3d1ad18019e177370d335fa03c61de5d01e1a7e154812f720c44109701e2b07068b0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4070a873b52b119a63ecfd68300d7f2f359963cdcdb4b7e6764647975b2fcf6ac0682c37690493d3078794ee680c0490381f85b20b8c0ff33f9642dad0064e0ab84eced4a8e38bacdcc4a068a7c5742d67e64b9019bbaf2f2a64a7e525b2198"
- deposit_data_root: "0x5242358df16ac3f92030b1fbbdb91f85d477b50d2d33a2f59dcf4bce046ee698"
- eth1_data:
- deposit_root: "0xa277f7cb6c03e9087666ea431b99d82c13b4d5ee95ccd73b1b627bacb236486a"
- deposit_count: "111"
- block_hash: "0xe89d23f1eaca58026acc006eff84e317245838800cd5c1be08a8564284c75a6f"
- block_height: 112
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x6cd8d51fa9ddfe114bb7f25d29576b6a72602063f2c1a541ac3e767dc0bd28f4"
- - "0x3f0c046faed71f3fab856fcaf43a55a7865e4f8054998ea1b7b0ac4b2ec62d03"
- - "0xac07404027d09239f2784ec2873ccb9baf4212a432cce6626f56e80f1e99ea5f"
- - "0x5242358df16ac3f92030b1fbbdb91f85d477b50d2d33a2f59dcf4bce046ee698"
- deposit_root: "0xa277f7cb6c03e9087666ea431b99d82c13b4d5ee95ccd73b1b627bacb236486a"
- deposit_count: 111
- execution_block_hash: "0xe89d23f1eaca58026acc006eff84e317245838800cd5c1be08a8564284c75a6f"
- execution_block_height: 112
-- deposit_data:
- pubkey: "0x8b47707a1f563d3b1034e20be2a663587f17fece6581fca156cf660575fde4b8de4d45f1fda7ade9167b953d4c93417d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x94c71b0489c2e7cc1041a4971b92bf507c78b868d58de47fa10f673952fffa15edbf42cff7dc09f55ded92069023ed31049a7b917ac3629560e1a1ab6dd936a8e846a36cc5a691cb0cdcc1ac61a47565778aa9c8ddecb41e2cacca4fa7a9a093"
- deposit_data_root: "0xecb5c27e0bd4dfba545e4be285416d20eea78a0c894c97542ead3e70cf3a0788"
- eth1_data:
- deposit_root: "0x98e76adf146e3608cd2e4f340d4d646e8f43a211e2326a454a86e2a2ffa8442f"
- deposit_count: "112"
- block_hash: "0x6803694b96704cf8b5a7b731ab9497fc091064132096166e8852ad5de1d23aa3"
- block_height: 113
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- deposit_root: "0x98e76adf146e3608cd2e4f340d4d646e8f43a211e2326a454a86e2a2ffa8442f"
- deposit_count: 112
- execution_block_hash: "0x6803694b96704cf8b5a7b731ab9497fc091064132096166e8852ad5de1d23aa3"
- execution_block_height: 113
-- deposit_data:
- pubkey: "0x8ce551755078927147bae52f683f962ca09cd68e2a14dc7444f98739fe5d27e3596314d78deedc87beb705bcf9532182"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa68afbb096250d43a72588cf6db83f6be6413f0d7350056cba7d11df6fc7efa07107dd925130c0d1ab55b510e5e39b29151649e8f371e113a83c7e2518c4a0d6d16b17c7209396a5bd9653f78f357528e277071f03bb9abfdb10580e919b84a8"
- deposit_data_root: "0x54af1e6596ebc505cb6c1eb2c2a58d137f0ab4ff9e8919495631a9c6ce02e185"
- eth1_data:
- deposit_root: "0x28d6d95d118088e83779c9030adbbd5faebcd35e8168a1d8c3f675a80ae7aa83"
- deposit_count: "113"
- block_hash: "0xaaf1b5f2693fb64143ababcc4d377385cc37a7f6a87c989b5c21ee9dd1578fbf"
- block_height: 114
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x54af1e6596ebc505cb6c1eb2c2a58d137f0ab4ff9e8919495631a9c6ce02e185"
- deposit_root: "0x28d6d95d118088e83779c9030adbbd5faebcd35e8168a1d8c3f675a80ae7aa83"
- deposit_count: 113
- execution_block_hash: "0xaaf1b5f2693fb64143ababcc4d377385cc37a7f6a87c989b5c21ee9dd1578fbf"
- execution_block_height: 114
-- deposit_data:
- pubkey: "0xb363a57c600a0037d54d738037358aa686e27da3ea65be95f95fc04d5736fba6338c5d544c3cf2b11262bd20e7a42dd1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8fb0e367ac8eeceeccc271b8abb3f6a51ac714bc0837d919ee3cd56df40f2b3020fa79592035cd9b4b59e428620b1fc0ef0b62804119288362814074b2247be97106821cbe2e5ee077d4935a853c17730701c0b9eafc83ff08656b8ec2fa7a2"
- deposit_data_root: "0xd6fdfa51b7eb29f6327bd5f283e43b584dde088d09df4378e58b244b871c4dbe"
- eth1_data:
- deposit_root: "0x4f43eee61db70c0290a3ec3eeed96b98d38fa1fddb21149808760133b9f7a385"
- deposit_count: "114"
- block_hash: "0x9184c85f99de9e7302c25f18b814f557e5ed7363677ce9fa97dd727f1c9c01b6"
- block_height: 115
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0xc2d2d3ec8e50223aa7c20032356d3d4a3be3ecfd18471318d91192e20bca4cd9"
- deposit_root: "0x4f43eee61db70c0290a3ec3eeed96b98d38fa1fddb21149808760133b9f7a385"
- deposit_count: 114
- execution_block_hash: "0x9184c85f99de9e7302c25f18b814f557e5ed7363677ce9fa97dd727f1c9c01b6"
- execution_block_height: 115
-- deposit_data:
- pubkey: "0xa5e05143d5034740cb9ad524bec81678b07223989d4534ad44ffad33ee2fc73e4ee6b297b68aef9de33f98e5487467b5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa44866b3ac0b41fb89fd7a51f4963bceab4b31e92f963aea80979a8a96835067eac75868f59c7ad204f00e117bb3cded053e6d2334e626634d0cee0120234658f7cc1e0c68f0c7d1f23327db2bf91d86b56ce7131012b0db84266bf624f0b599"
- deposit_data_root: "0x72a8893e5155db8e97031c2de604a4ea3b0d3323a6a242a4253c7a539dc72ddf"
- eth1_data:
- deposit_root: "0xa9ddf7428ca9cb8ffa10cf3f1ac2e56066e9f962e8cef91aedd841f0c0b3a6c5"
- deposit_count: "115"
- block_hash: "0x0343f11c8b2cb94cf8cce1b1f0e6dafcc956a4d6ba21a0010ae204a4e50d8171"
- block_height: 116
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0xc2d2d3ec8e50223aa7c20032356d3d4a3be3ecfd18471318d91192e20bca4cd9"
- - "0x72a8893e5155db8e97031c2de604a4ea3b0d3323a6a242a4253c7a539dc72ddf"
- deposit_root: "0xa9ddf7428ca9cb8ffa10cf3f1ac2e56066e9f962e8cef91aedd841f0c0b3a6c5"
- deposit_count: 115
- execution_block_hash: "0x0343f11c8b2cb94cf8cce1b1f0e6dafcc956a4d6ba21a0010ae204a4e50d8171"
- execution_block_height: 116
-- deposit_data:
- pubkey: "0xaf14e8626e043caed52d9dfe62046eaa698f8b95d25cedc8c63e472def8b6a59e64febfa00e95568538c1a382ac91d2b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8a07f9a5faf428d95a6924d2e4d9aab65e9756b878d548a9ab04b57257c56c3878e1d451b36f264f6fdb1521162ccda089ad9e5c250738c983827e64dfd21b9b3662ce1c5fff45b2f73bbe47d0b1a6b208b4f2fbf78447ad5e12bf6e7a4596e"
- deposit_data_root: "0xab893bbeb9c8f1b0aeb760b31be1696736b2f7ee05edff8dcc6183d76adae267"
- eth1_data:
- deposit_root: "0x03d68d623a18dd6af2380829bcb89709b8024f8ba83771ac3f5135bdcdee00ee"
- deposit_count: "116"
- block_hash: "0x73d9f83ad8851e59c41c2b25e0e568dbb0ef8c23f37a006dcade3329a8d6f0f9"
- block_height: 117
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x97906a31d1ca59143dc947a1f048242f4c67382be296dcdf43a03951553464ed"
- deposit_root: "0x03d68d623a18dd6af2380829bcb89709b8024f8ba83771ac3f5135bdcdee00ee"
- deposit_count: 116
- execution_block_hash: "0x73d9f83ad8851e59c41c2b25e0e568dbb0ef8c23f37a006dcade3329a8d6f0f9"
- execution_block_height: 117
-- deposit_data:
- pubkey: "0xb41a0d9f8f19be13395aa09711b492d20eaf4a56d2360cd6daa2fd665532d852cb9224a5a39e5abff389882f961f12a6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9976e20aca195ad464d2e5bdff8f89100d8fa42357588bffae1c3ebce0af6ab593fdbb83b6e316fde942bad4dca225520e3aa856e5e5adb167c7fee7a1f022a9caaa0f199b5e5a2f7a2ecda1f016c02845f2168f0a144a1de33890ec8480441b"
- deposit_data_root: "0xc970a40ac721ba0ea1adff1e2f0a10b8dc9529a25bf867f8eb22359655eb5c66"
- eth1_data:
- deposit_root: "0x1e0d48b0764fedc0a118aea5976361d0612144be975699f762b00c0365b22cae"
- deposit_count: "117"
- block_hash: "0x1f8c317ca00006c5468170bb2ad996fc5264a4622b30ff4feabf2c3a923a622b"
- block_height: 118
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x97906a31d1ca59143dc947a1f048242f4c67382be296dcdf43a03951553464ed"
- - "0xc970a40ac721ba0ea1adff1e2f0a10b8dc9529a25bf867f8eb22359655eb5c66"
- deposit_root: "0x1e0d48b0764fedc0a118aea5976361d0612144be975699f762b00c0365b22cae"
- deposit_count: 117
- execution_block_hash: "0x1f8c317ca00006c5468170bb2ad996fc5264a4622b30ff4feabf2c3a923a622b"
- execution_block_height: 118
-- deposit_data:
- pubkey: "0xb242e56475dca34fe92de09daee3951d647c04ed7a483a5c5c5613676f5ca88d54ec64d1aee81fb0f085aa67c88ee6db"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb0e8b1ab87c739db7149b5e2756e3fec4cb8ca9ce14cd17af4064c85e0917dfdd4c40c13f6c48cbffe760a45f63567fa13272ef95f73c5fafbfe62336292af7c1cf68d2ea3a399729e330feccc375c237c6630a031c1badee92d8d463bf2c3e4"
- deposit_data_root: "0x458248ac4f1676159c16889a98e42e86fcb36615a646d1f3e8c0d56a5c5710a4"
- eth1_data:
- deposit_root: "0x1331f96e0caa629377f330bbad76213870a7d46ea84f70f3211344cd2864ff22"
- deposit_count: "118"
- block_hash: "0xa2c8860839e76bdc3c39ffe65914b4fe29936c31f0218c0ec7b1096f086e6066"
- block_height: 119
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x97906a31d1ca59143dc947a1f048242f4c67382be296dcdf43a03951553464ed"
- - "0xa325f304db3245c0b82c9770d2cb6ee122a7a8ee7b7d02568fcba7c3d74cd1c4"
- deposit_root: "0x1331f96e0caa629377f330bbad76213870a7d46ea84f70f3211344cd2864ff22"
- deposit_count: 118
- execution_block_hash: "0xa2c8860839e76bdc3c39ffe65914b4fe29936c31f0218c0ec7b1096f086e6066"
- execution_block_height: 119
-- deposit_data:
- pubkey: "0x894798d09babc765b3ba22473d820465e713c1d7f78f3eaeade3d957bd412a742f498a9b91e55cba8e08c36c8ad4788f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3fe3f86d154a803bfbbcdf25da35ae7293e7a67ed8a486b2178424cf4dc4cd580419276d833bf6aebf02d5c59fb85c70e69fa7718448e6e590c5a88f81078982243ebc70eca16a8c65983d367597d9af062c7bec6e0657ed33c7caab044a6b9"
- deposit_data_root: "0x84bc2d2d601a86cf3f07e155e5fbf2c6a24a838c35c6f5aeb1cf8ec9f54076a3"
- eth1_data:
- deposit_root: "0xc711c10ca8badf31bce9ca6b0ef21a3aad8c94218e594891dbc49e5de5ef0480"
- deposit_count: "119"
- block_hash: "0x09861bc26ec9b9b75d164cba54b6b8f81256b16a0b8d4fad05c0bcb2368cef02"
- block_height: 120
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x97906a31d1ca59143dc947a1f048242f4c67382be296dcdf43a03951553464ed"
- - "0xa325f304db3245c0b82c9770d2cb6ee122a7a8ee7b7d02568fcba7c3d74cd1c4"
- - "0x84bc2d2d601a86cf3f07e155e5fbf2c6a24a838c35c6f5aeb1cf8ec9f54076a3"
- deposit_root: "0xc711c10ca8badf31bce9ca6b0ef21a3aad8c94218e594891dbc49e5de5ef0480"
- deposit_count: 119
- execution_block_hash: "0x09861bc26ec9b9b75d164cba54b6b8f81256b16a0b8d4fad05c0bcb2368cef02"
- execution_block_height: 120
-- deposit_data:
- pubkey: "0x93c65ba88f12ad22c761003cef7ffb155b9b17134ed871c0703fac60e80dbd2dd8d163bd28eba9dff88b1e9bd1ae4a76"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8358f8f27f66caf3abf2ab7ebead7028bd465266a29d6d465e94ed3bf4a26e7820379f90db0ddd4eef534a8fba0257691579607ef99b3e8cc06dd9994ac7b226a5cdf3b2e2c691ac805a26045d984fdcfdda393fdff9d27db2d8e6f58d49e364"
- deposit_data_root: "0xa702f084aa633619824587a2a5aa49dbe17cdf12bfa499bcc15fb2139f2773a6"
- eth1_data:
- deposit_root: "0x490811983daeadcb303ff1b7ff46fd6cfcd36dd23b0ce7949b4ee1db7ad695ea"
- deposit_count: "120"
- block_hash: "0xa6354e31dc8b76a24c330aa6be59b256b11155ac456a21d04e4bdfd3a0e56ba9"
- block_height: 121
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- deposit_root: "0x490811983daeadcb303ff1b7ff46fd6cfcd36dd23b0ce7949b4ee1db7ad695ea"
- deposit_count: 120
- execution_block_hash: "0xa6354e31dc8b76a24c330aa6be59b256b11155ac456a21d04e4bdfd3a0e56ba9"
- execution_block_height: 121
-- deposit_data:
- pubkey: "0x8ab4d3a78c54107bd7e71a0a006cb90dec379d6d86c9b6e4b3b010ceb37236cf2566febe76f955dbf0512884215f9f86"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80ea3f9c01a6c761102737733f9e2f0911fafe3bededf9704e219c4537de0ad1cbc4e60a67447e1d25d53c24511ba3640d7aba5362c465042b7dbf40a7a8e0a5e8c002c511c36f7a45411e5770ceefa0571a5670fdf9fd2c0b6a4ca453866f73"
- deposit_data_root: "0x838301a371b334dc75bce42fbac042a519866b7fbd0741fdcacd54b584f1110a"
- eth1_data:
- deposit_root: "0x2d26430bf9f104f9295c2318bb2bd619f41f538ddb1407718bde5af1aa789926"
- deposit_count: "121"
- block_hash: "0x46004bd96b147395928f4342db995e0e5f8c84f6be8479f1713553bbfb32dc2a"
- block_height: 122
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x838301a371b334dc75bce42fbac042a519866b7fbd0741fdcacd54b584f1110a"
- deposit_root: "0x2d26430bf9f104f9295c2318bb2bd619f41f538ddb1407718bde5af1aa789926"
- deposit_count: 121
- execution_block_hash: "0x46004bd96b147395928f4342db995e0e5f8c84f6be8479f1713553bbfb32dc2a"
- execution_block_height: 122
-- deposit_data:
- pubkey: "0x982d829cab4f09be252a2c57b77c166679b7e9fdf6f5cc882462b8f4dc9a90beb303c85af56304fb79b975d3643e2ed1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa49e810bb59cc1194a7ccbd85e6571d2b3fb04372071e9f520bbc6a89f17ce2b4ea4e2efdd7566736e7415c2bb2d5cae19efa75295819f670b2e1a152e8eddda18de95518f2d8ff615f131030635b766504b98a0b72e8470f476ed70c86f3ace"
- deposit_data_root: "0xc8fe237e6c86c9da4429095bdfacab4dc1fd6a8145fb01abad35d9746e44ce9f"
- eth1_data:
- deposit_root: "0x46c5bd8627005a4b9e42e3844469187bec02232d2005a380c126d0c652cab644"
- deposit_count: "122"
- block_hash: "0x3472792b86ec4d8fcb0eafa369176a7c2f0836c1e258a0b136f20dc78c6fb5cc"
- block_height: 123
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x7504f9b600c756a12aa0e36a3cdeb84baf7704f65c12284994facedb4cb7130d"
- deposit_root: "0x46c5bd8627005a4b9e42e3844469187bec02232d2005a380c126d0c652cab644"
- deposit_count: 122
- execution_block_hash: "0x3472792b86ec4d8fcb0eafa369176a7c2f0836c1e258a0b136f20dc78c6fb5cc"
- execution_block_height: 123
-- deposit_data:
- pubkey: "0x908ad5c41ba5fc8bea0cd8f028806a823bda814fcf6c2c32b5656c42b5d3061cfb077ecde2a50bf374e055e8d5dad4c7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb557348bd23fe03c42a128cb692187bc5b6ad278a205080fb475e6fd80ae7ab4fa5d212e3124631fb3c8ba457cb8dfc009e3909b741811b93aa5cd82d8a79e6570c1bc7e21cb62cb4540d7588b1c09803fb8a5c5994b30b8e0675567a94db604"
- deposit_data_root: "0x5f3f0fad8eb6c5f9e0775ec949cdab9b768e3a35ff9f275dfba030661917ee01"
- eth1_data:
- deposit_root: "0x53ae75a6909e9c71ac74676e3a6d8b65f375b54444b70820da477d70eb3146d4"
- deposit_count: "123"
- block_hash: "0x731a443bb391702a1b35eedf368fe11f2707e192e5fa7f0c76cd4b3450486e39"
- block_height: 124
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x7504f9b600c756a12aa0e36a3cdeb84baf7704f65c12284994facedb4cb7130d"
- - "0x5f3f0fad8eb6c5f9e0775ec949cdab9b768e3a35ff9f275dfba030661917ee01"
- deposit_root: "0x53ae75a6909e9c71ac74676e3a6d8b65f375b54444b70820da477d70eb3146d4"
- deposit_count: 123
- execution_block_hash: "0x731a443bb391702a1b35eedf368fe11f2707e192e5fa7f0c76cd4b3450486e39"
- execution_block_height: 124
-- deposit_data:
- pubkey: "0xab4de8ffccf7b19aa6d7d4ccc4c82f091ebd5715b5dd6680edf9eb4f0dfc312e8999b89a78a8d4ed4512aec75a5e5906"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9789f3948b7b284a5082da4e971859ab6d11ebd59bba14e25a5fe9f933148d151f7e831dbbb1d2219a3548aa77b64a970b630ff661ef87608c446c8ee87eefb8728afcc9d3f062955e2059dc22cbe43120777fcc0bc080adf513864869b53a1d"
- deposit_data_root: "0x5968e76b664c7a893bd1d6b4770e2ab6c367986489cb078bf9ebe15a7c37bcf0"
- eth1_data:
- deposit_root: "0xe61360c04f1c6070915102cc3c8e1da6f83689c00802a0a4d9421b597712b380"
- deposit_count: "124"
- block_hash: "0xe7d04b58be7cc09e2efaec16fc8acde80caf3dfe208a1f399464ef1e01c7c6a6"
- block_height: 125
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x000a10f9b9b70f1743febe640ecb94109a63a9e80299df2f72bf1882689e6293"
- deposit_root: "0xe61360c04f1c6070915102cc3c8e1da6f83689c00802a0a4d9421b597712b380"
- deposit_count: 124
- execution_block_hash: "0xe7d04b58be7cc09e2efaec16fc8acde80caf3dfe208a1f399464ef1e01c7c6a6"
- execution_block_height: 125
-- deposit_data:
- pubkey: "0xb544d0df633f2334845f73a3921f2a716b9694baa6abcd7cedfa359ba3448029d5b874eef8b3f9f324f1ff4c0f997e97"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8fb8d58d8be318a8b649c3a74593aeb6c83698850be4571509ef5e2b053e3ace87583b89330b63a804fc56fec750be74030a530602fc80566be34a22b5a37389d036796f48619842b4b4169421c8deef8e745b2873e37fff345fedf94a395823"
- deposit_data_root: "0x69c57f789da4ec1bc1c89fd375a62a159775a522bb17763f98317770d40ae9a0"
- eth1_data:
- deposit_root: "0x0e122e727cad3ae0d09e532df6103c967179b5f7841b6e19b9d224e2abe11a40"
- deposit_count: "125"
- block_hash: "0x2ac76d9635e62e48f43779725791bc2955641b541ce279dfd8a1d4ee43242664"
- block_height: 126
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x000a10f9b9b70f1743febe640ecb94109a63a9e80299df2f72bf1882689e6293"
- - "0x69c57f789da4ec1bc1c89fd375a62a159775a522bb17763f98317770d40ae9a0"
- deposit_root: "0x0e122e727cad3ae0d09e532df6103c967179b5f7841b6e19b9d224e2abe11a40"
- deposit_count: 125
- execution_block_hash: "0x2ac76d9635e62e48f43779725791bc2955641b541ce279dfd8a1d4ee43242664"
- execution_block_height: 126
-- deposit_data:
- pubkey: "0xab77bbaf0047e03ef4bb1ddaefb777f263c9dd556502f3078d51790653a59452f1455d23002e175ec5b541cb69007f8a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x892fdcc974b84026d23901f0772bfcaaf8ed4817e8dd529525658a3f422e8248cad7fa34e9c6d12b3203fe211340b2a90ff420761424d417a446a66c8317f8b120e89c72b7a6ea0e822bfdeaa43fc4efee6568c7f0ce860c9c8499406ba58825"
- deposit_data_root: "0xae683dcb55578a08ab4cc416cbf6f9a4d400f611555ae3572f5be428049c264e"
- eth1_data:
- deposit_root: "0x2d75c60ef0c030b2cf8b18fa80490294476ed31bda31c346ba6c408d54bfb741"
- deposit_count: "126"
- block_hash: "0xea2226b57df5f18306352ff56c91e325260868a83fea4af3100d2adad1cad128"
- block_height: 127
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x000a10f9b9b70f1743febe640ecb94109a63a9e80299df2f72bf1882689e6293"
- - "0xeb193fa7b29a3c6c580bb7006a016eb539a1f3c2d0b529d8ca69462e48200c6b"
- deposit_root: "0x2d75c60ef0c030b2cf8b18fa80490294476ed31bda31c346ba6c408d54bfb741"
- deposit_count: 126
- execution_block_hash: "0xea2226b57df5f18306352ff56c91e325260868a83fea4af3100d2adad1cad128"
- execution_block_height: 127
-- deposit_data:
- pubkey: "0xb56c50c51aa1ba14062d9a477ae78646c459bfe12fc1fa3362f0652077a0ba090a0b780ee0b58085ad2b885fa4a37d4e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85654b45a591e3ef272bf2d4f55ea861e6c06781b79059c0e3a56c07f86d7eef1ceae1d61cdba178078852d34103fc160a9499a05792e08759d15b414a6e174d7d01495fceda5a13517da3b020f4bbf54aadee63765fd78834ba3d6e99a003f5"
- deposit_data_root: "0x1aafc611bf508823603b5049d2bf7238853a3e19edf7af77fb8fd0d4d0057214"
- eth1_data:
- deposit_root: "0xe9a1d8e3b5b5bce6fdcd79c03f4acb7efdd73eb1071a1974af2cfa6f02d40f91"
- deposit_count: "127"
- block_hash: "0xf1097ac5fc5fb25e73c35efe2e9e75acb6cbf842cded0e5912d59f67433c92e0"
- block_height: 128
- snapshot:
- finalized:
- - "0x7a8435cc00762702eb56b993adbe7f3b4f2e490152838e57fbbd87920ffc66d2"
- - "0x09a2fea2eb2470fc221e82ba026e7e9fe417bde2e54fafb68c804dc2a598cd59"
- - "0x0ff1cd5c2a584c83b12d7ad77a2e309ba97738719c0876302ce0ca1e9b02892e"
- - "0x750fa31940eac308088042d159ae2a9895b1c22f1b3aaf2faaaaf448dac52668"
- - "0x000a10f9b9b70f1743febe640ecb94109a63a9e80299df2f72bf1882689e6293"
- - "0xeb193fa7b29a3c6c580bb7006a016eb539a1f3c2d0b529d8ca69462e48200c6b"
- - "0x1aafc611bf508823603b5049d2bf7238853a3e19edf7af77fb8fd0d4d0057214"
- deposit_root: "0xe9a1d8e3b5b5bce6fdcd79c03f4acb7efdd73eb1071a1974af2cfa6f02d40f91"
- deposit_count: 127
- execution_block_hash: "0xf1097ac5fc5fb25e73c35efe2e9e75acb6cbf842cded0e5912d59f67433c92e0"
- execution_block_height: 128
-- deposit_data:
- pubkey: "0x8bc5c1b16286219f479f6d00b0b31b193811b499a86139c45ff4350d8c9b492421e854cf75fba1a0dd566e6ead8ad667"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c322ba5f9cfaffd49ce18217a4351f2bff820017197a676657a1d29d140d41697adb960d340ebf075808ca553bd594713c290beac55aecdc63f96f1da3ea0945360cc8ce7a8de60186ca7a25386a09b17f01d0f3f98c084ff9f998a2ac5fbdb"
- deposit_data_root: "0xfd64f7c42aff4433793cc1eceb1a97ed7e3dbd2f5588cd2c613b99fb2dd7ac03"
- eth1_data:
- deposit_root: "0x8aea1ce3d5cf89b67db5f909d4d50f4db94bd65fe6dba209e245d440a7723c71"
- deposit_count: "128"
- block_hash: "0x87ccd43a65dd5d36c0607edfaef9c6bd9d772e1b41da8140b5f93f23cf5a2c79"
- block_height: 129
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- deposit_root: "0x8aea1ce3d5cf89b67db5f909d4d50f4db94bd65fe6dba209e245d440a7723c71"
- deposit_count: 128
- execution_block_hash: "0x87ccd43a65dd5d36c0607edfaef9c6bd9d772e1b41da8140b5f93f23cf5a2c79"
- execution_block_height: 129
-- deposit_data:
- pubkey: "0xb7eaf282595bd590bde41f67783d12ccf7666aea2f1efbaeaa80c8478a157cf59ca7bf009e5a125163212b0b9f51c876"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5c648bb5cf946f279dd63efdbc85bb7567aeb488fa82fc07094fc2a06306a9bafa1eb70f96d767d1a183838866704cd18157b2e00c7c3ab7c8e97b75533ea364042359d5860aeb6aac63fc88ab600d73e66e10056da3b3149056731fe71f228"
- deposit_data_root: "0xc72d087b5d20cfd70d9183225d0617b9829513337759db9764a466e391605f30"
- eth1_data:
- deposit_root: "0x4e1a7a0cdaa453f648dd2eee6e210e5ce1ced22668c8389b14b69cf390d06e41"
- deposit_count: "129"
- block_hash: "0x1daf3d0631736aff5da169b0fbfaaf76670e04bfb5f1d582847873089630a2c8"
- block_height: 130
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xc72d087b5d20cfd70d9183225d0617b9829513337759db9764a466e391605f30"
- deposit_root: "0x4e1a7a0cdaa453f648dd2eee6e210e5ce1ced22668c8389b14b69cf390d06e41"
- deposit_count: 129
- execution_block_hash: "0x1daf3d0631736aff5da169b0fbfaaf76670e04bfb5f1d582847873089630a2c8"
- execution_block_height: 130
-- deposit_data:
- pubkey: "0xb404c5cda4dad57827e456beecf745b1ed9f2bf776ca0eb806010b80b8912b683c288b4f231bb67c29ddfcdeb16ca909"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89c8d47b8ef9e3282d2e9ba98c4d4cdf0fd362f210564e00a8531640fbbe574206826502ec05ea941cd31a5e591aa1b416230bf0aa78cdf74694681653c2b4e36286aa8d92d4086232d58e6b52096a526d4bbb476961d94202c63182b76b3ab0"
- deposit_data_root: "0xb38f387c64b9c9322cb74515298703ce4922ef2997c1064e4429f037f1609ebf"
- eth1_data:
- deposit_root: "0x5399bcc9eb6e3af50e9fba6c24424fa4df66ae4a13f6b03f7d50045c7c0c434f"
- deposit_count: "130"
- block_hash: "0x80ecd955e11b7c0379a794762c9e233d40df9af56efee83dcade1a18cad09982"
- block_height: 131
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xc712b8c0610483895c01d4680ed4421cc67ee49d0792102971ff4642b82e36c3"
- deposit_root: "0x5399bcc9eb6e3af50e9fba6c24424fa4df66ae4a13f6b03f7d50045c7c0c434f"
- deposit_count: 130
- execution_block_hash: "0x80ecd955e11b7c0379a794762c9e233d40df9af56efee83dcade1a18cad09982"
- execution_block_height: 131
-- deposit_data:
- pubkey: "0x944c4c5147a6b263898f335d2d59177c829d55901e5a4e394c9253cfbba6f0f3ce6ac393aa7b123f7a15db2909aaa37d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa46121a7594f41556fea16a1b3292312880391bce6deb315f12f445e326a2ed77b4a74007b876eaef7c8da205e00e6830bf6436dd332fa280ca379ede2c334279309527b076f1385c9e55da6319b3a534053cd4598a4979b35e136e81f7f2dda"
- deposit_data_root: "0xfc30a2ec2eb7b30f13ac732834306398cda4fc65e4677ef007bec1a3d5dbf18c"
- eth1_data:
- deposit_root: "0x8a0505df56a0bc3b337baea7a403e6076f751267b9b0b32eb3f377a4c7464098"
- deposit_count: "131"
- block_hash: "0x1a51a4d2db3c6a25fac8e8df0962130e493850d808d3a798dbaa7b3cdaea01f5"
- block_height: 132
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xc712b8c0610483895c01d4680ed4421cc67ee49d0792102971ff4642b82e36c3"
- - "0xfc30a2ec2eb7b30f13ac732834306398cda4fc65e4677ef007bec1a3d5dbf18c"
- deposit_root: "0x8a0505df56a0bc3b337baea7a403e6076f751267b9b0b32eb3f377a4c7464098"
- deposit_count: 131
- execution_block_hash: "0x1a51a4d2db3c6a25fac8e8df0962130e493850d808d3a798dbaa7b3cdaea01f5"
- execution_block_height: 132
-- deposit_data:
- pubkey: "0x97dfc5eb14556d1a85e34c069da71fc5e1bb5e17b421d9503f25d76a8f3cd0f2f9c5a1937e785e1c0e73edb6561dd176"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x82d599849169580c5cfe93e84ecf5935ab27dc88447836eb4f9d9d1875d8d5131356e5b220d6ef92de2cc8eb93e6301c0ca1107e2b33a0cfe4a82dcb0cea523bb223e47b91eeb8fda927ac6b951d5741004e2e2340a451649b266df4dcbcb38b"
- deposit_data_root: "0x0efa199eadc389a2e5876ed70eabd6fdb57b124fef39391a43197a06d4d12a9a"
- eth1_data:
- deposit_root: "0x6ff97ae565976870078e1d2df2f544fa9a9f52e522445e9613cbb9d6d0e0ae34"
- deposit_count: "132"
- block_hash: "0x5b5b8e0f913eb2cff3476e7e7cba6efc247b50f863093abe9184daa9c43ffffe"
- block_height: 133
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x21919d31feaad9b4f0198aa85b8c92b9162acdb2be06e4fbb76488dce29f6409"
- deposit_root: "0x6ff97ae565976870078e1d2df2f544fa9a9f52e522445e9613cbb9d6d0e0ae34"
- deposit_count: 132
- execution_block_hash: "0x5b5b8e0f913eb2cff3476e7e7cba6efc247b50f863093abe9184daa9c43ffffe"
- execution_block_height: 133
-- deposit_data:
- pubkey: "0x9145e0920e276f19fe65b9ea81339a41dee6e21ca12512005701a014426322be4fe504f853d6ae48314902fe9ff50a43"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xafaab29ec6f5ea64ebde52ec7d3fc4ec1eca00c799f9b73b51f40a59d8047d2623c7bc92456c3754a79c0b62c722db85113cb8bdcede6b95093a591f43f63098f9d558fb898f4098d6c731534288343e6b23fe04b1b0d36e49cdc03b6a097a51"
- deposit_data_root: "0x8e2528c2d652e704bf50d274aa2f813cab8038b2f0c6242556fe38e4ee1342a7"
- eth1_data:
- deposit_root: "0xc9c06b3a8f036dac268ac85aca78bc258b292b53bb870d6bb65d2e4400eee5a3"
- deposit_count: "133"
- block_hash: "0x5668a8e6259e5716d8988973626760ed0f8f381d0553230e5b74a5a9f01dcebe"
- block_height: 134
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x21919d31feaad9b4f0198aa85b8c92b9162acdb2be06e4fbb76488dce29f6409"
- - "0x8e2528c2d652e704bf50d274aa2f813cab8038b2f0c6242556fe38e4ee1342a7"
- deposit_root: "0xc9c06b3a8f036dac268ac85aca78bc258b292b53bb870d6bb65d2e4400eee5a3"
- deposit_count: 133
- execution_block_hash: "0x5668a8e6259e5716d8988973626760ed0f8f381d0553230e5b74a5a9f01dcebe"
- execution_block_height: 134
-- deposit_data:
- pubkey: "0x836c4b67713b082c060003d8fc839e265c1aca7f9bb82ce07f71a459d39073ebfdca87609859c70e55a1b0e7a613b395"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa04db5e044437271fd78d17b8f68970582937d883f11957506eb5a03e751ee98b10788be39acaa54ac43fdaf233d17470e7cbdaa7696e13a095e4cc2f1198e080f7d263b0e2f94f987d111ff479a24707b426aadee55e9df8aed27cf2f214c87"
- deposit_data_root: "0x3a112eabe9f6e71d1909cef64d68d32ff8ceeeed9247f628babab96f83f4c748"
- eth1_data:
- deposit_root: "0xff0787b73d84f56a8d8c4f58ee259b2a799758380be7452d30200be34a2b1697"
- deposit_count: "134"
- block_hash: "0xf158ad39fac4114d21115c72d76ef1486378b8bb3972904973e3bf415093e86f"
- block_height: 135
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x21919d31feaad9b4f0198aa85b8c92b9162acdb2be06e4fbb76488dce29f6409"
- - "0x27ef184d8974736eab9799399f71b459bd5a849f57939017510488c06a92471a"
- deposit_root: "0xff0787b73d84f56a8d8c4f58ee259b2a799758380be7452d30200be34a2b1697"
- deposit_count: 134
- execution_block_hash: "0xf158ad39fac4114d21115c72d76ef1486378b8bb3972904973e3bf415093e86f"
- execution_block_height: 135
-- deposit_data:
- pubkey: "0xb5217af9139deb6be95a106c7651e1d8dcd8eaa04f3c6196dd52abad84c862724603686f90c7c2a985f2d75a1c8facdc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85a96d2f00884fe1e363e875256bccc230716611daa78efc84425b051008e606401bf9b5413b9b8f806b2177cf7d1cf20cd75f895c8a69c7cb59ff553af9fcc1dbb33c360a1834daa1efb5fe57322303fabde1f93e692c96b4bbfed668ab6268"
- deposit_data_root: "0xaa6054d15854b80f7ec7eaae6dee3a436a3fbc7a5b960d5a63b87cda94d45467"
- eth1_data:
- deposit_root: "0x450e75beff47dda09d642c64023e985bb9b4084c3ebb3fd93cee4ff6ecedca3f"
- deposit_count: "135"
- block_hash: "0x768e4089d2988baf80e8a20e391ae3827a2018cf543e42831949ee31d9abcb51"
- block_height: 136
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x21919d31feaad9b4f0198aa85b8c92b9162acdb2be06e4fbb76488dce29f6409"
- - "0x27ef184d8974736eab9799399f71b459bd5a849f57939017510488c06a92471a"
- - "0xaa6054d15854b80f7ec7eaae6dee3a436a3fbc7a5b960d5a63b87cda94d45467"
- deposit_root: "0x450e75beff47dda09d642c64023e985bb9b4084c3ebb3fd93cee4ff6ecedca3f"
- deposit_count: 135
- execution_block_hash: "0x768e4089d2988baf80e8a20e391ae3827a2018cf543e42831949ee31d9abcb51"
- execution_block_height: 136
-- deposit_data:
- pubkey: "0xa38b021855057c62bac15b2de83156dc8649bad858327b10cbab68c8fa3613a3de698322826d2644652ca9ef92664cb3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa8634b7543bd89635688f7842e0202b9430332a39d6ad9670277543387708e06466c21747af713f1c6cdf62f78e96411191d7bbd079322d3c6bbf1fc4f739ca4f6a77b304566a3a77768188efde4e240fa78245d5943a3a601192112a334a76"
- deposit_data_root: "0xfef7a5178631d697d14133c15287f33d6a2ccb3e6efe5dd46022965eca0f23fb"
- eth1_data:
- deposit_root: "0x9825f4b4b017dde1e6fda6ebb8a809409d57cc060bf19d44a9a898a26f75d50e"
- deposit_count: "136"
- block_hash: "0x051c8ee04d7535b585729a7ead7016d35ccd323e274e39a000a4d302bf454de5"
- block_height: 137
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- deposit_root: "0x9825f4b4b017dde1e6fda6ebb8a809409d57cc060bf19d44a9a898a26f75d50e"
- deposit_count: 136
- execution_block_hash: "0x051c8ee04d7535b585729a7ead7016d35ccd323e274e39a000a4d302bf454de5"
- execution_block_height: 137
-- deposit_data:
- pubkey: "0x828b5be17d71a278644b6fbe7ab5fd3a065312d1b03734e0b9d74703a566dc99815c81fc50b13725961376edc2f54405"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89235bcafefc07c6ed61bc483071b76d22e0881272925d61d8178942b701797d907ad10a3ef967df5f647863540e70d6052ba3814abffac5acb8bcadeb41b9c393dd2d664871535e6984725c7cdac5c1433abb7e05f06adcf75fd2c3a8e096f3"
- deposit_data_root: "0xae3d1bd187858e08287ed35692a78547ca791719a1cab975707b4c4c023d1f12"
- eth1_data:
- deposit_root: "0xf52b85738cb675d5d8f894f5653ed2e05cf513faae7dbec06e9b1841510d3bdc"
- deposit_count: "137"
- block_hash: "0x0bfaadbce1850c4917a8e7b161d3c926ce11488ae996ade89332e76c3c26e30b"
- block_height: 138
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0xae3d1bd187858e08287ed35692a78547ca791719a1cab975707b4c4c023d1f12"
- deposit_root: "0xf52b85738cb675d5d8f894f5653ed2e05cf513faae7dbec06e9b1841510d3bdc"
- deposit_count: 137
- execution_block_hash: "0x0bfaadbce1850c4917a8e7b161d3c926ce11488ae996ade89332e76c3c26e30b"
- execution_block_height: 138
-- deposit_data:
- pubkey: "0x956aeb449c6e00e75a7795ea552bb0a2c14e065bfc9fee78c5a337f9d0c1814045802ad4f2e3c60868e54cd381809cca"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x819db83518bfe3262416f3592dc4a98a7811decc1c2e3b75adbec61e503cf31adc93bb0ab7167f5cb5659a4836dbb047141c61f810b392c68f8abba9699131fef029ad3ed054895b35c599460a3c3c25a9c0290bd3d4a51806cacef247589af9"
- deposit_data_root: "0x7863ebf9d15b7d7faf3eaa9c5921396b467c452ae27d2a17cf873fd03ebeb5b4"
- eth1_data:
- deposit_root: "0xa5000d5a716be585c7263959af46459fe207ccfee4b131e340db755d7841b6e3"
- deposit_count: "138"
- block_hash: "0x7e3ff3c5214e2e9d1bf033fbd58772d2df71241ff00f285e467559ba2c435729"
- block_height: 139
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x4e197bcd1ccf6d1ef8b4b3c658d14cb45b72045390d6afc86479c562d99290ee"
- deposit_root: "0xa5000d5a716be585c7263959af46459fe207ccfee4b131e340db755d7841b6e3"
- deposit_count: 138
- execution_block_hash: "0x7e3ff3c5214e2e9d1bf033fbd58772d2df71241ff00f285e467559ba2c435729"
- execution_block_height: 139
-- deposit_data:
- pubkey: "0xa0ab6917fd4c65ff95b1a5ed5f3c0d7cef103de58a90f2cc5383b4914566aa085f04e8505c862a29a0c914072746f83a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b99987e93032d8d9d07d726957fe4394b818ee34dec214aa6dcdb1469f0ed7aa0dfeb4ed805baf48ef287f97b9058140262f05105769e65decbac6d3df02f712cfb0ad7a2ff65eba13fcc167d94d993f8c3148143731d4eb028ec23902443a9"
- deposit_data_root: "0x4fc27de5f8c8d68da0bb0258d0151521fbac62e4967c08b8876cd976ba113e59"
- eth1_data:
- deposit_root: "0x270aab20e630999f0ebe072b5f955d7d0b6f0919157002eab351eef7873a9b1a"
- deposit_count: "139"
- block_hash: "0x294cb83538800d76ddc52bd16c33ff956de7f5b94d9419178b50824aefeed6b5"
- block_height: 140
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x4e197bcd1ccf6d1ef8b4b3c658d14cb45b72045390d6afc86479c562d99290ee"
- - "0x4fc27de5f8c8d68da0bb0258d0151521fbac62e4967c08b8876cd976ba113e59"
- deposit_root: "0x270aab20e630999f0ebe072b5f955d7d0b6f0919157002eab351eef7873a9b1a"
- deposit_count: 139
- execution_block_hash: "0x294cb83538800d76ddc52bd16c33ff956de7f5b94d9419178b50824aefeed6b5"
- execution_block_height: 140
-- deposit_data:
- pubkey: "0x93e08f94b3c1e5e9e7454185c5493111db66673fa0f1ba86d7a395858a32fd2c2ccd0c4838affb453112f0e9a8e3a370"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xadf8d364f8bfd7352b5423ec6e9891d9dda14132bb5fca8ec977b3eebda7df0e67a3dbf69e7c470714ef28028cb4190b18c5c998b8ec2d65089e4f1e89ef078c3b3d20f8a1c223a4d19cf7b6fe94be511c6633da6d64f2c60148926bb05f284f"
- deposit_data_root: "0x394d27e70621db71ab9db062b080a827591c330679e0db882e6086d1ce0004df"
- eth1_data:
- deposit_root: "0x6a884aaac611577d4a3e6b1beda285d44e45c7908553df6142fcf83dfb30dfe2"
- deposit_count: "140"
- block_hash: "0x2ce6dbcabe45faa4be2c1f491500699fab5011beb8f8edfa6125188d5c75f474"
- block_height: 141
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x94db8bffb5c1311bba8a0713a8cb1ae95ce40c9b0dc482ffc6273482df8a11eb"
- deposit_root: "0x6a884aaac611577d4a3e6b1beda285d44e45c7908553df6142fcf83dfb30dfe2"
- deposit_count: 140
- execution_block_hash: "0x2ce6dbcabe45faa4be2c1f491500699fab5011beb8f8edfa6125188d5c75f474"
- execution_block_height: 141
-- deposit_data:
- pubkey: "0x907c4f53d28167c96d711746d338b7428e7ffa389ec76497920c25445df3b1ce7e88648a5fa9f4e1b5d2d254938bb65a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb718c98631b6896423bc477b0c6b6c38aad77af35657008c27a760225c17f1d83244c9e67b031d1ff54696774c9e03a70397a5377b9ee1a4f05b4086659fefcad9e8e8992feefa489b51e35063789424dda7cef6c87a5a52ffedd58f87e9e1dc"
- deposit_data_root: "0x27c015fcfe5104cd1c8d15aefb823bde65e61ea352c3b2d2886eb671caa5e700"
- eth1_data:
- deposit_root: "0x34867700acac7b229aa98c88283ca0967e781d7640ffe43521d8f32a43b44521"
- deposit_count: "141"
- block_hash: "0xdd2ca2e628c5fe5f8e641e57a076568b40c0a85522cc2e0860f38eeff295e68f"
- block_height: 142
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x94db8bffb5c1311bba8a0713a8cb1ae95ce40c9b0dc482ffc6273482df8a11eb"
- - "0x27c015fcfe5104cd1c8d15aefb823bde65e61ea352c3b2d2886eb671caa5e700"
- deposit_root: "0x34867700acac7b229aa98c88283ca0967e781d7640ffe43521d8f32a43b44521"
- deposit_count: 141
- execution_block_hash: "0xdd2ca2e628c5fe5f8e641e57a076568b40c0a85522cc2e0860f38eeff295e68f"
- execution_block_height: 142
-- deposit_data:
- pubkey: "0x987b620dd2ade22c44ac3a642d17ac9009da6c2d989028957da877e5178668216cb9ad2314a520ebeeb8b032614ca2f7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5294d4bad5d63db39d236813cbc1032093b8c7649d28b4b2515c03855f56d78ee8b243e6b29935d83d6a9ce344d2ae618894c91dd7cd82eebe2020938f55ee77b95118ecfc2a80792b23e75251396cb09edad531138fc2129d3442934472fea"
- deposit_data_root: "0x55bcef5f8cc010243428b8c8d96fa0cade22f5df82fdd813c337482189f7d33e"
- eth1_data:
- deposit_root: "0x6343479ad51df7360082d3c7736a119a9cf461dfe40f749490b98cd60c48b1d8"
- deposit_count: "142"
- block_hash: "0x3fdc183d26e681a76cb366df8540c48422832c01893da752c20c02764f3e42ef"
- block_height: 143
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x94db8bffb5c1311bba8a0713a8cb1ae95ce40c9b0dc482ffc6273482df8a11eb"
- - "0x61ecb3ba1163a8bd70a0c91060a0d7df5c5f1d429222c6da2628d42f51140b8b"
- deposit_root: "0x6343479ad51df7360082d3c7736a119a9cf461dfe40f749490b98cd60c48b1d8"
- deposit_count: 142
- execution_block_hash: "0x3fdc183d26e681a76cb366df8540c48422832c01893da752c20c02764f3e42ef"
- execution_block_height: 143
-- deposit_data:
- pubkey: "0xb4bb3db19f9162fb238ddbdbf5b8e819696e90783775249825d64767625f2b6e9c52edd859bf8afac8a87371e9100d24"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xadbff5ad606002d50ac669f878194974fb3f338b8301fb46426e92b4e65309b1eabf85441ddd75dadd6eec5293ee05df0860040dbf875e698cb23cadd960b8eb23674a86795bca545385e8b03b847ab4ac7970a6b2a73b960e54866b11fbd1ab"
- deposit_data_root: "0x79b12382ebfde996e7dc957b826c432d14eb7f3a3b61c61800707f60c4bf193a"
- eth1_data:
- deposit_root: "0x4095812eaf8df557e3e6c36dd16b99952769d623281342926d22b6d07d270553"
- deposit_count: "143"
- block_hash: "0xc782ae505c8831621b6d9afd7fff61d359f1d39248aae61504d561695fbb8d10"
- block_height: 144
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x52228e1e54f9b75dbb4c3e67d77e36c395d945cb6a4b5494c18eb1218db1ebb2"
- - "0x94db8bffb5c1311bba8a0713a8cb1ae95ce40c9b0dc482ffc6273482df8a11eb"
- - "0x61ecb3ba1163a8bd70a0c91060a0d7df5c5f1d429222c6da2628d42f51140b8b"
- - "0x79b12382ebfde996e7dc957b826c432d14eb7f3a3b61c61800707f60c4bf193a"
- deposit_root: "0x4095812eaf8df557e3e6c36dd16b99952769d623281342926d22b6d07d270553"
- deposit_count: 143
- execution_block_hash: "0xc782ae505c8831621b6d9afd7fff61d359f1d39248aae61504d561695fbb8d10"
- execution_block_height: 144
-- deposit_data:
- pubkey: "0xaa083a83471b7938693e54b673d98f90340fe5cd2556b27eeb9c9069b7150e853391d47543dab155f6fdc8ab7f2e185a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaf55c3b8d00ede905a7e5a546aef5e817f540950cfcb04fd86a16f4574897c7118d1a971cb06018ea5a8d59b673a6e19060462b839135255e8790d9c2152fe2497f090027242091f0fa19d957524046f920b4e980631216d9ad88ffae00894ab"
- deposit_data_root: "0x62f0c56109eaf759c780578e7fa47725568ac9c4b417a79f75e0778b98f8dac6"
- eth1_data:
- deposit_root: "0xaab06426f70faa1c4f596a4f42f15dcfff709218d7f4c479835e15d0f7612f82"
- deposit_count: "144"
- block_hash: "0xa8bd5909dae96b248a94193373f3ebc4050994aee8ec82e5eaf61530e66ba126"
- block_height: 145
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- deposit_root: "0xaab06426f70faa1c4f596a4f42f15dcfff709218d7f4c479835e15d0f7612f82"
- deposit_count: 144
- execution_block_hash: "0xa8bd5909dae96b248a94193373f3ebc4050994aee8ec82e5eaf61530e66ba126"
- execution_block_height: 145
-- deposit_data:
- pubkey: "0x916d306c24956c1a97678695330d240cb492062889dbfbaa6349cf53259c719ef83748b065e4a30fa6edf8a171af326b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c8963319e8e7e3dab0c8048410b8818fa648f4a4e337d06d2226e5732ce99e8089103886812055eee70315a028ea5b3044691168068d150967f6dd432e585fdfc9ac2d5b593add5e671ec6a1ef1fecf265fbe43f564b1d63ca3ed6dc1d1d49d"
- deposit_data_root: "0xb779d0910d0c595a2fe92c63c2e8882f2e0db6c55f749864cda06e9ab53a1175"
- eth1_data:
- deposit_root: "0xd41b2fb56eabbe8a5494e16f53677b85e8329a31bc1b106c57e0d67ec4f08c2b"
- deposit_count: "145"
- block_hash: "0x59e61e4cbfabe9ebff9d7632bd4946b9b34b40bd189866c9d3a300f7e88584ff"
- block_height: 146
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb779d0910d0c595a2fe92c63c2e8882f2e0db6c55f749864cda06e9ab53a1175"
- deposit_root: "0xd41b2fb56eabbe8a5494e16f53677b85e8329a31bc1b106c57e0d67ec4f08c2b"
- deposit_count: 145
- execution_block_hash: "0x59e61e4cbfabe9ebff9d7632bd4946b9b34b40bd189866c9d3a300f7e88584ff"
- execution_block_height: 146
-- deposit_data:
- pubkey: "0x89d9aef34711c5ea0787f591e4683f34727391729c0a402702a51de4d6a36a9324e1c77890a1b34c70a06d30bf9cb0c9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa558bdece7dc28e7a68298edb2b4d9277e21c590ec58c8e9cbf85560ce442eb91b5d35be159961dded127f612a232bff0b8df1043e6d592a498d2f672032a443e3a235337b2aeb596cc24bd20aab9001357399c450dd911107e6860e061bc6b2"
- deposit_data_root: "0x952e03098c3a3e617b2085b2f360883902c7560615ef16f06ad87aeef11d4b13"
- eth1_data:
- deposit_root: "0x42a6aa131d749068ece539bb5dd92c0b35abadaf3fdd09e6dbbfbe3a9864a4de"
- deposit_count: "146"
- block_hash: "0xdbdcb5286172a0827e2cf09afb3ec1a5edf6210eceed78570a82ec9b985793ef"
- block_height: 147
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xfcb2cabbd2e78c7299e4090c745a5f70f964f9609e16ef7dbf822ec6be390b5a"
- deposit_root: "0x42a6aa131d749068ece539bb5dd92c0b35abadaf3fdd09e6dbbfbe3a9864a4de"
- deposit_count: 146
- execution_block_hash: "0xdbdcb5286172a0827e2cf09afb3ec1a5edf6210eceed78570a82ec9b985793ef"
- execution_block_height: 147
-- deposit_data:
- pubkey: "0xa3cc6919919abf050a3e64b6c5d826148ee3f766e6b67e7e8000645e51ebed1b9c6a20b9b7413a4eb835529cbe4f77a9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5eebafdde0dcf96d9ed536932dac3368f11890a1c9047ce33777dd864b8edb96d627c643dc10a1ad25704bdc94a10d81163c449b7cb1298523fe6817f78d6c99a89bea5c444452057a26a8002b66129b895f24ca1e5594b07fcff0734df654d"
- deposit_data_root: "0x416f86acf71961090832d765a7a736ecf18cbb6a1fd9f1e42ba0ba99abcc5a1c"
- eth1_data:
- deposit_root: "0xd0c5fe81027e3262bf1682a130fb3952371006f707a02c98cef95952e116b566"
- deposit_count: "147"
- block_hash: "0x762506294eb00ae05c84543d9b495e2b0b24047aa0ff1d747ff474498d1176eb"
- block_height: 148
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xfcb2cabbd2e78c7299e4090c745a5f70f964f9609e16ef7dbf822ec6be390b5a"
- - "0x416f86acf71961090832d765a7a736ecf18cbb6a1fd9f1e42ba0ba99abcc5a1c"
- deposit_root: "0xd0c5fe81027e3262bf1682a130fb3952371006f707a02c98cef95952e116b566"
- deposit_count: 147
- execution_block_hash: "0x762506294eb00ae05c84543d9b495e2b0b24047aa0ff1d747ff474498d1176eb"
- execution_block_height: 148
-- deposit_data:
- pubkey: "0xaa70cfdc554a8e67bbd3e6f3d2a0ef61c2a7ce1784acef01e9d7f08ee3a4723c2b7bd789c4bb687f19466a58e6e7bb34"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x937471d746fdc9d2bdc43b70133bf53b8c934685e3a220b02d6615648ff1c2d17afe93e5e8844825a1e71e30269e703d02cf89a01ea5737c58964ecbb42ec4736721f66cf549231b1baf839ad3775665ee3db8f5af6c7abc76fe4985e881f3d9"
- deposit_data_root: "0x11fa92b165b8cdd90432e623dd16b219357f7258304be89741c3748fc2b07281"
- eth1_data:
- deposit_root: "0xabbeb3c7c12ac8ea30a18ca7f4953f788c6d7b6d28375d597ab8188ae4750442"
- deposit_count: "148"
- block_hash: "0x49319e6b9bd5b42ee760b78a016ff8c3472c40c0aa015f6f64c26f8ec9b73da4"
- block_height: 149
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0x2f36ad9e26bd49169087381023a518ca363e37b699bea22fb07fe8fc2da3721a"
- deposit_root: "0xabbeb3c7c12ac8ea30a18ca7f4953f788c6d7b6d28375d597ab8188ae4750442"
- deposit_count: 148
- execution_block_hash: "0x49319e6b9bd5b42ee760b78a016ff8c3472c40c0aa015f6f64c26f8ec9b73da4"
- execution_block_height: 149
-- deposit_data:
- pubkey: "0xa1a1b99827c25c1079d4ed035a31478a38c2141db49291d0fcd10b64eb6ee5b0d9e758a9b47f40b2092f1c150bc28e11"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa843d0ca06dc76c42f57ccc9a5f50b5c17f39135ed33d3eef9a9b88826c3cf5dae2e1991f40163184ed4cf375d37ac2f147c75eb8b4e3790ff510008c0960eec1c5bca5af9c7e4ddf81277acdfe4f264cbd5d1cc1608b0f3db2fe000e2edb789"
- deposit_data_root: "0x1bc04fb54834e25adfacf21f8408527b4ada1fb47d5355cf0024436cadb5df12"
- eth1_data:
- deposit_root: "0x4165f4725bc2e58cef28e6a287ba3fd6bf46f445fc65b67d383d7d6b7bf709cd"
- deposit_count: "149"
- block_hash: "0xc5a9ec49e34f270b82dd423e53c924b72387fe2987f8b0ba039efaea92a57b63"
- block_height: 150
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0x2f36ad9e26bd49169087381023a518ca363e37b699bea22fb07fe8fc2da3721a"
- - "0x1bc04fb54834e25adfacf21f8408527b4ada1fb47d5355cf0024436cadb5df12"
- deposit_root: "0x4165f4725bc2e58cef28e6a287ba3fd6bf46f445fc65b67d383d7d6b7bf709cd"
- deposit_count: 149
- execution_block_hash: "0xc5a9ec49e34f270b82dd423e53c924b72387fe2987f8b0ba039efaea92a57b63"
- execution_block_height: 150
-- deposit_data:
- pubkey: "0x87af7702ff5e6e9a4416bbb516c3aeec7827408b75e3d1a8d420031157ba7a5a4d1eb565d29f100c5cdaddc05399bce1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xad97e9253436103fbb79067fea41d3db0b36abbbf2c9a345ac838a16b93ebc6fa0414bbe4c96514c67dfb5e4d207df200bb413b4ea1be94dbaf9d008c49aeb2fdd0552dbcf171e0f8a6fa89bfb6139d606b5ed0765b4047c489999bcbac53c24"
- deposit_data_root: "0x1d331b2e13e8ff1333f00c80b5de05a294bfeb904d782e6636461a4ec01cca24"
- eth1_data:
- deposit_root: "0x5f04ee7b040e36e61c3abf826d86c178cadd08541f545298c02d6fcfe7defae5"
- deposit_count: "150"
- block_hash: "0xe44b8c19d80353eaaebdbad5689d94f2c68ce2977dd2c687ee64560e75bd46e4"
- block_height: 151
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0x2f36ad9e26bd49169087381023a518ca363e37b699bea22fb07fe8fc2da3721a"
- - "0xdecd5c32fc1a5a55f4b2dff4cefc1b493884d7c78f74b3d9c399f3a583ba4aa8"
- deposit_root: "0x5f04ee7b040e36e61c3abf826d86c178cadd08541f545298c02d6fcfe7defae5"
- deposit_count: 150
- execution_block_hash: "0xe44b8c19d80353eaaebdbad5689d94f2c68ce2977dd2c687ee64560e75bd46e4"
- execution_block_height: 151
-- deposit_data:
- pubkey: "0x8db57d195b1216309f3182f522ee9c6a724af5eebfc8faf058edb4e444a74f7ca9fb0f227a7960887abf8ec4697ef4d2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac2c9dfc4a9bfb53a71b7647109bcf478924d240e2501655e30e4fa4db22bd7f004513f5600dc19cd66141ecd1ff775904b8085d23885c3a414fb8883bd7676b32f008dd84beb2e32ff444a9e7c047cb2884ff998644aa5ffde04acb7a1a952a"
- deposit_data_root: "0x664b99054c780ab51854845d95d8ccad24d1f9a45fbadf4f04664f9e533da249"
- eth1_data:
- deposit_root: "0x1bece2bb88b659bbafbd110cbc8d8765c5488f30389cc03a4b48730f8324f501"
- deposit_count: "151"
- block_hash: "0xc5ed7232fa2461e41d333f13bfd2e3e7f113aef12fe4e465f1c9ad345f140679"
- block_height: 152
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0x2f36ad9e26bd49169087381023a518ca363e37b699bea22fb07fe8fc2da3721a"
- - "0xdecd5c32fc1a5a55f4b2dff4cefc1b493884d7c78f74b3d9c399f3a583ba4aa8"
- - "0x664b99054c780ab51854845d95d8ccad24d1f9a45fbadf4f04664f9e533da249"
- deposit_root: "0x1bece2bb88b659bbafbd110cbc8d8765c5488f30389cc03a4b48730f8324f501"
- deposit_count: 151
- execution_block_hash: "0xc5ed7232fa2461e41d333f13bfd2e3e7f113aef12fe4e465f1c9ad345f140679"
- execution_block_height: 152
-- deposit_data:
- pubkey: "0x8cd26495562e8fa526dd3dd5ccf7706e0b802747a2858ca76e4be7e9188ecaaf095b7ba58cf504057c4039e990f88618"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8370ace5a4fcd6231c5bab72652d4f508a407e5d7b177ff034ca82a1efd0d06b23b618f17268d7ab67f5a964beec59e0d929c6b611092e67099be102b77782d704d63da4e6137bdff977eed1e526332624e5c052bfa16e71b9296ffd5f4e1ad"
- deposit_data_root: "0x82ae1b44b3e9bdcf2b48fdf000acbfbb762153634aac9d5ed5663bd6fe57ddd5"
- eth1_data:
- deposit_root: "0xa0a5548e34617b4b07307f5e80a50b88320c59ad0b655a8b3d01f7e77b96cedc"
- deposit_count: "152"
- block_hash: "0x42f0b6cc26d7613b3658fa113804dfc7624a3672887ca41229f9000a5f1eade3"
- block_height: 153
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- deposit_root: "0xa0a5548e34617b4b07307f5e80a50b88320c59ad0b655a8b3d01f7e77b96cedc"
- deposit_count: 152
- execution_block_hash: "0x42f0b6cc26d7613b3658fa113804dfc7624a3672887ca41229f9000a5f1eade3"
- execution_block_height: 153
-- deposit_data:
- pubkey: "0x95d668e777610672265275332a570af04c1a6090d9caae5152b66d476a7ac895c120e68724bdf30d3a51ece24a76b225"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb0bd20a856159c8ce771848cc33ca90aebe6bd56f8537a2ceed4a3a043cb448d489342b299bfcca3333a3f10c7c483780b335c78197a348eb2d0d28cf16e2a50368478693799d9b46076fbae6981732deacabac0bfe9747c5642477fa3718e59"
- deposit_data_root: "0xf952d77f6747501c8f12ac319fc9b537ffeb20e38afc5ff9046521c27076607a"
- eth1_data:
- deposit_root: "0x77bd65842bb2ab1513449bbe102333c0bd621424fde5d37257a32c3d26eaeb5f"
- deposit_count: "153"
- block_hash: "0x9af33652ee1b895df878aec4adb356e1bee86181c4c6117a1bf4ad21c1258669"
- block_height: 154
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0xf952d77f6747501c8f12ac319fc9b537ffeb20e38afc5ff9046521c27076607a"
- deposit_root: "0x77bd65842bb2ab1513449bbe102333c0bd621424fde5d37257a32c3d26eaeb5f"
- deposit_count: 153
- execution_block_hash: "0x9af33652ee1b895df878aec4adb356e1bee86181c4c6117a1bf4ad21c1258669"
- execution_block_height: 154
-- deposit_data:
- pubkey: "0xb37c32301c15cf9a62fdf10ac221d751918f78ca95cf7f79b5a3828fe77c88561cdf863454133bc4bf56e6209b53d0d8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8938e16203e369321f5e88d883f7ee521005230d74981fc6ccde25b775982cefbe88888ca720bfb48b2f77aed3d849221874fb97dde7bbe699cb17b397bdf72fbe580302fdcde9dff66c2567a1c518c63eb4a923619918ff18e76167c184c017"
- deposit_data_root: "0xbcb802dd617c023460f14a9e490207b829016a9b88cbb44b87fbd9fed9a00452"
- eth1_data:
- deposit_root: "0xece431b6b5a2d074c528e73dd8a1fc686e167dcf3575e118deb1c012e2beba56"
- deposit_count: "154"
- block_hash: "0xacd9c61ebeadae453909aac86b39107821848a4c7e85e7ae99fad8f46c09c5dd"
- block_height: 155
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x11665987a6e900976d175d96c7ec5ddf750a00e89237cba75d596b7355553279"
- deposit_root: "0xece431b6b5a2d074c528e73dd8a1fc686e167dcf3575e118deb1c012e2beba56"
- deposit_count: 154
- execution_block_hash: "0xacd9c61ebeadae453909aac86b39107821848a4c7e85e7ae99fad8f46c09c5dd"
- execution_block_height: 155
-- deposit_data:
- pubkey: "0xb923cab7abb3e0b5a8ca7b841662262014e59dd8ab24ef4513ef5fc1c85dc1860bf4fee2565a732a7df4dd73ff638403"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89fb7bcb413178f88f843949a819180630d0651d184fea6bbba521e241c52834e9c9b1ab7496d6791f99b3cd4c0d23cc15b3ccb9893badbc524e1e67b027961c3d43661348c6a938c87f573d0f59919db632ef38279b28e03593e4bb9d1587bd"
- deposit_data_root: "0x0c4afbd64a8f690f413bb4eb4ba458f8af3c57cb27ef5043155e5ae329db963b"
- eth1_data:
- deposit_root: "0x5699749c403acccf444931ff8920ea52316ce8ba01b47566db967ac82998be4b"
- deposit_count: "155"
- block_hash: "0x5b56da2713e1546d90efde2fce7553310399d03774f4495e3ddfab74615c91e1"
- block_height: 156
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x11665987a6e900976d175d96c7ec5ddf750a00e89237cba75d596b7355553279"
- - "0x0c4afbd64a8f690f413bb4eb4ba458f8af3c57cb27ef5043155e5ae329db963b"
- deposit_root: "0x5699749c403acccf444931ff8920ea52316ce8ba01b47566db967ac82998be4b"
- deposit_count: 155
- execution_block_hash: "0x5b56da2713e1546d90efde2fce7553310399d03774f4495e3ddfab74615c91e1"
- execution_block_height: 156
-- deposit_data:
- pubkey: "0xa25d1dd7f5dc5ed5aaba0187d33ee72921d6455b6052c657d87e108aaeee9c31c53701e7b288ae0f9ca74cae34a1f49c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x918558e2fb2ed8d33bc35cbb6794dce54fdc363d07eb66d2b8def16d8ff28be953d0d2b9d4207e6f1b4157aecfba99810472a8ad6fcb41a6f968a83c82cb140ba8bf1bb947f742ad470f4f3b83d447e38b925578e07f421c6a518a57b23dc84c"
- deposit_data_root: "0x069c4690e4914d5b8fb41fbd74c9205c5ef329affcaf903ec8293ccbf3943bcf"
- eth1_data:
- deposit_root: "0xf287114b93614b301a10c43ed09504c14298377eef05000f902e4cc5ec7daef6"
- deposit_count: "156"
- block_hash: "0x9bdce9e95c9fb72c2018eddd357e19ad47107c224bae328531bdd0716e7e500f"
- block_height: 157
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x5cf0c39a7fa083994f7baf809c387f9ab82024f5f1bb1e9badc5d3b26c5c2973"
- deposit_root: "0xf287114b93614b301a10c43ed09504c14298377eef05000f902e4cc5ec7daef6"
- deposit_count: 156
- execution_block_hash: "0x9bdce9e95c9fb72c2018eddd357e19ad47107c224bae328531bdd0716e7e500f"
- execution_block_height: 157
-- deposit_data:
- pubkey: "0x824904d20a5620ca46c015ff630e1e26fead9df53243354ace937f01a971916e8883687a8e5f087598c633a91d0d6fbd"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb238a8b1da5862bfce25d25b502130c2809263d257efdf8eef3da05a7b75b70f463f57a7c14e21b5853dfb404a6e3e66017f1d987fb634500fe403fe0ee06f0a329108af069c05b429dfc2b0ef87d7a384dfd10ed0d7b0ab82d335ed33bef84d"
- deposit_data_root: "0x1147a26009ddb6d159aad698f440619d7503b848807e09679dcbd58bf1b3a899"
- eth1_data:
- deposit_root: "0xc7307a5a78027139f9a0fcb9ec77193528b7067f2468b26ba79f6155fa579205"
- deposit_count: "157"
- block_hash: "0x1f02f863183c9f6f57bf3146745f7461290f64f73065bcd52e065e97ca1f4ecb"
- block_height: 158
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x5cf0c39a7fa083994f7baf809c387f9ab82024f5f1bb1e9badc5d3b26c5c2973"
- - "0x1147a26009ddb6d159aad698f440619d7503b848807e09679dcbd58bf1b3a899"
- deposit_root: "0xc7307a5a78027139f9a0fcb9ec77193528b7067f2468b26ba79f6155fa579205"
- deposit_count: 157
- execution_block_hash: "0x1f02f863183c9f6f57bf3146745f7461290f64f73065bcd52e065e97ca1f4ecb"
- execution_block_height: 158
-- deposit_data:
- pubkey: "0xaed2a3ef693d13698e77966b8125442ac40ee0a62e8d97f71493c966da3c8604932dcee09606c2394afed25f8ad4f31c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8e2b32b5180bba930cd1d405258ec2cd4a7dcc0bba374a4da4e57ba6084db5341db349348413d6385fd336cd476eb1e41396bfb8201727239547f3f175b8baa7b0c98de9aca97fe7226a5fc354e7d16c39275ac3ce5bd36f3fa5ffbbbba1e4ab"
- deposit_data_root: "0x1e35604482803af5afed89b925dcb5e9f41ab291388918e7b317d467e8bf2aa8"
- eth1_data:
- deposit_root: "0x6858813a05b486da3ccdcc7c09b56d5a96b1396a594ecf561ca209e7273d2153"
- deposit_count: "158"
- block_hash: "0xd52fe7ca49fb3425010be4c5fc698606361cdbecd68ef63800d013391b53939c"
- block_height: 159
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x5cf0c39a7fa083994f7baf809c387f9ab82024f5f1bb1e9badc5d3b26c5c2973"
- - "0x431fb43239425b2f4faf58bbfc2e8bf64202d513954ef412ee9154052f667c4b"
- deposit_root: "0x6858813a05b486da3ccdcc7c09b56d5a96b1396a594ecf561ca209e7273d2153"
- deposit_count: 158
- execution_block_hash: "0xd52fe7ca49fb3425010be4c5fc698606361cdbecd68ef63800d013391b53939c"
- execution_block_height: 159
-- deposit_data:
- pubkey: "0x8f8ac057107bc490de273453730753b9e2b69df03917a0addbfb13c5152d93fa05702cf21d8b58ed7c08ac3295c1de3e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb799bc548db09f68b31bc25159d865b5925ace14d63cfa21af51f8e822d85b6221ad968839f1bc57e8218e5a8c093fe6030098d5c8c43a59bea334048bedcc511b3ffb6c1d64876d0214238f70b27267e606afb1747423b1aa254209bea36e8e"
- deposit_data_root: "0xcc6561589f174b04b6adcf0b2a893667c65f3443bed0e5c8a3af84d3157c3baf"
- eth1_data:
- deposit_root: "0x28bfff0f74194d7bfcc9ba76c21cfe0c2908f605b8017e023792ece9d9b1c1eb"
- deposit_count: "159"
- block_hash: "0xe93ddeb537374b4dbb453dc08411c26a02c36c9d3b77f4b9679a89bd75b70dae"
- block_height: 160
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xaf12585229c24dfcac5f5fa3ac66011dabdfd39529f6d98c07abfa998c1b4e52"
- - "0xb691ba9f86444f0a58a7e0becd7c3bad9b44e5bf6a88b85a7cfc6f243f6e2fb8"
- - "0x5cf0c39a7fa083994f7baf809c387f9ab82024f5f1bb1e9badc5d3b26c5c2973"
- - "0x431fb43239425b2f4faf58bbfc2e8bf64202d513954ef412ee9154052f667c4b"
- - "0xcc6561589f174b04b6adcf0b2a893667c65f3443bed0e5c8a3af84d3157c3baf"
- deposit_root: "0x28bfff0f74194d7bfcc9ba76c21cfe0c2908f605b8017e023792ece9d9b1c1eb"
- deposit_count: 159
- execution_block_hash: "0xe93ddeb537374b4dbb453dc08411c26a02c36c9d3b77f4b9679a89bd75b70dae"
- execution_block_height: 160
-- deposit_data:
- pubkey: "0x8fe63d0f0da14a975a69446571eaa08409b6b4d091c720ca26519156a1cbd9e0fd44de574d8486ff98ad4086e0d96f59"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa80cc551d9eb7d869858e173eb701e706fa8bb1fd82e798bf19085c1b07d1b4807681fa0fa34ab3f802ddb664933a43513a14975a33d720b949c4873ce646f8f80ea6e8a645e404c81441b7ef30076650694972b8cbc3ff2062ff4772dca91c2"
- deposit_data_root: "0x59822146ece6a1e35fa5c3b0b38f1a7ccfb6cea652ae7d6d6867a0cd2298276c"
- eth1_data:
- deposit_root: "0xf125f86aaf7df54e79f43355d6be50d55daab4addaaabae4c58e7a977f3b1cc2"
- deposit_count: "160"
- block_hash: "0xb6bbba5e6a9fd9d2972588347d65cfc8633717b19e2c059aeae1c55f790b6ea0"
- block_height: 161
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- deposit_root: "0xf125f86aaf7df54e79f43355d6be50d55daab4addaaabae4c58e7a977f3b1cc2"
- deposit_count: 160
- execution_block_hash: "0xb6bbba5e6a9fd9d2972588347d65cfc8633717b19e2c059aeae1c55f790b6ea0"
- execution_block_height: 161
-- deposit_data:
- pubkey: "0xb249899bfe2b0b123c7a151b5041d5e994c57568a6b427e38b25f2ef04ef0c30b4577e66fa7b499ef14d8d24563ef06e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8ea309386ac878fe5d5b3e6c4dadd85302bc9432ceeb7ddaa95ec3414d7f2cccd0792606dd481c49dd4f1d3455847b9b0e07bc4726118afe68116701d4641e0ecf9caf7be829cd0dcb7651801c9bc0ad18b7592b5f95012802f1e7b14e9cdefd"
- deposit_data_root: "0xe3149b68de3b804bb8ecdfaf36696dd76fcb801e7e47142e5beafd06b8c96c31"
- eth1_data:
- deposit_root: "0xaee25dee2d482203030ad50d3f0731d4b215bf84f1c60b875e88e19125482a75"
- deposit_count: "161"
- block_hash: "0x13c72c657d79ba0f34266ace9d2e195cfb91257db5853010df831bde22774d4a"
- block_height: 162
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0xe3149b68de3b804bb8ecdfaf36696dd76fcb801e7e47142e5beafd06b8c96c31"
- deposit_root: "0xaee25dee2d482203030ad50d3f0731d4b215bf84f1c60b875e88e19125482a75"
- deposit_count: 161
- execution_block_hash: "0x13c72c657d79ba0f34266ace9d2e195cfb91257db5853010df831bde22774d4a"
- execution_block_height: 162
-- deposit_data:
- pubkey: "0x965ce54aa0e435602fe222441ea4ac7b227948ea37e927f9816d89d779dbeba426dc68ba6829ab8da33a565a6b879c65"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb0352350082b57df3eb8cacc48bd3e999a1b2719ef218cb2a5189291e0234f4678b21b037392c37b724ff82a6a42727b103809bea4cc34cf9c8f86675d0a40adbf65b467e9128358802e0079a0cdb100b9206a4475b97e7129272a8c36e51b9c"
- deposit_data_root: "0x8b1968fceaf4e3214998a64db92e35e11a383ca34a1e8d37a4f07588debb444c"
- eth1_data:
- deposit_root: "0x81cbc850d30b5486ca44fc0f2368100fa3673575e87fb5635485fbd553ceb59a"
- deposit_count: "162"
- block_hash: "0x95088152d0c1114f167cb7b65078019b8bd5f2023e889e18c201c0bf6cca138c"
- block_height: 163
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x2e6b570d265740ee405e8ebdf6c5e228efe005294f62cf1af23affc7b72a38e6"
- deposit_root: "0x81cbc850d30b5486ca44fc0f2368100fa3673575e87fb5635485fbd553ceb59a"
- deposit_count: 162
- execution_block_hash: "0x95088152d0c1114f167cb7b65078019b8bd5f2023e889e18c201c0bf6cca138c"
- execution_block_height: 163
-- deposit_data:
- pubkey: "0xaea84e54336d09257061a8b23f419438c2e3d2659de36b993033bb30e396d9c9ee8b6f1b66261a6a060c3ab706827afb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x82804e80f3e381cec665c1f51b1015500a0eb2b35085c1b1365156e4fbb5ab82d7d4af7af12e8cfc2a73026e6aa8e3440cc9babfa8480efd255b15f1097fc8a2283d76b02f225a1d7105e44f9daffe9794208e97bbb19907dd83a0608095c127"
- deposit_data_root: "0xe374e9bd5c51394fcdc6852e98614127fe095a5192cf53d340cf519bf20cfb59"
- eth1_data:
- deposit_root: "0xdcd46c40bcbbde1ad6887dc6099f6109980c4dd6bb67d03e7534dd7d87038867"
- deposit_count: "163"
- block_hash: "0xdbc232ce7aff4b99b9ae5e05a47ef313d62affb1f08328157161c00a218575b2"
- block_height: 164
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x2e6b570d265740ee405e8ebdf6c5e228efe005294f62cf1af23affc7b72a38e6"
- - "0xe374e9bd5c51394fcdc6852e98614127fe095a5192cf53d340cf519bf20cfb59"
- deposit_root: "0xdcd46c40bcbbde1ad6887dc6099f6109980c4dd6bb67d03e7534dd7d87038867"
- deposit_count: 163
- execution_block_hash: "0xdbc232ce7aff4b99b9ae5e05a47ef313d62affb1f08328157161c00a218575b2"
- execution_block_height: 164
-- deposit_data:
- pubkey: "0xa90dfa8114a00b3fde7cdddfb2fab9a6d113500aee32f08786634bc5c99ccd7730417e4ae4a05299b62342c1ab98ada3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x993aaf734e6ea9848eb8b581d8349a780dcd2689bd341c984ed7f291efb035c1bb6a7be47bd9904aeb1d9bc595596b670b011d2e36bf1b4a1e3f83bd87ee5d1a2b8e10d93825bdafe498155fa3b39cd1d929e858e14cae16dccac990a918b407"
- deposit_data_root: "0x7b4c8cd4bdd1696c9acee551bc67972ee101a70a05d7e80e327867bf9c2cca75"
- eth1_data:
- deposit_root: "0xcbe12098660ef62edb564991133409b98044b1f3e79ad49c9b26a29d990694ff"
- deposit_count: "164"
- block_hash: "0xe2797260931e52abe1abde79d64ef6760785f83401180a0799ef7688f4118150"
- block_height: 165
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x582e9a6fd990c0d996070550f2ed7e8e8cd420dd85740a5a6e53f4f0c300d47c"
- deposit_root: "0xcbe12098660ef62edb564991133409b98044b1f3e79ad49c9b26a29d990694ff"
- deposit_count: 164
- execution_block_hash: "0xe2797260931e52abe1abde79d64ef6760785f83401180a0799ef7688f4118150"
- execution_block_height: 165
-- deposit_data:
- pubkey: "0x9346419f620830d6535546fe2ddd827b69156ea9c29194780c63a8f07b6fdcb0568282914ce3cc06a2ba44e2ee1a6e9e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb243d10f9864d3abcc933b7ca0cdb2e40fa08a1631ecb702c41dab1113f0e689677ba1e8b078618989b65548103adc5d0d7531c102f22f4d502504c64148b8aded9cf314ea6d8336b5f36329e90f79298efe0d48fe6f84647dbf3952247b1f93"
- deposit_data_root: "0x9843715212db9556a5ae4aebc9cd03db21467bdb82a6b0b7c8aad1e03e7c0db9"
- eth1_data:
- deposit_root: "0x62657a90eb6dda61c00c5b33dca2b652a03fba9f0aa4090c0711418945d8444e"
- deposit_count: "165"
- block_hash: "0x8090b1b61be967d73abea99aabd3a2df3ea098eee99126ff117aa1e3b0581543"
- block_height: 166
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x582e9a6fd990c0d996070550f2ed7e8e8cd420dd85740a5a6e53f4f0c300d47c"
- - "0x9843715212db9556a5ae4aebc9cd03db21467bdb82a6b0b7c8aad1e03e7c0db9"
- deposit_root: "0x62657a90eb6dda61c00c5b33dca2b652a03fba9f0aa4090c0711418945d8444e"
- deposit_count: 165
- execution_block_hash: "0x8090b1b61be967d73abea99aabd3a2df3ea098eee99126ff117aa1e3b0581543"
- execution_block_height: 166
-- deposit_data:
- pubkey: "0xa399755dad117a369409206196a9e3a1637a625dc22d0da18583827dbc487ab9a2ba6c995927df9d8560e07860ae8b0f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa6f0fc1f51494308f876cb2391f625009d4761871c69af305712751e35cf0f3c026e06c159e3c82988b9f97fff4d1d99078f3bd6c8b7d3d308e36eae49ac1b79ace6e04656b0fcd3d8daaf2ce6333c0ec0ca998ce3c08ea86e73fda1c8d25bbd"
- deposit_data_root: "0x4e25083e3dccff55e85eaef37ccc737c720ecc898a98e8ca0c52b897431a315a"
- eth1_data:
- deposit_root: "0x4619beded7d11311791dcef425b8027ea14e383d8c2cd5c742879c134637ee91"
- deposit_count: "166"
- block_hash: "0x3c684054459e115db8518ed799e879a579a049bc9994c1727e568d3e9dbe2767"
- block_height: 167
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x582e9a6fd990c0d996070550f2ed7e8e8cd420dd85740a5a6e53f4f0c300d47c"
- - "0xd9c72e2b3770f12ee0e9f7d83243ab36680e0b9483eaf7a537848aae96531edd"
- deposit_root: "0x4619beded7d11311791dcef425b8027ea14e383d8c2cd5c742879c134637ee91"
- deposit_count: 166
- execution_block_hash: "0x3c684054459e115db8518ed799e879a579a049bc9994c1727e568d3e9dbe2767"
- execution_block_height: 167
-- deposit_data:
- pubkey: "0xa4695dc25f6cd20e48edd948321a09ebe2884b1d6ebf622aa02a023e96f9a1d365be7f2c6668444b347aee678fc7bc5d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93375360b97a238600161ddf1096b86637d2bb9cf4453450804fca3b16bbc74e1aac6d9a9ece486250461b0492a68470164b8f779c6eb89f59233ec304af5cf3f76d4d5ad6508599bf569927eb97096f422051e33c4137df737eb4db9a4e421b"
- deposit_data_root: "0x468fd4b82322e73a7470baa353b8931947a2bf6fe3cb62cb1b0f126973a2df1a"
- eth1_data:
- deposit_root: "0xb2d04fea4f590b0f56e5a7fa576d4b2cd2d88b99c09dccb2b4aa560eb0885c9b"
- deposit_count: "167"
- block_hash: "0x06c9e6315169cf6fbbb198a180cc67111550846dcc2b78e2265dbcb5d29b17f3"
- block_height: 168
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x582e9a6fd990c0d996070550f2ed7e8e8cd420dd85740a5a6e53f4f0c300d47c"
- - "0xd9c72e2b3770f12ee0e9f7d83243ab36680e0b9483eaf7a537848aae96531edd"
- - "0x468fd4b82322e73a7470baa353b8931947a2bf6fe3cb62cb1b0f126973a2df1a"
- deposit_root: "0xb2d04fea4f590b0f56e5a7fa576d4b2cd2d88b99c09dccb2b4aa560eb0885c9b"
- deposit_count: 167
- execution_block_hash: "0x06c9e6315169cf6fbbb198a180cc67111550846dcc2b78e2265dbcb5d29b17f3"
- execution_block_height: 168
-- deposit_data:
- pubkey: "0xa8c0966a8c0869e28110ea5587321cb26af1bc49591fdaab24b37c77feed399439515d2aca8f2483a3d666be8b4eeef5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xace818afa05a123b98626d805d1b747f09b1d2e41c826b607da97cd28c41ca78d2514e2d4e4a0a1a98cb6034a1ace05f033e4091dfbe40eb7eb6943b682c7ed8b26b8a68f731f908ca7c18f5f8568a1c39648bb94870066275245e42e44ecd03"
- deposit_data_root: "0x9dae7719d40b642b28d8de5358c902e0e7b6dcddeb88a29cc2583600c15ad2eb"
- eth1_data:
- deposit_root: "0x847f32ad10d7b3de3275fc8a8730008ec5f12a89142209a4ba63c8cbdb022ea3"
- deposit_count: "168"
- block_hash: "0x619b700d81b9b1216b6b9ff1f0eb4f7b11c4ffd3c4cf781af2a9cd47ef42a7e5"
- block_height: 169
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- deposit_root: "0x847f32ad10d7b3de3275fc8a8730008ec5f12a89142209a4ba63c8cbdb022ea3"
- deposit_count: 168
- execution_block_hash: "0x619b700d81b9b1216b6b9ff1f0eb4f7b11c4ffd3c4cf781af2a9cd47ef42a7e5"
- execution_block_height: 169
-- deposit_data:
- pubkey: "0xb210d799f2cc4d87df36b60fe1d7408d9e4b5124aeed740eb42227dc1f456d9e13bcecf309e068f9775996c71b55ca8d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa59636627fd11a272aac90b9ae21cbe3156c8e347f34c6a92d6078f1a130864026c4fd8149df5c0808c9d8be6e7257960c627011fa459fed2d513ac91bc10ef3858e27ea6b88aa3d1f566ada6075daf2f3306fed983353dc6593375f9a2af410"
- deposit_data_root: "0xd2ff2f73a25e4c4de82d2bc2f1fe937bdaecc03fddfb5f971df8c65a6fd9d93f"
- eth1_data:
- deposit_root: "0x7e03a31121d9081c87abc7e9789a6ba49abf30fa5e5b0e2245cd75c76869ad5a"
- deposit_count: "169"
- block_hash: "0x307cdbb86ebbce74ab00d13e63aaf58c789c1fe21b037234c2798cf2e44ac41b"
- block_height: 170
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0xd2ff2f73a25e4c4de82d2bc2f1fe937bdaecc03fddfb5f971df8c65a6fd9d93f"
- deposit_root: "0x7e03a31121d9081c87abc7e9789a6ba49abf30fa5e5b0e2245cd75c76869ad5a"
- deposit_count: 169
- execution_block_hash: "0x307cdbb86ebbce74ab00d13e63aaf58c789c1fe21b037234c2798cf2e44ac41b"
- execution_block_height: 170
-- deposit_data:
- pubkey: "0x83af2f04a869d856df934893edd7f15dae94ef74d78139e0556e1166e81f8ab2c294708af67f194e854946f2da4e87da"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x944859b17259fedb50e94bf3fbee57b0d5c7f43401fb611258a599696f24d94622a71d179d540fb83b475122c406c85113f84ba8684096c38accf6d171ae2abefb725a638207dd12d12099a7bdeddb832a05f4707797d724deea9570679dab0e"
- deposit_data_root: "0x9aad59fe2860067c1859e09c5a0cbd41a482389f2457b3ddf246b065d2b797e5"
- eth1_data:
- deposit_root: "0x0507a6d86c34e8fb6f2e644d93bea484d395eb00f747aa4185e15e67741708f8"
- deposit_count: "170"
- block_hash: "0x4840cbf1750adce5ef26a3b6e0251a60f5998a1bb4109a3918410e2f459edd2c"
- block_height: 171
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x0243f87cc01998a622e06a46d90ff0e2c2f4e0457b4e0c418a13a3183743df4e"
- deposit_root: "0x0507a6d86c34e8fb6f2e644d93bea484d395eb00f747aa4185e15e67741708f8"
- deposit_count: 170
- execution_block_hash: "0x4840cbf1750adce5ef26a3b6e0251a60f5998a1bb4109a3918410e2f459edd2c"
- execution_block_height: 171
-- deposit_data:
- pubkey: "0xad69af5d2ee0d68b32e6c4ebafc348a0c509aeed7e4f5c24c236dad4a8f91129cb9f8ee521de07c8199807e36e6a84f9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a8c6e627da5d712418638f0a31f9671f753d44f5b9439ba0ebacd3a4cfbe41b6ec1c75eb70e0e57bc3535409e7f949f01dbafa227b0b87d44ebc5dd63083e3848b36f4b1821f0f3c1ff2a9878c5ba2cdcc16e39b01e0f4a924aa8c14278c447"
- deposit_data_root: "0x41deea4572826ab6dba52032eeabd9996d80e3a5725ebba8a8a20726fd16d10a"
- eth1_data:
- deposit_root: "0x73170edf9923bea7b1203c4701f3023cb42ab5a8c15e7a5310fdae89f49a10e8"
- deposit_count: "171"
- block_hash: "0x409571a87e6260ebf8a4b04e70a01d1276eb29c3ea26ec4f85561f1b15089ea6"
- block_height: 172
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x0243f87cc01998a622e06a46d90ff0e2c2f4e0457b4e0c418a13a3183743df4e"
- - "0x41deea4572826ab6dba52032eeabd9996d80e3a5725ebba8a8a20726fd16d10a"
- deposit_root: "0x73170edf9923bea7b1203c4701f3023cb42ab5a8c15e7a5310fdae89f49a10e8"
- deposit_count: 171
- execution_block_hash: "0x409571a87e6260ebf8a4b04e70a01d1276eb29c3ea26ec4f85561f1b15089ea6"
- execution_block_height: 172
-- deposit_data:
- pubkey: "0x93568c9c40bb362329367dfc26a65567481a03c35fcaab51f781c9f364b7e676cfc3d2c08633888b29715a6731dfb6b0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8afaca7a98ed1bbe7d5ad827d9dfb25e22983515a8cb7bbf9660b8bc965dbd22cddcf301be0b8ea07773716cd6bb40c0939ee4236b1048b327b51dc56eeec3333296519c33ba8b42671c2e64941d3c0274204eff17c255729a6ff036dca11d2"
- deposit_data_root: "0x3ce86437d73f789ed89cc006c250d5ae9ebe44e25ce3df3b8a87c511f3252ab3"
- eth1_data:
- deposit_root: "0x5f0c1f7e6a02232a6a1d7aa1c7a94f9d46700a5715138165282542665559fe6a"
- deposit_count: "172"
- block_hash: "0x4f2e4afd489e40fdb8ecfe276f4a028e550ae9f2224c29aff14670bff6732ac1"
- block_height: 173
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x6706f41e298f5bf853c88ba459952003db6fa9dd7a4c36b72fdca4b7d831d42f"
- deposit_root: "0x5f0c1f7e6a02232a6a1d7aa1c7a94f9d46700a5715138165282542665559fe6a"
- deposit_count: 172
- execution_block_hash: "0x4f2e4afd489e40fdb8ecfe276f4a028e550ae9f2224c29aff14670bff6732ac1"
- execution_block_height: 173
-- deposit_data:
- pubkey: "0x8509086b192c039cc84d145fd6a2b2cc3e3a3d46092e928cc1ca9a66dd663550a2782ab32d677785e02c23b6637df70d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9055741c269436e5cb5eb9560441a9dd62dc3605913b6b83b207e49eb2c9f3837b2c877c8e937ce326ddfda973a031920f60331a5eaadc52555cf37c6a0216ca8ac3ba965a2c0060b1b9729472e977a5fd23b23c0a39286b849a7ee22d76fe5e"
- deposit_data_root: "0xc9ca71afaa9631f5c9645212720807c19c302df3a5911504c49fc87f78011862"
- eth1_data:
- deposit_root: "0xda5ea898120a262741057304c7596b6a34af9ca93abc2a162c738cbf30613c57"
- deposit_count: "173"
- block_hash: "0xd53d21964f2af07692e1fa7c1886d583dd28693ea39b391d4ebb18e603d0ecb2"
- block_height: 174
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x6706f41e298f5bf853c88ba459952003db6fa9dd7a4c36b72fdca4b7d831d42f"
- - "0xc9ca71afaa9631f5c9645212720807c19c302df3a5911504c49fc87f78011862"
- deposit_root: "0xda5ea898120a262741057304c7596b6a34af9ca93abc2a162c738cbf30613c57"
- deposit_count: 173
- execution_block_hash: "0xd53d21964f2af07692e1fa7c1886d583dd28693ea39b391d4ebb18e603d0ecb2"
- execution_block_height: 174
-- deposit_data:
- pubkey: "0x89494e98d8cc4c763b3b138e21d6cc1c86f7eeb69315cf6a4b8b5b7018dd59e3b82c0b7c785a381ffd1b809e5bbf4625"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa937d3c9c04bf31b388af13d98636e1339e5e9cf3d8dfe50dff7722be110fb42e68efd406af92b5e3c0ed4f73959c89502c84a8ef20410120d5344b7441872686652f642ccc7b2d944e3a6937670e166795535e65fc66204fbc61a9e846a9950"
- deposit_data_root: "0x000a7e1720ce430ce6344f7add0f7e4b43ca5ca57be2a8efbf63c0746787cea2"
- eth1_data:
- deposit_root: "0xb349cf11fad3f0efcc1b018ea084cc30ff6ce11e8c13ff066a548ca67bb03906"
- deposit_count: "174"
- block_hash: "0x446efd92f90c3861d7acb8deccea5b7c28036a54dd441584508a5c8a52f905c2"
- block_height: 175
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x6706f41e298f5bf853c88ba459952003db6fa9dd7a4c36b72fdca4b7d831d42f"
- - "0xdc8f10386657c08bb0d17aba01f7647252ad4c6db5a36fe938283fe819b0c9d0"
- deposit_root: "0xb349cf11fad3f0efcc1b018ea084cc30ff6ce11e8c13ff066a548ca67bb03906"
- deposit_count: 174
- execution_block_hash: "0x446efd92f90c3861d7acb8deccea5b7c28036a54dd441584508a5c8a52f905c2"
- execution_block_height: 175
-- deposit_data:
- pubkey: "0x8451860d32c95e30f685cf31fccb967b0cd172566ff7b7d2c5ff35130bd1232cb1a216c9f0cd355ad69a93469b78e8ba"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaaeaad75e6abb6123819f1f01b636a91f85f28c38fe57833e38e555f0a78546a151c02dad44fce569eb89212879c381c18a516d9256ca79afde66a5fc334005b470dd2e3d704248cd7f61203ede9fffe343dfbd0b55f0a24b1c832be7ae68cd6"
- deposit_data_root: "0x38d3cf596f6aff5b5603a02e0cab7770a129d72499ec88ae2cf89bf01ba15b8a"
- eth1_data:
- deposit_root: "0xa927a1cd6a0fd5bfcbdc12921e8197df198e82b0fd4ec52051885184f7105703"
- deposit_count: "175"
- block_hash: "0xbce83de010f32cd9de9e1af87710aa65227fb59b04ae6825ffe42bbca51ad8fe"
- block_height: 176
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x51ed246dd0a98ad17d95eb60d315ce5433d7a022cd5db0a6d4f1be5b3bbae2c1"
- - "0x6706f41e298f5bf853c88ba459952003db6fa9dd7a4c36b72fdca4b7d831d42f"
- - "0xdc8f10386657c08bb0d17aba01f7647252ad4c6db5a36fe938283fe819b0c9d0"
- - "0x38d3cf596f6aff5b5603a02e0cab7770a129d72499ec88ae2cf89bf01ba15b8a"
- deposit_root: "0xa927a1cd6a0fd5bfcbdc12921e8197df198e82b0fd4ec52051885184f7105703"
- deposit_count: 175
- execution_block_hash: "0xbce83de010f32cd9de9e1af87710aa65227fb59b04ae6825ffe42bbca51ad8fe"
- execution_block_height: 176
-- deposit_data:
- pubkey: "0xb48c495c19082d892f38227bced89f7199f4e9b642bf94c7f2f1ccf29c0e6a6f54d653002513aa7cd3b56c88368797ec"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xab221d4174ca55a27aa072b675ee700d63edd048d4f417b79bce310c3bc3f5aa214eca529c4624accb014bad5d1f79e50ea67c82e4b3daea65dda4de263c0131eff1ab811e5716eca36bc2409495ae2795abbeb161311df4a3289cf1aff624e8"
- deposit_data_root: "0x960ceb47ae45f726f760f1a6e4c501a1e539f332f3cfad2dcd22be596fc8c126"
- eth1_data:
- deposit_root: "0xe95f5528ca45a8860a620ea21eda926f6f153cbaaa6b9324ae5ea82aff8dc2b3"
- deposit_count: "176"
- block_hash: "0x3f7e984a3ba436e0ed8fbfdb1bca8308e6ec5b1060400a1c5156af6ef110bc5d"
- block_height: 177
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- deposit_root: "0xe95f5528ca45a8860a620ea21eda926f6f153cbaaa6b9324ae5ea82aff8dc2b3"
- deposit_count: 176
- execution_block_hash: "0x3f7e984a3ba436e0ed8fbfdb1bca8308e6ec5b1060400a1c5156af6ef110bc5d"
- execution_block_height: 177
-- deposit_data:
- pubkey: "0x8bd22839c85ec58af4303cde58674394247fbe1f51b4e30ebcdf86aa861ebef2ac9239aa21bd9b07fd03f28dc4806780"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81fb9baf8c52a4888566448ed653d4e199b40bbf4053c34ea0105554f96a4dd245df81a2ed37e900b73ac954c7001f7009a2240737f034d9e4ca6874f3913d06efbfc2eea789f86ad5a353b37b755ba73aae5dcb5f3f44fb155410807d44bbc0"
- deposit_data_root: "0xfe4956baff4bc251951ba1c955db9f46821ab844d6a031ef7db7b68de6959856"
- eth1_data:
- deposit_root: "0x76342485c471517c60dce8cf762fffbf3f06f93202e98682c7078618c4eb0e88"
- deposit_count: "177"
- block_hash: "0x66c1f5247e10372a47af81e6e30ffdccc3f0d64f7fde478420394289c435dec7"
- block_height: 178
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xfe4956baff4bc251951ba1c955db9f46821ab844d6a031ef7db7b68de6959856"
- deposit_root: "0x76342485c471517c60dce8cf762fffbf3f06f93202e98682c7078618c4eb0e88"
- deposit_count: 177
- execution_block_hash: "0x66c1f5247e10372a47af81e6e30ffdccc3f0d64f7fde478420394289c435dec7"
- execution_block_height: 178
-- deposit_data:
- pubkey: "0xaace874118a4ea9cfec8d7979dbb4618f4833dde4cfc493a403ee5cedb67f294bcac4aaa2d626ff25f4fc7ee9fa61401"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x859e833217c0fd90fc641745e75e0d100d6b3cdfc1fc98dcd92dd0838a22c3bb3508ffbfc41662ec93134881f4a75a7d01661c1eb91d302c8ad28463703fa445276f9a7ce810a0fe475e18631ba1b81084f2b0c65008b37eccffbc01eca98143"
- deposit_data_root: "0x2325c1ee7ee609107dc5df1c7445e7d02a00e48798fe06f73e48705e0357e8b4"
- eth1_data:
- deposit_root: "0x95111c86ff2b172022650c8d000331c7c57d98b2f330aa9bd6bd417f94547739"
- deposit_count: "178"
- block_hash: "0x0c95d8c50c7fa3299c3ffd7ac683ef683fc907c39997b8b606bc8210c71c1b9b"
- block_height: 179
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x452e7913b4f3ad6bc209cce6fc61588821ad6494282520a51e00926d913aac94"
- deposit_root: "0x95111c86ff2b172022650c8d000331c7c57d98b2f330aa9bd6bd417f94547739"
- deposit_count: 178
- execution_block_hash: "0x0c95d8c50c7fa3299c3ffd7ac683ef683fc907c39997b8b606bc8210c71c1b9b"
- execution_block_height: 179
-- deposit_data:
- pubkey: "0x956851460cb809871966cc4dd44d0b58dc68a1c22110864f374cd3aca743ee63b0743999d35b473e3f95ea38a276eaea"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa22edc0fab4e7099060fb062f9ac88bc08e2903dba9c9243dae581b169e91a3a8a823fe5a429d0d459d6499fd70c1c240d33cd4f5d7053ba9278234fbced8df69ed82849f3fd8510658918a00720c80d8453044bad1c4bdbdb20ca5ff75ffa5f"
- deposit_data_root: "0x9567c1a847009105673244cbcccff11184117f0b3e465f48e1771ead7976779b"
- eth1_data:
- deposit_root: "0x358b5a17f9a64b0a891cf6741ceebd0b615dfb89490550c9b601551d13781068"
- deposit_count: "179"
- block_hash: "0xd6917e5c5a35c21ea97cb5bd1f9070427106bf4980bb247d8a25fed86a6d09cb"
- block_height: 180
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x452e7913b4f3ad6bc209cce6fc61588821ad6494282520a51e00926d913aac94"
- - "0x9567c1a847009105673244cbcccff11184117f0b3e465f48e1771ead7976779b"
- deposit_root: "0x358b5a17f9a64b0a891cf6741ceebd0b615dfb89490550c9b601551d13781068"
- deposit_count: 179
- execution_block_hash: "0xd6917e5c5a35c21ea97cb5bd1f9070427106bf4980bb247d8a25fed86a6d09cb"
- execution_block_height: 180
-- deposit_data:
- pubkey: "0xb8cd27d87c94a69cecd953999908640b437f6215ddae069a1ad403f995dfde6e4ac46e5c85fdd8bd4fa655f74cc2bc80"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x986d671909e02d5efe0689ec87b8add58331b963e14b4ed9d989b586f1bbd1c5f119360e1bff27fe64e598601545c52d08386c175a1fff8acf5f6760d12acfb51027523ae9e7afd69ff4db75a1e580904ecf93a22da7ef83c5cbf08f92bc85cd"
- deposit_data_root: "0x9c0182b4b9d2a650eee485c0a5b6c743d4377dfb2dad1094972ecb50271f65a6"
- eth1_data:
- deposit_root: "0xfa89ade12d8c6d2a1d9800b7bb254622b424c40067e2b0b9e569bab078c024e6"
- deposit_count: "180"
- block_hash: "0x6c27c6e514081d3f51296640528a1da12d22a3462cb44810dad190c782f7cbde"
- block_height: 181
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x2d162bc4799fcfca576dc1ddf85c96c62bf3506922863de03d99b21d5d57b1fc"
- deposit_root: "0xfa89ade12d8c6d2a1d9800b7bb254622b424c40067e2b0b9e569bab078c024e6"
- deposit_count: 180
- execution_block_hash: "0x6c27c6e514081d3f51296640528a1da12d22a3462cb44810dad190c782f7cbde"
- execution_block_height: 181
-- deposit_data:
- pubkey: "0xae37d415dda04db4f1abcf52c080c1c7a1921a819181161c4c2c18f809cdcf695de3f0f793c78802bacc1f4a32bd921a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97d0c9476aeb800a3e27f0b60f371679789e6bb03919bd65503eea6ee138275da5ea35f8a21352d68f1e5cde6be870d50c5356047cca0a2f043d83acfe44d3732e19f2aa54e844ccc57bb72b2061b00100cd28593eeab5601f35a594a2e82a98"
- deposit_data_root: "0x0da07a675920dd21e72440e13ac21d1d8d9864c92db43ffbb3bb100d6d112923"
- eth1_data:
- deposit_root: "0x46cb3dd3672791d77dadce6782dff84a88f34d594a9dd8441473f26bbff0e3fb"
- deposit_count: "181"
- block_hash: "0x7e23db8c0087f9044534d05457249a8f3bf7d50496eb005325709a44bc102b32"
- block_height: 182
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x2d162bc4799fcfca576dc1ddf85c96c62bf3506922863de03d99b21d5d57b1fc"
- - "0x0da07a675920dd21e72440e13ac21d1d8d9864c92db43ffbb3bb100d6d112923"
- deposit_root: "0x46cb3dd3672791d77dadce6782dff84a88f34d594a9dd8441473f26bbff0e3fb"
- deposit_count: 181
- execution_block_hash: "0x7e23db8c0087f9044534d05457249a8f3bf7d50496eb005325709a44bc102b32"
- execution_block_height: 182
-- deposit_data:
- pubkey: "0xa7c674e6660a1930c546b4a7e345265a51527fbd53327f90cf7edce01ec2a9c9470c9d9f0a2e4dcfe4c0c5df4382aafa"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9765a98cfa6c562e97d0d18e26d20649229ecc001700852fcebdc804c14ad8fd6a9e4169972e16c0abcc07912469267d0f62d285abb659530eaac69c14dbace530e4f3d37b89ff58242c534c1e87a993dd0e53e52151f0021a699827196ab3fb"
- deposit_data_root: "0x3c02d11665be2b3121a49de3fc627ae4d2728050be2857acab0ab6800d30702f"
- eth1_data:
- deposit_root: "0xc2bd6a75ddac26bebb1dedff17e01e7388ba0d1daacad735c06dadf4d1497ab8"
- deposit_count: "182"
- block_hash: "0x24b5eec3f6b3ca56fe7e893edabe438ac14e338fae43ac6ad28b231a79e66768"
- block_height: 183
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x2d162bc4799fcfca576dc1ddf85c96c62bf3506922863de03d99b21d5d57b1fc"
- - "0x3a0f8fa7a03d6c1c8c53c26f944126d830c08b1cea4019c7980dc8d3cca5aeaf"
- deposit_root: "0xc2bd6a75ddac26bebb1dedff17e01e7388ba0d1daacad735c06dadf4d1497ab8"
- deposit_count: 182
- execution_block_hash: "0x24b5eec3f6b3ca56fe7e893edabe438ac14e338fae43ac6ad28b231a79e66768"
- execution_block_height: 183
-- deposit_data:
- pubkey: "0xb2c9669a6f3e64a5f8b37c210c88adb507ce396042921b1aefd5bf52a3089f0ab0b5695cddf9b1a1157fe5dd43558e54"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8602ae96ab5650a7e477de5f00e10cb53826e3a268d96dbc0bd925e7370ff3f3fa7258261eb75a58d74c4de64db6713d19293e04d0cab40c1bd0c4669a7dd87a2b6272b8dd3c8f6414290843a4fbb945638eaf09594d44f502e2da1229d0ec3b"
- deposit_data_root: "0x68d5efabced0e3a67465028e2e9786d3626da8f47164112799f6280044e1da6d"
- eth1_data:
- deposit_root: "0x0e02f967291a37a27493d09d2cd5b530d83b67accb29fa7378acb5294b878af2"
- deposit_count: "183"
- block_hash: "0x392303f20a0d6202e844fffb6ac069f6a9dbaaa3f4447a7997afc74f1a83ee13"
- block_height: 184
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0x2d162bc4799fcfca576dc1ddf85c96c62bf3506922863de03d99b21d5d57b1fc"
- - "0x3a0f8fa7a03d6c1c8c53c26f944126d830c08b1cea4019c7980dc8d3cca5aeaf"
- - "0x68d5efabced0e3a67465028e2e9786d3626da8f47164112799f6280044e1da6d"
- deposit_root: "0x0e02f967291a37a27493d09d2cd5b530d83b67accb29fa7378acb5294b878af2"
- deposit_count: 183
- execution_block_hash: "0x392303f20a0d6202e844fffb6ac069f6a9dbaaa3f4447a7997afc74f1a83ee13"
- execution_block_height: 184
-- deposit_data:
- pubkey: "0xb00c6d2cf271b167f17135bf7bd14b7df669194045eb6f09b9dec787c7b608dcd42613dab0f857fbfa3fb84792a3e63e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81bf33d08664f53464ad3fffff9475069948094c54b61edba63fb435969b7e621f7349991d72b43c8dd1bc48f20ccf1800e20a812f9996e115e9a98c98024186c4ba49722dbe463ea6c1c897105f24f5f983b2bf911c3af59123e43edfffefc0"
- deposit_data_root: "0xe2a3b3697c4174b669c5c9c3ce72ee244719fad0e9f198234cc3a13b7afcf5ef"
- eth1_data:
- deposit_root: "0x35db931e35f47dd387ae57bba681831b91a6579f034a754e7df92a8616679861"
- deposit_count: "184"
- block_hash: "0xa3d47fe70c8d2099b59a84c9f42bbc91c5bffe370010d5e535657fa3a1c4c816"
- block_height: 185
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- deposit_root: "0x35db931e35f47dd387ae57bba681831b91a6579f034a754e7df92a8616679861"
- deposit_count: 184
- execution_block_hash: "0xa3d47fe70c8d2099b59a84c9f42bbc91c5bffe370010d5e535657fa3a1c4c816"
- execution_block_height: 185
-- deposit_data:
- pubkey: "0xa5e5e5af2ef8b65bf9b7575606f81e99d1fa645078544b0fcd4e0b506670e6a75504e6ba4001e6cec25632633d050276"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb05a3fcac399a997e7ada5181638bdd95668dbef59f2a62b9c45a85857a42afa5f885748f6d07ecdefcae45e736ec3b512a94bccd7be7bbaec688d9449f586ffb48a82f3c693d1248932d7b7026082ccd7c0a97aae7e714f39484614690abd72"
- deposit_data_root: "0x2c3e00b8923d7c7bba4859372c106c9aa052b00d19a1cd9fa3aedab4a5511741"
- eth1_data:
- deposit_root: "0x87e828349d121957dab0e13448ba28216514999e6dfff614978f171578e27e2b"
- deposit_count: "185"
- block_hash: "0xc2320a2fc8b6dd2243c3abcdde3847e2598ffb7aaf303ce46cb2416d8e3be4cb"
- block_height: 186
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x2c3e00b8923d7c7bba4859372c106c9aa052b00d19a1cd9fa3aedab4a5511741"
- deposit_root: "0x87e828349d121957dab0e13448ba28216514999e6dfff614978f171578e27e2b"
- deposit_count: 185
- execution_block_hash: "0xc2320a2fc8b6dd2243c3abcdde3847e2598ffb7aaf303ce46cb2416d8e3be4cb"
- execution_block_height: 186
-- deposit_data:
- pubkey: "0xb7ad21b3cc61c96c4ea90e81cb5a39836f114dc477bb63da54af20f60d42dffb99aac4ae12ecb70288b1d226ca7c2522"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80714ff567371483af7418f8d43a7e4adfd10d8d464e3fad6f72ca3d981920aa58d71235f1ffc6296b89a8744b66b23519367b3f5691e4410ca3bd068d28d88b4fedfdd91ac4ebbfe5a176827576c3a7176d4bb04f28c854051354db197d4112"
- deposit_data_root: "0x56f3cf8c6f87ca6f6298746c6aebf716e8d2387075aa400a69746cc5dbc31815"
- eth1_data:
- deposit_root: "0x7ac99b76e5fc809c4327f6edf9142d7bc55e12c3f9089a53066ec41500dfb5a0"
- deposit_count: "186"
- block_hash: "0x92708be0274d0ac8798c19482761e0a59edeb96edaf6e5fc2c1588a3365394b0"
- block_height: 187
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x9856919205a162db29485432bba026c979f7d89cfce702fc09657632a7a4f14a"
- deposit_root: "0x7ac99b76e5fc809c4327f6edf9142d7bc55e12c3f9089a53066ec41500dfb5a0"
- deposit_count: 186
- execution_block_hash: "0x92708be0274d0ac8798c19482761e0a59edeb96edaf6e5fc2c1588a3365394b0"
- execution_block_height: 187
-- deposit_data:
- pubkey: "0xb3eea1ef03b3cd28709513f691d9b7aefcb9908efc7114e20e302598cc8dfcea02fd9423045f246112e4db1bdcfa9e14"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9576775970091bad8e182acfa971d69815b901f7818738490d7a94bf3b7fd5de9810aface9670ad6d4074295cd91c3fe073a989aaaf4143cdb6da3a0a6545e749cdbb914b38c9d3dddbcc5b57552ac5711f91fa2c59fe7ee52fca41c248dd7d4"
- deposit_data_root: "0x0fcd143f7e8ffc456987f9c887bb46743be683a31a84fbbfead37a6929f1d0be"
- eth1_data:
- deposit_root: "0x4a796a1cd10ad42e890c811c5261325c80df56afcfdb45b36ca98eca59d1cc1d"
- deposit_count: "187"
- block_hash: "0x8f679f6f3487c47c32be42dc94ca7d0bdad809ac30d9c8c38ad5010c046af1e1"
- block_height: 188
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x9856919205a162db29485432bba026c979f7d89cfce702fc09657632a7a4f14a"
- - "0x0fcd143f7e8ffc456987f9c887bb46743be683a31a84fbbfead37a6929f1d0be"
- deposit_root: "0x4a796a1cd10ad42e890c811c5261325c80df56afcfdb45b36ca98eca59d1cc1d"
- deposit_count: 187
- execution_block_hash: "0x8f679f6f3487c47c32be42dc94ca7d0bdad809ac30d9c8c38ad5010c046af1e1"
- execution_block_height: 188
-- deposit_data:
- pubkey: "0xb0f147fdb3e17379f4933c18e6dd3e3c9e9414ed5920ab029dc5907c01f671f664e4bfde8a4bcfa273a57daeb824f695"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xadcea3abcac1ad298bc1711dd9555c2f9802e83e406debfc65ba54af21f99d652f440ebcf584d55915905dc5608c8e8a03081a51dd172d8cb0d11739ed1d6ffc7e9c0100cc4c565cdf7ca8d287f121dc7892583490629aaa93d2da2b8cc57d8e"
- deposit_data_root: "0x35cb7c2582792d09b08d2b5da3edb333de2b9074576999f0bbb0891adf6fb9b1"
- eth1_data:
- deposit_root: "0xab52ed24e0e69808c8d21fb5ca3ad3ec64c02344b953dd830261b97e3d7356d5"
- deposit_count: "188"
- block_hash: "0xe762ae9acb10f13c7f8e344c9fef7ee760577fe56c516050e1921cfa41e339c1"
- block_height: 189
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x1ad4ff6de258418fe600f0c8dabec3d6665177e5929c3570071111e85c21a90c"
- deposit_root: "0xab52ed24e0e69808c8d21fb5ca3ad3ec64c02344b953dd830261b97e3d7356d5"
- deposit_count: 188
- execution_block_hash: "0xe762ae9acb10f13c7f8e344c9fef7ee760577fe56c516050e1921cfa41e339c1"
- execution_block_height: 189
-- deposit_data:
- pubkey: "0xae04fca0e06b256e03d4173d7f772e2106efe6f72d469243dba695179b5d2be8b61052c2844247ce49ec3b6cfd18c73d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb32e41533c45bff774de491d8b06cf576a27225dcd8b7713e980a7f61eb6bd4e53ba34484c0e061e38448e4bd4859868172fd3f4da5ebedcc4cb322f675ace60d7272cef4e7c27afaf8aa6f46d2b575bc14208ce19c6d1a29e759b883d70f590"
- deposit_data_root: "0x9426eb1a7383fe76d2759e9482e7cb6aca0b0b7afe88bde72a55c4a1c54d56b1"
- eth1_data:
- deposit_root: "0xe4ac94ad06eaff8884701227e53fc6cc79a3471f92bd7891f31432c1ad4b1e6d"
- deposit_count: "189"
- block_hash: "0x167dbceea97680bfd280469520320efcef8881d4f735bbee384fd13f0b8b6d48"
- block_height: 190
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x1ad4ff6de258418fe600f0c8dabec3d6665177e5929c3570071111e85c21a90c"
- - "0x9426eb1a7383fe76d2759e9482e7cb6aca0b0b7afe88bde72a55c4a1c54d56b1"
- deposit_root: "0xe4ac94ad06eaff8884701227e53fc6cc79a3471f92bd7891f31432c1ad4b1e6d"
- deposit_count: 189
- execution_block_hash: "0x167dbceea97680bfd280469520320efcef8881d4f735bbee384fd13f0b8b6d48"
- execution_block_height: 190
-- deposit_data:
- pubkey: "0x98c4e0f20616fa174bb221011e731650cb841ec29305f074fdafbed1d04b761c107a854722d4a6d69d6a15f7bf85c7d0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x974f103ca1b3e597a8edb9ddc0a26388902a3d016d25322bbbd3f8160117472cf6a8642f9ba00b40a364463e2598226607ddd490c88f48878dfe288bfd1eafeb1216d7702b80180afce9c3c891fb566795a6cf7a29ebabbcd729e735ae999c15"
- deposit_data_root: "0xa35b4a77af8ce0b6db5f6d71cfea7feae8cb334d1d8bf25b954c9c5e46ca812b"
- eth1_data:
- deposit_root: "0x3f7a7f8f15b24ce7b68da0583b9a3ea05e4eb68a97db64aecaf1be63dda51842"
- deposit_count: "190"
- block_hash: "0xc6adc26aa6328f1ba0efacfa64978e016f0cb79732f8d0030e5c5a908cde788f"
- block_height: 191
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x1ad4ff6de258418fe600f0c8dabec3d6665177e5929c3570071111e85c21a90c"
- - "0xd3cdd6fba6102cf506ca28a01aff74996a181dadaa9bf9819ff0fbffa9461e53"
- deposit_root: "0x3f7a7f8f15b24ce7b68da0583b9a3ea05e4eb68a97db64aecaf1be63dda51842"
- deposit_count: 190
- execution_block_hash: "0xc6adc26aa6328f1ba0efacfa64978e016f0cb79732f8d0030e5c5a908cde788f"
- execution_block_height: 191
-- deposit_data:
- pubkey: "0x8800aa633b5ab60ea1da84e04e4a2fe6fb19c1d90197791ae6212e5349d306ff58afe02d4dfad739b07171ab5757d26b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x98f03706cdb826e0909662f03081bd021f6c9e45eee0ca23ee0d99af23b1aee1b89f7f416a54ec69060f8ae12e28da4411cb16e3395d670c2ec8391e334a7de5691c5b2580f60929ec0c6b3cbefd4c98af66fbe609461338aced45e3e78b7c6a"
- deposit_data_root: "0xe0b69fa6a6be23e2f39b421d4f53ca95608f755be6f1e6f3cd131e4845a9557e"
- eth1_data:
- deposit_root: "0x3f9f9fcb0d2dddda55497b58cadb8ea93f1f3b741656a4849bb7fb0fa6722521"
- deposit_count: "191"
- block_hash: "0xc5f1e8d399f145ef92628f2d687619db3d5981fbf51dae54ff28b1f6641dce22"
- block_height: 192
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0x01a4a7e7ce6c883eaa125ca6fd50f1342b9d35c305634bf843d7a609cc8b36f8"
- - "0x3bdcdb12a251d536acdb1af1c54acb37cd882c8fefa579587efd7828584f5422"
- - "0xc81cb8f54677d5a3e4f8f079429f97cf7ea6fb35b82afc3d691763085cb8c78e"
- - "0x1ad4ff6de258418fe600f0c8dabec3d6665177e5929c3570071111e85c21a90c"
- - "0xd3cdd6fba6102cf506ca28a01aff74996a181dadaa9bf9819ff0fbffa9461e53"
- - "0xe0b69fa6a6be23e2f39b421d4f53ca95608f755be6f1e6f3cd131e4845a9557e"
- deposit_root: "0x3f9f9fcb0d2dddda55497b58cadb8ea93f1f3b741656a4849bb7fb0fa6722521"
- deposit_count: 191
- execution_block_hash: "0xc5f1e8d399f145ef92628f2d687619db3d5981fbf51dae54ff28b1f6641dce22"
- execution_block_height: 192
-- deposit_data:
- pubkey: "0x9474c26852bc2adfc52d093351dbf7ea822a2639d99db5b0d344e440e0ebbd1e856ae37daf3d91a05cf62f33342bd790"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x906782c06b770529831187f04df19f8c727112b36499e90e0ad918cfb44318fc0c3eb8e76184c0b5e40b088d93ff645a1903c216805754913fccff7f99c705fa735ef28f0343a7fc0f416bff0855368ab5d168e5b1a4002d149dddf9a7fbfe6c"
- deposit_data_root: "0x36a01af91aeb0f7858b003955815f552bdec183db519e9c8210c18560fdb8d1b"
- eth1_data:
- deposit_root: "0xa0fb785cecda8d27d5ce055f5cab99945fd8fb66281532c8d8b51e7596117bc0"
- deposit_count: "192"
- block_hash: "0x69d947eb6e6297a9449d82c807920062fc057f18e168cc0bc06bf5a89a8aa275"
- block_height: 193
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- deposit_root: "0xa0fb785cecda8d27d5ce055f5cab99945fd8fb66281532c8d8b51e7596117bc0"
- deposit_count: 192
- execution_block_hash: "0x69d947eb6e6297a9449d82c807920062fc057f18e168cc0bc06bf5a89a8aa275"
- execution_block_height: 193
-- deposit_data:
- pubkey: "0x86c82451f5ea5981c9031b3871e1463b10875934eda1c2520752d03bd51e71d943037b1a902979b6821eee7bd5779f78"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa9fe9f4af4705bda5e0ce2a369ebeef5ee8cde8cd9a66303e0f8100f282b23a5441a9c5be3c4ba6462d28117626fbdb6157951056078532b6e1717b5d5e44fc0839cefc1e34983900027caddcbffa2404014a35b16a3f6adf6cdcf35d8cdb396"
- deposit_data_root: "0x165cd78151e962dad0f4d9de56e66436d07d08beca179d0bf92a9b534791aab8"
- eth1_data:
- deposit_root: "0xc9fe80c8ecada066e8d0fdb2edec4b23b5f6d116bd65b980a9000c9fc251031e"
- deposit_count: "193"
- block_hash: "0xe2aade60b0fbbbad2f998e5badd1b8d3ced7fc0f7ec6f52ad7be45be91f38ec7"
- block_height: 194
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x165cd78151e962dad0f4d9de56e66436d07d08beca179d0bf92a9b534791aab8"
- deposit_root: "0xc9fe80c8ecada066e8d0fdb2edec4b23b5f6d116bd65b980a9000c9fc251031e"
- deposit_count: 193
- execution_block_hash: "0xe2aade60b0fbbbad2f998e5badd1b8d3ced7fc0f7ec6f52ad7be45be91f38ec7"
- execution_block_height: 194
-- deposit_data:
- pubkey: "0x864a08f5f022ce7757cb73be7ebf54e387fb3d5d4b0371d01ed493270be3236c5bc3b1272e42d2628f8f3c000d60eeaf"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91b20dfe5a0f41fc5e8cb0b591faeed60ccf42c7d7ead8c17ba7075c6349bef80a3f263f175a57b6b3a4a1fc2ebb1a800d2f1c4f5d45713d1ee418fd903c01c168c507a01c207d182cfe012342bc0f57707a24c7c0df942e247540bb97fd824d"
- deposit_data_root: "0xdc1915b04568269a1f5dc65e91d8b380c104621822d27c6e4233a878ae0fef5e"
- eth1_data:
- deposit_root: "0x5f5a8158ce7e1a776c1b6187d70abb5f6676b608626c8d051abe7795c8435946"
- deposit_count: "194"
- block_hash: "0x32c72593ddc2739d5eae88440cee25dd36d46751816d1e6f8eed0ef30de97fcf"
- block_height: 195
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x735a400964fac7b2378423de5960b50eaa02589ac565a271de0129a009f66614"
- deposit_root: "0x5f5a8158ce7e1a776c1b6187d70abb5f6676b608626c8d051abe7795c8435946"
- deposit_count: 194
- execution_block_hash: "0x32c72593ddc2739d5eae88440cee25dd36d46751816d1e6f8eed0ef30de97fcf"
- execution_block_height: 195
-- deposit_data:
- pubkey: "0xa38e925dd3c45de24e8d73e9170168dc8206035ea711741d91a35c24fa71bb7981b89bdca545ee68e8680307a754e801"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86bb5e37880c4338cf71f6e8712bb644c536d42369c715067ccbf57195781d66d6c321343cc2012d8384d22de7d1b1ff16d9cf7f6c4fbd3c0a5c78bfd15e3c88c3177d54b8967dba46627ab28f2ce2a0c7864d73364be3459fda509352129739"
- deposit_data_root: "0xf0715cc57042701d7d885798175984ad28a7034f132792da09509aa9df0ddc57"
- eth1_data:
- deposit_root: "0x2215ed2c63f505ac6fa32a11161d46f18db19bd56aed182298505b91366adb61"
- deposit_count: "195"
- block_hash: "0x04f7e15ab5591a7e1931772b057c38e3e385c6376d0e78dc0487be63de1d0ae9"
- block_height: 196
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x735a400964fac7b2378423de5960b50eaa02589ac565a271de0129a009f66614"
- - "0xf0715cc57042701d7d885798175984ad28a7034f132792da09509aa9df0ddc57"
- deposit_root: "0x2215ed2c63f505ac6fa32a11161d46f18db19bd56aed182298505b91366adb61"
- deposit_count: 195
- execution_block_hash: "0x04f7e15ab5591a7e1931772b057c38e3e385c6376d0e78dc0487be63de1d0ae9"
- execution_block_height: 196
-- deposit_data:
- pubkey: "0xa626ce67a47dea646ca21759fb026c6a258cc6ea8db330ee68cbd2455d1c347bbab51f3c08423eedecfa9e36920ef80e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaf63ef6fdc71c6e3adb00df9284be7862cd48ce1a48e8c46b8d2640f72de9a290e160ff1535277594ff03785112e245514287bda41fcde5e4f41099b651467c5e1e580ce2de799e2740a074386c99c7778ef7e4c2a945e40f6e553e152db4f1a"
- deposit_data_root: "0x11c9f14e452b20440a56ff34917760d8dcd5a8e630dc7287357181cd486facb8"
- eth1_data:
- deposit_root: "0x0fa3a4dc90fb01188e00d9df9f45687f0c8a947228db2d315bcf554f2f4244e0"
- deposit_count: "196"
- block_hash: "0x5c247a56ac7270505ea91e5701c596d8ca2ff96acc269238ad57898ec20b900e"
- block_height: 197
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x7a988bd4f4f2f44e82e3b09c2bfc32c9b2eeea372287b0222e2b1d9aaf4aa6d3"
- deposit_root: "0x0fa3a4dc90fb01188e00d9df9f45687f0c8a947228db2d315bcf554f2f4244e0"
- deposit_count: 196
- execution_block_hash: "0x5c247a56ac7270505ea91e5701c596d8ca2ff96acc269238ad57898ec20b900e"
- execution_block_height: 197
-- deposit_data:
- pubkey: "0xaae22c365554eb37e2f402f6e6e4bfb0aa9416d8dda0a2f8ea5647ba7dd32023089f4dcc111121e56b52b1fdc29067b3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2f3d0bd66262806b2e9d0683f26016d1b7aa719d3f2739b43516900f126fa7b05f45376bf968769bf9d23cc47124f961960c17f9ce4e1b8f32544aefcedb5711327128e0d54ab20c31c7e11bc6b16dc8360107276385a30180b225aaa3a5cce"
- deposit_data_root: "0xdcd3b1b400746a2b3933c4a326f05ae8eab21177b548c9a4b23991d67221db2b"
- eth1_data:
- deposit_root: "0xf0767d7bb07aac096d4fc126f24e653dae0ed20d2e78a537239aeb416bd9f61c"
- deposit_count: "197"
- block_hash: "0x9e2658d320b979325eaefb9a6bc7f8bb8d993ffe01dc5048a598f5532a2f7868"
- block_height: 198
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x7a988bd4f4f2f44e82e3b09c2bfc32c9b2eeea372287b0222e2b1d9aaf4aa6d3"
- - "0xdcd3b1b400746a2b3933c4a326f05ae8eab21177b548c9a4b23991d67221db2b"
- deposit_root: "0xf0767d7bb07aac096d4fc126f24e653dae0ed20d2e78a537239aeb416bd9f61c"
- deposit_count: 197
- execution_block_hash: "0x9e2658d320b979325eaefb9a6bc7f8bb8d993ffe01dc5048a598f5532a2f7868"
- execution_block_height: 198
-- deposit_data:
- pubkey: "0xa5c3572c3b770214c14beb4d403d00ffa981480eb850195c99f3b6a2418cef98df28b7f1543d48a2500bfbe25e18ad80"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c50c39e613fa154f1f7b0afd09e716982aa305d5b14fa151a387ecbf172ddb5072311ba32e850725bef0fbacd85fb701822a16e22c408af47500cc33b52c1f40c4ca15d2fb23b90da304e5d4c14ee828ba64556f0e3a4ba95b949ad0b050613"
- deposit_data_root: "0xd4386ba3269154bcebcf9be99f15c4a3c5cbb29f1233f4c8392610bf378bc7b1"
- eth1_data:
- deposit_root: "0xb900dfc08320f9c098a4eada49948bcd336be1f0b018ad9e741049dfb7b8ed93"
- deposit_count: "198"
- block_hash: "0xb7d727f382dcbb633b6354371ba93f697e4ee8974356879ad1e9071d041cab9e"
- block_height: 199
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x7a988bd4f4f2f44e82e3b09c2bfc32c9b2eeea372287b0222e2b1d9aaf4aa6d3"
- - "0xd6fd367da921cad3a94901ae5bd5b3cbc3dfd1462326a6d78aa556797d2a4637"
- deposit_root: "0xb900dfc08320f9c098a4eada49948bcd336be1f0b018ad9e741049dfb7b8ed93"
- deposit_count: 198
- execution_block_hash: "0xb7d727f382dcbb633b6354371ba93f697e4ee8974356879ad1e9071d041cab9e"
- execution_block_height: 199
-- deposit_data:
- pubkey: "0x8e793a86453b578e9b2f4c252e9ff18a8fb1af36fdd09d9144aea8e2b172738fde30faff3e9391d00827df5efb534821"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80b57d9e5602fdf0ea42b3ed7eec2f69921264575bd8a63a685cb796db3eb8009bd89f080548ccf9982aca0e475990b90e89e0f2ee025eb3a28f3a928924e79025d6f123bfefc6739685068bb7c41d44c39101612cd65f779c64e9b94b3aae80"
- deposit_data_root: "0x705b49ff60a831179dc633062c11329e0fc800bffd91cd2162ee5f9824bd436d"
- eth1_data:
- deposit_root: "0x90211ebb48dc63aec0f43b619b9de255f716983c02de0f14a5b22e002cf8e2bd"
- deposit_count: "199"
- block_hash: "0x7889af3b1bec5acaba75ac39a3d3b9e95ca78aca797f305510409b9b468719c9"
- block_height: 200
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x7a988bd4f4f2f44e82e3b09c2bfc32c9b2eeea372287b0222e2b1d9aaf4aa6d3"
- - "0xd6fd367da921cad3a94901ae5bd5b3cbc3dfd1462326a6d78aa556797d2a4637"
- - "0x705b49ff60a831179dc633062c11329e0fc800bffd91cd2162ee5f9824bd436d"
- deposit_root: "0x90211ebb48dc63aec0f43b619b9de255f716983c02de0f14a5b22e002cf8e2bd"
- deposit_count: 199
- execution_block_hash: "0x7889af3b1bec5acaba75ac39a3d3b9e95ca78aca797f305510409b9b468719c9"
- execution_block_height: 200
-- deposit_data:
- pubkey: "0x969ca05ea6e49aa9b35d41c3354096f022e9a86718ac454cc8140419dd2ef5c19af37d42733a434a0e77970117ab884f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa809d95bf1d42854575411ce2e535ea3b3cb263c07dffb715044442b196cd701ab25c79a5ae2440783f447c542f518680bbf949ba63ebd1f67bdbe832731a70fcfc6c3b549d2b160239ac852b41b4bd2bd23c88328bcbc6a20590a3fdaa8a3c2"
- deposit_data_root: "0xb2150789ea91596d6a1e50fe9841761330fdb7d4a8ad45528f7646684d9cc52a"
- eth1_data:
- deposit_root: "0xad8875e0af2f6d20643e3670fe9b991c24f3c0fecc85a59a41fb25c0e791fa17"
- deposit_count: "200"
- block_hash: "0xe9365f98552e964ec79bc2c5d2b0c741b2579c9558480d9ffaa1ee1d3df642b2"
- block_height: 201
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- deposit_root: "0xad8875e0af2f6d20643e3670fe9b991c24f3c0fecc85a59a41fb25c0e791fa17"
- deposit_count: 200
- execution_block_hash: "0xe9365f98552e964ec79bc2c5d2b0c741b2579c9558480d9ffaa1ee1d3df642b2"
- execution_block_height: 201
-- deposit_data:
- pubkey: "0x8b4ff71ee947785f545c017bbb9ce84c3f6a90097368cf79663b2e11acc53e18e8f7159919784f4d28282cb39a7113f7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4d04ea08df7c81fd63b7c08aabfc91858eeeebf022ee8dc1eb85b2d092555df04d55cc4c1c4994dc040493b1e310ea10afaf3631c04556b99c22cca3f4b51fc07b63d8eafc136d9dc25729de2b157493277de3ce6427a7828c7aee03ea73c54"
- deposit_data_root: "0xd543fb17cd7258052cfa9c1f3fba1a8a858ca4228f5d612b517030a0bf95badd"
- eth1_data:
- deposit_root: "0x15a652c1b3b70a8a66292accc0392096462bb6655e9d8528afb93d25732e75a7"
- deposit_count: "201"
- block_hash: "0xae4a7f8e521201b9b74056012a8bdb16a12ca537009ee7b2825cbf5277efbcd6"
- block_height: 202
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0xd543fb17cd7258052cfa9c1f3fba1a8a858ca4228f5d612b517030a0bf95badd"
- deposit_root: "0x15a652c1b3b70a8a66292accc0392096462bb6655e9d8528afb93d25732e75a7"
- deposit_count: 201
- execution_block_hash: "0xae4a7f8e521201b9b74056012a8bdb16a12ca537009ee7b2825cbf5277efbcd6"
- execution_block_height: 202
-- deposit_data:
- pubkey: "0x984a6c8f4b7545aabbe9e0341c5ff990a05508c94e3757da474daf1d70124c8213ba2457718ec2d1fc562fc0bb36213d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaf9e0247ecdab1f08ffeabf0b753f08007a14506b72377dbfb7d08069b43537995bee0d17a36be683d1d76d1f31218760ed3d72a992bcc4b8e33e1fee223c0614cca7f850d80e651628a3f1f0a129e5a2154e87e6f4c98978063f329eaeecf6f"
- deposit_data_root: "0xd4ff330e73b1afb26efcd9f7db884f99e14121b778ff54ed0f4cfdf5585d821d"
- eth1_data:
- deposit_root: "0x9c5993864595eabaeff8b60957115c80be20df7e4077c9799bc2718b85d31af4"
- deposit_count: "202"
- block_hash: "0x034d3912b8d10a6c82bff870992b671dd6053602d8b2ec63f5da2d533bbec9cd"
- block_height: 203
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0xd74dd49dc28c9adbab7fb5dd05c11f09a6c2ef7289e6d45b56462a2dc7879a0e"
- deposit_root: "0x9c5993864595eabaeff8b60957115c80be20df7e4077c9799bc2718b85d31af4"
- deposit_count: 202
- execution_block_hash: "0x034d3912b8d10a6c82bff870992b671dd6053602d8b2ec63f5da2d533bbec9cd"
- execution_block_height: 203
-- deposit_data:
- pubkey: "0xa14cc20155f6fce0f248f9c306a32cbff425272829f7d920073c599b48168fb018c82b2aaf7cbb8b5f6449340023c37b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa993e3a47f18a67b4c866ef09bc402471a32422eb2181c53dfbfe6636f8a67bda4ba86ed22d3c480f796f70a56c6b20914c4b80a014199f8b35ea115a9f6f2539283479d545d9a33dd5f6babc3d861d5b03cec90bac204239f074c08dbe9cce0"
- deposit_data_root: "0xd1a0715f2f749515ed034ed6a16583a2ba0276f53db1a55aa6cc9b3d795e99b5"
- eth1_data:
- deposit_root: "0x8d2051b62cacffd2a701ca5212d26832f0f4e0dec045d5c9a996fc1f3e3d4afa"
- deposit_count: "203"
- block_hash: "0xd4833843972af8732196ca814e0ea093f8113431a00b6173b899a1907f449971"
- block_height: 204
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0xd74dd49dc28c9adbab7fb5dd05c11f09a6c2ef7289e6d45b56462a2dc7879a0e"
- - "0xd1a0715f2f749515ed034ed6a16583a2ba0276f53db1a55aa6cc9b3d795e99b5"
- deposit_root: "0x8d2051b62cacffd2a701ca5212d26832f0f4e0dec045d5c9a996fc1f3e3d4afa"
- deposit_count: 203
- execution_block_hash: "0xd4833843972af8732196ca814e0ea093f8113431a00b6173b899a1907f449971"
- execution_block_height: 204
-- deposit_data:
- pubkey: "0x89737986b89c213367ab0fb9a4eb998d9b0b713143cc8b0f209c9355607daa4f6e6c925dac3026890e291a9480463395"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2a249d89d206c1e335bffc3838497ab0a8162bb827aff7ced1f08b819ac0e13583a6857eeb5c6eeeead7510062febaf0e142ab4c56a00802bea141e09e8708e750e3049cdbe91bb1448ffa1d2ec4f2c09a1626a774ceb0d0cbfe2e3a3c86207"
- deposit_data_root: "0x75b338b16d27eb10fbd28510660fe5816d30c5b2770abf69bf55aba29378746c"
- eth1_data:
- deposit_root: "0x1a2c95f781f6e6bc105146aa1405aa3a157e835e3159aae5e06a90fdb5e2c3e5"
- deposit_count: "204"
- block_hash: "0xadeb61523c297ae6488924eeb397706fbd36b90460ba258d39eddcc162bd32b9"
- block_height: 205
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0x81af419186b40e88c6b75d4a7e50d2eb478b523a890245e90a5a8666c14d8920"
- deposit_root: "0x1a2c95f781f6e6bc105146aa1405aa3a157e835e3159aae5e06a90fdb5e2c3e5"
- deposit_count: 204
- execution_block_hash: "0xadeb61523c297ae6488924eeb397706fbd36b90460ba258d39eddcc162bd32b9"
- execution_block_height: 205
-- deposit_data:
- pubkey: "0xacd8a33698c0b95294943f0642c8b8919bdfbf1e92c61f26107f0f9ad989497742b58363e3d885e4d41a3bcfcc9c073c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x88acce1b8ddba924e58450a9bbb256fc8cde985dcf0c13fad60a248adc6bcbefd26846db5bb49401baef27fd3599074e09a7b18cc4c7b509585febf85dc56d346462b209359ec2cb16d2684a23d744ef4fa0c24e25078408b73f31aaec0256a7"
- deposit_data_root: "0x96fc4bac61a6cd54baa17b7434ff2d25eb1d0e3442a602af6d484cb1db9cc6e4"
- eth1_data:
- deposit_root: "0xd50f56058861337da0c947bcdb625f96a40d3ca4621c58b07eaf8f311aef09db"
- deposit_count: "205"
- block_hash: "0xcc2b772737ecdf295382ee2a1ee8894aa42f33bea847e41e308728a0f31ed472"
- block_height: 206
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0x81af419186b40e88c6b75d4a7e50d2eb478b523a890245e90a5a8666c14d8920"
- - "0x96fc4bac61a6cd54baa17b7434ff2d25eb1d0e3442a602af6d484cb1db9cc6e4"
- deposit_root: "0xd50f56058861337da0c947bcdb625f96a40d3ca4621c58b07eaf8f311aef09db"
- deposit_count: 205
- execution_block_hash: "0xcc2b772737ecdf295382ee2a1ee8894aa42f33bea847e41e308728a0f31ed472"
- execution_block_height: 206
-- deposit_data:
- pubkey: "0x964e84e1272dcea0fd79d698c1db18e847a5abe1406ef7988e61f39e3f1ef46371be5c25b6c2bf7e53788730f702b735"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80f6d4e14705862b42e0ba0ab0a063488d8c2a68a61294029529e0eeccf938a0521d81a06147fc84ed867d1ac90b61b613446206fb88cabb7d1dba91eb9808e0dcc82e474e57be768868aa76e2be21dc777ce6ae0c083fa2ddc5abea3325bed0"
- deposit_data_root: "0xb0cb5384d711a5179c1c0fae14f4b843321abdce75b4203796e838cb6bd8f9ef"
- eth1_data:
- deposit_root: "0x750757bba12b4098e68006661bb2504a51ecd34f699881f9ed0191f0ff10f694"
- deposit_count: "206"
- block_hash: "0xc030e84c7c82778ecb278a7970d6f0d1b453a126fc97b57b964aff30e0f4d0c3"
- block_height: 207
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0x81af419186b40e88c6b75d4a7e50d2eb478b523a890245e90a5a8666c14d8920"
- - "0x177af982879e5f9786c25fcc42e0a20e48e09419dda7d03e71c6fe190adaeb5e"
- deposit_root: "0x750757bba12b4098e68006661bb2504a51ecd34f699881f9ed0191f0ff10f694"
- deposit_count: 206
- execution_block_hash: "0xc030e84c7c82778ecb278a7970d6f0d1b453a126fc97b57b964aff30e0f4d0c3"
- execution_block_height: 207
-- deposit_data:
- pubkey: "0xb406b1521362c206669d15b4e5448aae2f1854c707592abc612973b4726d47edf3bcd9ecea1a4b6cffc6a9f7b039921f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8122c635f73ce71fa05d9680c5c48c39085864af2e811c324c233c73fd12aec80390bb306a6103bfdada9a2679874261462273f765cc1c5ebce0dff42cd9e80ff21fed9fb53e755602db2646742013a4e6ea25470da6fc11a3ad90b06651f43"
- deposit_data_root: "0xf74d5d7d3af4a3bf5f6695b1f34ab4d5336c9ef290b8a1794f44db60a1d85b7f"
- eth1_data:
- deposit_root: "0xe39b947702ff8af4cc4e50acaa3fc0d9ab834dd60237e134122f4a5b3690644d"
- deposit_count: "207"
- block_hash: "0xc3dbea25648a192a58491607281a486afb876647edf3523a4ae7cbebbe7067e2"
- block_height: 208
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x1edb1ff214185dbce83d685ff59906b779b360f07616112aa60e2d2dc8508c51"
- - "0x81af419186b40e88c6b75d4a7e50d2eb478b523a890245e90a5a8666c14d8920"
- - "0x177af982879e5f9786c25fcc42e0a20e48e09419dda7d03e71c6fe190adaeb5e"
- - "0xf74d5d7d3af4a3bf5f6695b1f34ab4d5336c9ef290b8a1794f44db60a1d85b7f"
- deposit_root: "0xe39b947702ff8af4cc4e50acaa3fc0d9ab834dd60237e134122f4a5b3690644d"
- deposit_count: 207
- execution_block_hash: "0xc3dbea25648a192a58491607281a486afb876647edf3523a4ae7cbebbe7067e2"
- execution_block_height: 208
-- deposit_data:
- pubkey: "0x8ca1bfff2cea25ae77249cb18146a39b9630be5947b65d15044a5e5816b6d29dac9da83504083bb8e87dbe97dfb6451f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb83a7cf087d9dc1d5d587b103b84f2dbbfaa07d9385861937d2733eacb7c1e291336214aa6eea4b38377fb2a2a7de2170edf187e150125be3d3f8dee35f71b86be7bf4e8b390bfec55f15330dba9eefa1003fa9cc5122fa5c97d8d699f2e0a2b"
- deposit_data_root: "0xa0a33dd10f90a1ae86de6926edb1c128943a276b0532426521d187c1d5d363c6"
- eth1_data:
- deposit_root: "0xd2fe6e21e57ccfe1ededd19b56161b95e46022936207835b5563617107574558"
- deposit_count: "208"
- block_hash: "0x04a5433ddf3ad6d7dc52c745d96e863204f6f5add434e7d3a34cef73dd92e34e"
- block_height: 209
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- deposit_root: "0xd2fe6e21e57ccfe1ededd19b56161b95e46022936207835b5563617107574558"
- deposit_count: 208
- execution_block_hash: "0x04a5433ddf3ad6d7dc52c745d96e863204f6f5add434e7d3a34cef73dd92e34e"
- execution_block_height: 209
-- deposit_data:
- pubkey: "0x8c2e07abba50e0e1c624bae0dfff418f8f00502e377840f72e067cd33917a209c525fea7dcc7c44f0195a3b9a5dabbb5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b9f750ad5ca21b49bee7a975da855675f22904ed9bfc52d8a9491e6d96e8ba58fd67270d3084e91e3cc7ee7321d683d10864550590818c393d4c2a0003926e2e5a73164336c216babe5a0fef22ed447aa51c67cd4704762da4302e1f7d3b49b"
- deposit_data_root: "0xbdab20d7935a00c76b38e589b2073a6304eeed96e201423a7e420619edbbe893"
- eth1_data:
- deposit_root: "0x99fb82c1633a127efca032676fae7239a258b230c9323ec75644c7e659cbb231"
- deposit_count: "209"
- block_hash: "0x4d98b647dfe4547b79591778779136b4586160a163f5af4162fff546817ce4c4"
- block_height: 210
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0xbdab20d7935a00c76b38e589b2073a6304eeed96e201423a7e420619edbbe893"
- deposit_root: "0x99fb82c1633a127efca032676fae7239a258b230c9323ec75644c7e659cbb231"
- deposit_count: 209
- execution_block_hash: "0x4d98b647dfe4547b79591778779136b4586160a163f5af4162fff546817ce4c4"
- execution_block_height: 210
-- deposit_data:
- pubkey: "0xa4c11513391dd190b1ac0cf8a1c2c1b9c39d925b38aecb950d357283beee49ab97b1d7dfb34396bcaf1c25658fdf7713"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb82675644e2826c0d7f77f6e4579d2ba98d37330591e05c3e87c5de32a8c97ff1fa48902289ec52d990fb81d2172a5590c569bdc5da0f0f7b9e7e07d86433f54197a37457ad65cec11b8028e88c8e175e45530910925fa6720be77a7b5323d8f"
- deposit_data_root: "0x49b40e35773ce653a0d51a6a45e20d9490df06160eb3059830a1f7ac9fb7393a"
- eth1_data:
- deposit_root: "0x10530b32816c9a5d1213ecba4ea82e0746d706721bd5dd14441b32050a6c33e4"
- deposit_count: "210"
- block_hash: "0xf35c48ec777e6646c99c7e1a873e949bf426354e55c2f115fe9670914e249af4"
- block_height: 211
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0xa94a6052c766a8599b6c20b938f754be5554f1b7a7ce0c8d337160a8b5c5fa68"
- deposit_root: "0x10530b32816c9a5d1213ecba4ea82e0746d706721bd5dd14441b32050a6c33e4"
- deposit_count: 210
- execution_block_hash: "0xf35c48ec777e6646c99c7e1a873e949bf426354e55c2f115fe9670914e249af4"
- execution_block_height: 211
-- deposit_data:
- pubkey: "0x92afb506a8345b325a4fc1cf1135455eac709fe1c623bd8f0972cd9e51a763cc1e80bab1f7e01976d1c4f13af3c57caa"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xabd9696dd03623a4c7ee8eaba9dd7d40a3e2658d14c46ad3ba0e07fb6a8003788a6b22cde39b54b38e41549d4b278b270d4423ae1cf28228b92d29763200a97e454f66a2eb84e4596fa5b1776d288639c6ba9e2b8f07c6695e25d6369f59d9f6"
- deposit_data_root: "0xeb7df9a089860361315c6c55ed2695cad55caa92a751329b1c7f07e2c8055ccf"
- eth1_data:
- deposit_root: "0x30c2e1bb452f52ccf55edb7abc1ec4774dc3058e166ac655d79640f1226a7943"
- deposit_count: "211"
- block_hash: "0x7fa99b674a69b2752edf65932a26abdb23109fd68632de579ee075271fb91e80"
- block_height: 212
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0xa94a6052c766a8599b6c20b938f754be5554f1b7a7ce0c8d337160a8b5c5fa68"
- - "0xeb7df9a089860361315c6c55ed2695cad55caa92a751329b1c7f07e2c8055ccf"
- deposit_root: "0x30c2e1bb452f52ccf55edb7abc1ec4774dc3058e166ac655d79640f1226a7943"
- deposit_count: 211
- execution_block_hash: "0x7fa99b674a69b2752edf65932a26abdb23109fd68632de579ee075271fb91e80"
- execution_block_height: 212
-- deposit_data:
- pubkey: "0x978b5194d96515146754465533db2d854e58371f26e78fe0eebc5c5b65917a3611947cab3bf7fc645e3cb870e4826019"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7a1cbd47302acfa136a0114abe23123670fa4ad08e76fa4bc86007e6d941c71ce51dd92cbf1bf0d8836b4ae49b762a609559b7e798e3652a1eda20d89ace8606fff2ca5b1fe83c7783bed9267a18cc29e119c361329c574cc64fd8d209221d7"
- deposit_data_root: "0x4715ee6c9d226f8fa5da1140ef6cd9f7f2f67a417c24498377025d176df07ddb"
- eth1_data:
- deposit_root: "0x64f8471778ca893643db2d0be9bf4ba437611a0bc61cdcef451da8250e30baca"
- deposit_count: "212"
- block_hash: "0x0176fbf110c6da3ef4495909cdc1928eb1d9c77a7f41444b89c73dfaab805caf"
- block_height: 213
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x80be627c56fc721728d409e5f72984eb86cf51276c72be17a7def353b43a0c36"
- deposit_root: "0x64f8471778ca893643db2d0be9bf4ba437611a0bc61cdcef451da8250e30baca"
- deposit_count: 212
- execution_block_hash: "0x0176fbf110c6da3ef4495909cdc1928eb1d9c77a7f41444b89c73dfaab805caf"
- execution_block_height: 213
-- deposit_data:
- pubkey: "0xa3f841f04d3410b06a4b4eb31b3fd92eadcf486af60986723d34ef7b8a9908541ab6e7e0ecf421f593f86afdf8cbe894"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa810363310e7254b59997009c7b4739bf34856e5b16b7bbcebc61c23efdf727e36d9be21eaf4cffd2eaf4563d9fe6b060eb81f52882047c188136b132f34cdd5d9b67b04acdce7684aa16e9e378de9162c5886bb48cfa76435655b099d5190a7"
- deposit_data_root: "0x8a2db165a79f35c68b6f84336b364a56a68eb231908eec22d8b32dd85fcc731e"
- eth1_data:
- deposit_root: "0xee9bc848d593ff36992ed82fa51763caa78d4e5efd3a1fc7ae9f0fa7e19a8e94"
- deposit_count: "213"
- block_hash: "0x51c836750936babe4616f3402135e0ab0dd470e1151c44879a4d7662b9b08be3"
- block_height: 214
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x80be627c56fc721728d409e5f72984eb86cf51276c72be17a7def353b43a0c36"
- - "0x8a2db165a79f35c68b6f84336b364a56a68eb231908eec22d8b32dd85fcc731e"
- deposit_root: "0xee9bc848d593ff36992ed82fa51763caa78d4e5efd3a1fc7ae9f0fa7e19a8e94"
- deposit_count: 213
- execution_block_hash: "0x51c836750936babe4616f3402135e0ab0dd470e1151c44879a4d7662b9b08be3"
- execution_block_height: 214
-- deposit_data:
- pubkey: "0x81fba887a59873ac21711818cc8a63b2d4be1a69627f8c70586a56328a96aff64b880f1a07c125eda24784dfea0bacd4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93595db7bb94204b0825b54a3feaa6fbbbd2b7b2500eff772129f5d1633e5d3aabf48d138d91a11f3432fa45d49a7a2708ff91c8e53bffd0da37f03b03aebe01626d67ae5388a38325056e0ee9419f511520511fc772a51f4d512df91d562f24"
- deposit_data_root: "0x25cead55a29f7e5da33987cb5519bfbca4e10d14b747ec5d0e0a5d20f92a59cb"
- eth1_data:
- deposit_root: "0x0a6f0bafcc040a1296ff468e4ee75a20d5d26cc395113fefb164f4367ba017e5"
- deposit_count: "214"
- block_hash: "0x16b04fa33d14e124eb5a40a6af1b01daf48c86937982ae4d208f63bfbc4c7d7a"
- block_height: 215
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x80be627c56fc721728d409e5f72984eb86cf51276c72be17a7def353b43a0c36"
- - "0x3785e11a23b4330f60f96e5dad69c55dab1a4c26c521e1c02f31f53639928bb7"
- deposit_root: "0x0a6f0bafcc040a1296ff468e4ee75a20d5d26cc395113fefb164f4367ba017e5"
- deposit_count: 214
- execution_block_hash: "0x16b04fa33d14e124eb5a40a6af1b01daf48c86937982ae4d208f63bfbc4c7d7a"
- execution_block_height: 215
-- deposit_data:
- pubkey: "0xa9da8f5d1d62844df8f6fae763aa653127d6eaad1b4d8ba0b3b3417e9c486be3cc879ebad7fb182dcb364d3a292ab07f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8748cde6cce3b3b7ad6b0a606e3bbefcfd26794817699117b7ba4993df77ebb656954eab6d0563447620584f04d08fd7106462757153f4ee774ebfc316c9a79836dc02beae801f29c1da0933928a8fe0f326a01538e3e32a6f10f728edb34eac"
- deposit_data_root: "0x884ed496077a53a281f0d0b56028a6d3947753cee6ab57d9bbb71cd9bee577db"
- eth1_data:
- deposit_root: "0xdd69faeaad85b4e2093afd6b377c9bc01987a0ae95ce1ca8f7dcc05407cdf147"
- deposit_count: "215"
- block_hash: "0x7b4865729e81f44da4be1ba22a9dcc7e422c9532974f5a9062ec67ac9bd62cb8"
- block_height: 216
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x80be627c56fc721728d409e5f72984eb86cf51276c72be17a7def353b43a0c36"
- - "0x3785e11a23b4330f60f96e5dad69c55dab1a4c26c521e1c02f31f53639928bb7"
- - "0x884ed496077a53a281f0d0b56028a6d3947753cee6ab57d9bbb71cd9bee577db"
- deposit_root: "0xdd69faeaad85b4e2093afd6b377c9bc01987a0ae95ce1ca8f7dcc05407cdf147"
- deposit_count: 215
- execution_block_hash: "0x7b4865729e81f44da4be1ba22a9dcc7e422c9532974f5a9062ec67ac9bd62cb8"
- execution_block_height: 216
-- deposit_data:
- pubkey: "0xadeb5ccef7679c5d26e97ac5d2c8222058bf8b7c5eaebd31db3f3ecbb8d00987e2b921711dc6953eff6852601c57b198"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb6b988317f7e9f48abbe85d6719ab37ed5abc8e98d31a4a37120767a70b9e1cf4a5e3b391b9941a201cc7a1f004fa97a0a1e3c8767e0fdac133d9292a8eb6da59e5ab28473bf87d0ea514ac69c60f1b56f9d31aea615fa48ac7feb17e1ebb4b4"
- deposit_data_root: "0x8699f7dfd9049a9383abc845a33cbce20d6bccd88b08cfb4166e298ead4e2dd9"
- eth1_data:
- deposit_root: "0x5bd775b2a763bac39331c22c5a1fb189221e22f7be74fb91dc7de0eeb7fcbfb6"
- deposit_count: "216"
- block_hash: "0x3660dc622cb11cd94846055fbeb73df41c3a088242dd96c2e5159de3f1cadc48"
- block_height: 217
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- deposit_root: "0x5bd775b2a763bac39331c22c5a1fb189221e22f7be74fb91dc7de0eeb7fcbfb6"
- deposit_count: 216
- execution_block_hash: "0x3660dc622cb11cd94846055fbeb73df41c3a088242dd96c2e5159de3f1cadc48"
- execution_block_height: 217
-- deposit_data:
- pubkey: "0xa4e2f5a419590f3d30cbcf9cac0b4a89b636458dd6d38aa763694d4edd787056536089077d8e71cc4b182f8e87dc7916"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa4c51bc0d55bfc64de2f5123bb685777f33784bd632b61e65166ca8eb8084d8effe9e93e4a7359b88f4d03644fba521028e45f33996189e216637655ac2de55dcb0266289b81cd8b4e83c9e2bf0b7bd53d95942f66c7ee9d85776c8ff7af6ce"
- deposit_data_root: "0x1c3dd97d82fd3cc85dfedad67f70b39cd7bc2df5d376eee91cdb3137e1f420da"
- eth1_data:
- deposit_root: "0xebbdfeb489d87fc3cd7e79ae85adbb1ca2237cc64b6e4d37a6de996f32f6ea3e"
- deposit_count: "217"
- block_hash: "0x861a80af90e9a9b72718b0f49dac71c9c100cf0d00ecd0816b52278ce534e106"
- block_height: 218
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x1c3dd97d82fd3cc85dfedad67f70b39cd7bc2df5d376eee91cdb3137e1f420da"
- deposit_root: "0xebbdfeb489d87fc3cd7e79ae85adbb1ca2237cc64b6e4d37a6de996f32f6ea3e"
- deposit_count: 217
- execution_block_hash: "0x861a80af90e9a9b72718b0f49dac71c9c100cf0d00ecd0816b52278ce534e106"
- execution_block_height: 218
-- deposit_data:
- pubkey: "0xa365251e868fae8780f009c14c7ddc349389230b75c79e11628b798dad880d9704a10f3358bea40f4136fe37fdec13ca"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8ec3bda16c205360636e42958f2076ed5e245cb48f3ea395d7680c689f62eb2bce4839b78129884aac0dab5345706f560310654681b3542f364b7aa4e426109ec7a772070be08997e80a890e2c1e8a4606f50cddc1fa8298ccb038719561bcc6"
- deposit_data_root: "0xbc2cf0159a36545c3dee043c7c612029a41ba7e4ac055d4c63ec9eb5b6564738"
- eth1_data:
- deposit_root: "0x7bc4420c8f3a21b553c643f7f33d830cfc6a658e9c5e53c24828403d3f487b82"
- deposit_count: "218"
- block_hash: "0x1fbb6ad18010df3607676411ede951c80c862b09db67219380cccdeed7d01422"
- block_height: 219
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x555908f2ac7299a40b5bb9269ac6d4ea86a65af7b648d63181f59cfa8314d17a"
- deposit_root: "0x7bc4420c8f3a21b553c643f7f33d830cfc6a658e9c5e53c24828403d3f487b82"
- deposit_count: 218
- execution_block_hash: "0x1fbb6ad18010df3607676411ede951c80c862b09db67219380cccdeed7d01422"
- execution_block_height: 219
-- deposit_data:
- pubkey: "0x91ad339cd616316e79470c8695cd83b3811eb762f292c9a67c802b84e8e074ef5d208704dc1d5fb4a8343e0e44b25807"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85d02a1704c8fcdcce59ac1ec6868f282d66839ea77e3673cabcbc178b8cefa93b4dec28167f38a83dacfed4b543f1260375c743bd25e015d8450ae0503594afd8eb394411dbd377f67b16436b6fafe1133e5012c474158aaf2881c040f27716"
- deposit_data_root: "0x0407440d40aec95c78548e7f9cfe22144f11166bd468e553a150733962098bd2"
- eth1_data:
- deposit_root: "0xadfa2dc986c1769723c3007c92843f9fba2a30d162548bfd2c5073a0520ef59b"
- deposit_count: "219"
- block_hash: "0x274170cd5f2790ae9938185e411eeb46d258cc7a1d13a3db5be028cc55a832ee"
- block_height: 220
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x555908f2ac7299a40b5bb9269ac6d4ea86a65af7b648d63181f59cfa8314d17a"
- - "0x0407440d40aec95c78548e7f9cfe22144f11166bd468e553a150733962098bd2"
- deposit_root: "0xadfa2dc986c1769723c3007c92843f9fba2a30d162548bfd2c5073a0520ef59b"
- deposit_count: 219
- execution_block_hash: "0x274170cd5f2790ae9938185e411eeb46d258cc7a1d13a3db5be028cc55a832ee"
- execution_block_height: 220
-- deposit_data:
- pubkey: "0xa2d7d0d6f85894bda115022811b35ed5689143187a911fee5bcd0d6b1c78f4db3542223f496024fb2279b8ee76b5ea79"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3d3e4034783206e696e6ed0fe1bb3d85b3ff78892422daf8f73b60c3526e862463c0ebec3f57fee778adadac8c4e096016430f0e39659ce5cb4ff72e377ef585b0e5fc06502fe030cc19c6ea3b63c475c4f151c698758f3ab55c6a757ca004d"
- deposit_data_root: "0x4ff35fdd7abcb307af9cd011f196a1dcc2383905c9f5267ccd8e12729932ded0"
- eth1_data:
- deposit_root: "0x6c54753ac7f623632b80b673c081a8aaef63506b1e4125e3d37557e191c911dc"
- deposit_count: "220"
- block_hash: "0x75b5f98560bcca1d3ef1f0ec2409dbe6ade0e7c167446aeaaa2834c4edbda673"
- block_height: 221
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x4615edc70a037bfbbe30e36784fc579c02930a553305855c6201fa479683dbd9"
- deposit_root: "0x6c54753ac7f623632b80b673c081a8aaef63506b1e4125e3d37557e191c911dc"
- deposit_count: 220
- execution_block_hash: "0x75b5f98560bcca1d3ef1f0ec2409dbe6ade0e7c167446aeaaa2834c4edbda673"
- execution_block_height: 221
-- deposit_data:
- pubkey: "0x80029a26a45145f67892bfb25783d04f700e8917afc2b406695d4443fc3a45ab9c2c0572c357a33a9ed3877ebc479822"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7f1069867daaee8b61e9e4494feb875e7192624aa37058b3862f796ef13e72df222abc75b902324af95af6baa62b5c40fbb70f59aeadcd4eb4a22a2591aeb150e9b04fbce014b4bebff2af4a7f38aa17ceb65c01cfb2aaab6f290703d12f878"
- deposit_data_root: "0x8d9db83da28ca8c0edf22485af80afc1f19b144a3b44797cff3f9b11fc580f0f"
- eth1_data:
- deposit_root: "0x994cebba4398a53a0b2acfe1754f7e26ad34f11cbdaa520bf72099e5ba45cfcb"
- deposit_count: "221"
- block_hash: "0x9f3818b078a804575ae9a09ac84ef7268274b564cb832e78662d8febb4b9e81b"
- block_height: 222
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x4615edc70a037bfbbe30e36784fc579c02930a553305855c6201fa479683dbd9"
- - "0x8d9db83da28ca8c0edf22485af80afc1f19b144a3b44797cff3f9b11fc580f0f"
- deposit_root: "0x994cebba4398a53a0b2acfe1754f7e26ad34f11cbdaa520bf72099e5ba45cfcb"
- deposit_count: 221
- execution_block_hash: "0x9f3818b078a804575ae9a09ac84ef7268274b564cb832e78662d8febb4b9e81b"
- execution_block_height: 222
-- deposit_data:
- pubkey: "0xb6c8c112c7802a29579e14b228ae6a33fd7f0a3d33d06708b0f07cf7ec18f48e5ed7d5c47e7942c2aea2d1f4dd95557b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x82d56bd4b5cf49b4aa037a0fac68e16f6285b7e2156e52267b15a0f424c60f6df11456d6ee28dd6e48782c52fdae8690062b82574903fe2f1a0b6a502f9667957022fb4685f9d77576cb580148448f1a8d223e2d3809c55d52314b33033053e7"
- deposit_data_root: "0x9c5e003d673975a5d0dd59c797238f6699c03098dafaf05c841725e13f2211e7"
- eth1_data:
- deposit_root: "0x3190b4adb59dba145f8bbcc6e138e92173e69a57b657bd09822f0dc4699bbd6d"
- deposit_count: "222"
- block_hash: "0xd35aa31fa61ada5bdfafd207b08316b9cf404bbbbb655756be1654367a556dea"
- block_height: 223
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x4615edc70a037bfbbe30e36784fc579c02930a553305855c6201fa479683dbd9"
- - "0x9d39bef25d1cb967f1c2afc70f08d3b10fa353154698513f0516f4a2326ef1c2"
- deposit_root: "0x3190b4adb59dba145f8bbcc6e138e92173e69a57b657bd09822f0dc4699bbd6d"
- deposit_count: 222
- execution_block_hash: "0xd35aa31fa61ada5bdfafd207b08316b9cf404bbbbb655756be1654367a556dea"
- execution_block_height: 223
-- deposit_data:
- pubkey: "0xad4beca6ee84273739c03792e0a2096337c92fb096f7a902e0b09b8bf38d3f67c27a00b05d3ca69a0c9a43b491e8af4b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83afd2f9eee050a9e4f27651dca18b4ac1a4a48523aaa8d41fd7c87b26e288a07e4ff33ffd243fc053204b10a9abe3cc02b014ab31cdea51e94094d670dc9f6c830dc0c04f078cfcd74cb3cafa0bad02d99433d67a2377b53908062267573dc5"
- deposit_data_root: "0xa2c62c2afa8009d90ee3f7ded14aee4bf2d35ecea17026a011447c433f42986c"
- eth1_data:
- deposit_root: "0x21511637fa74488b88e6b0831a941619772a0679c69c43f0c7a91ec5ecda1b6b"
- deposit_count: "223"
- block_hash: "0x4320d44ec19761231557697186b0c02d807a9980a0a55c0af4b308bf9276fb65"
- block_height: 224
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0xdc8256156a85778064cc0f46fab037bebc4ea0f98abe602270d370a7938cc711"
- - "0x500bcd7598a4378a5c0ab9ae9ed217c3ca4c47ae0e0d34b7f5d9c987780cc413"
- - "0x4615edc70a037bfbbe30e36784fc579c02930a553305855c6201fa479683dbd9"
- - "0x9d39bef25d1cb967f1c2afc70f08d3b10fa353154698513f0516f4a2326ef1c2"
- - "0xa2c62c2afa8009d90ee3f7ded14aee4bf2d35ecea17026a011447c433f42986c"
- deposit_root: "0x21511637fa74488b88e6b0831a941619772a0679c69c43f0c7a91ec5ecda1b6b"
- deposit_count: 223
- execution_block_hash: "0x4320d44ec19761231557697186b0c02d807a9980a0a55c0af4b308bf9276fb65"
- execution_block_height: 224
-- deposit_data:
- pubkey: "0xa9ec8e4f705f27e6991a43ce006155825776666664d03be89929c4e5c9a01c7b759c1751e16b7a5d12084c419e97878d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7b8b994844e1f99366d6b36e6802dc9e9c9e93898bbe2856b17b47f3ee086dead8413745f983d2d02aacbc58c623faf096201428d8cb54a5632334e9e486279e1c055fbb7b993827ee6823dbd633b3f5adc742133f2835470e2c047410d0218"
- deposit_data_root: "0x757bda9525f7bf25b15158d2eb44382b9271d489703752c15c79f2022e8bf9c0"
- eth1_data:
- deposit_root: "0x7abe7feec57fc014c31f919a1706868a569b15e5721201500f8a502f2c38ca73"
- deposit_count: "224"
- block_hash: "0x2e1d1bd56695914502d3d69e874b7969503fd2bddd90402671ae2e58210e30e4"
- block_height: 225
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- deposit_root: "0x7abe7feec57fc014c31f919a1706868a569b15e5721201500f8a502f2c38ca73"
- deposit_count: 224
- execution_block_hash: "0x2e1d1bd56695914502d3d69e874b7969503fd2bddd90402671ae2e58210e30e4"
- execution_block_height: 225
-- deposit_data:
- pubkey: "0x801a35e02410c44a3d81b564980738fc5a1d4d15b887c9477c8835c9038233fceddfac4c572226599b25fe3faefa85b1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xafcafcad14dcb0b9aa9cbd21fefdee102e9da1439d676e7721edd62641b218dcb43264f361e56e2aecaffc31865c0f9304c7ebe5ce98f2c8dc230029bc681d9282b80ee0a4b1f18e8bdbcb80e6963608bc9d02182afed40ae381347577395f9c"
- deposit_data_root: "0xb0c1df18776f2378e753ae8937bce428eeed11559e3e00da552ad63fcebdefca"
- eth1_data:
- deposit_root: "0x3f5c02cdafa88b492e4e0e4a424dbe520959a048044e2c214460d9aea2fb203a"
- deposit_count: "225"
- block_hash: "0xb382a1b5dbb7b22d33c0000937f48cc9d2a1902576c2f789b2e13eeac8e295d0"
- block_height: 226
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xb0c1df18776f2378e753ae8937bce428eeed11559e3e00da552ad63fcebdefca"
- deposit_root: "0x3f5c02cdafa88b492e4e0e4a424dbe520959a048044e2c214460d9aea2fb203a"
- deposit_count: 225
- execution_block_hash: "0xb382a1b5dbb7b22d33c0000937f48cc9d2a1902576c2f789b2e13eeac8e295d0"
- execution_block_height: 226
-- deposit_data:
- pubkey: "0xa38b922e79533b5fbec5f710ad90837cfce8073c982c57597027e5b6facaabc1edac06c7014fb1bcf8e11aaca4049dbb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x813753be7c3419e592c33627668db7e74bae071c775b069194853355f9b91755d7dcc77672ebc011f313c8e3dafecc900f63260e6247d7a1b3c08ff3a6f1c9ff5b805b073049d1d197867d66cf9d356a3f6200041b4722d72564aeb29a0d4a7a"
- deposit_data_root: "0xb7c0ab5e3995215280d9af900c21a86dbb5d2cf9ff454f7a762b699358e9558c"
- eth1_data:
- deposit_root: "0x3e59ddbdc9744648e98694f1fb660d80bed43d554cee48dd274b482847d8c1c7"
- deposit_count: "226"
- block_hash: "0x6a3c9dafcc60d22e4747369ddd595545dacdf29926f2d3d6d4344ccb76fd8760"
- block_height: 227
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcb67f19e86fe3c871884bd661d1a82b3780ca2e36b225490607b2a6eaf66a552"
- deposit_root: "0x3e59ddbdc9744648e98694f1fb660d80bed43d554cee48dd274b482847d8c1c7"
- deposit_count: 226
- execution_block_hash: "0x6a3c9dafcc60d22e4747369ddd595545dacdf29926f2d3d6d4344ccb76fd8760"
- execution_block_height: 227
-- deposit_data:
- pubkey: "0xaf4cb80f788305b5c22f5a16bd3f5d2f2f50a403e4171b78e267a4e2d15b14beb04735b9ec206751a8163dae9ef3e96f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x828d01fe50f60180f2639e9337a79c130615172a25692bb29c0e21b7a6644c63820b38840fd2dce4c425faa1c8ae96bc19d7761cf0db0493413ab186acb3fe78dae6c3db6d815d91f817645646d54ea03738db3b2ca686344bbbfadd06299c45"
- deposit_data_root: "0xd8a2270f803bc660d2ae17e446ea8a47d59fbac4662232c48d7093b28bf4446a"
- eth1_data:
- deposit_root: "0xb1d7530096f2c5173ff8c3568bdc8dc0eccff29e5697ee803b488a9b1c89c451"
- deposit_count: "227"
- block_hash: "0x1c539da3e3764a8e1dd17e19451b72437daeb6f8fe45e592e8d96a7970efad4b"
- block_height: 228
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcb67f19e86fe3c871884bd661d1a82b3780ca2e36b225490607b2a6eaf66a552"
- - "0xd8a2270f803bc660d2ae17e446ea8a47d59fbac4662232c48d7093b28bf4446a"
- deposit_root: "0xb1d7530096f2c5173ff8c3568bdc8dc0eccff29e5697ee803b488a9b1c89c451"
- deposit_count: 227
- execution_block_hash: "0x1c539da3e3764a8e1dd17e19451b72437daeb6f8fe45e592e8d96a7970efad4b"
- execution_block_height: 228
-- deposit_data:
- pubkey: "0x8e0d2214a6f4364590a4acbe3db7b3757b6f2f1eee526babc383e68fee4a7c9735a672f83aff5e9384d66b2fe264c9b1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb07f7ee9cae121e1482ad8cf0855b4ea785bf039f3c09032e417f9b6418b83ad4c7e68f9b68ae015953f5519fd47c8a604d61acf88b0a10c6bb0061f99320be1ea016e3e07e5d6078574ff97d5e9fc315f5156cc6d4f79c541cec94cd5872dc5"
- deposit_data_root: "0x6bef5bde9f19342720ad3e132be8e8b9f7bf1508882bfe3f8ab56e1d11faf7db"
- eth1_data:
- deposit_root: "0xdce8bfad47155a9784cd497dcbc4dc3e96f262261246701c7792d45689a4e44b"
- deposit_count: "228"
- block_hash: "0x80caca4755897203f034dc16b609c1c2f4564cddad11ba383e79803dfc8b00e0"
- block_height: 229
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x5fb54637467f4b1e7fef955014bb48a73937a490562092a7bd1b99dac451fde4"
- deposit_root: "0xdce8bfad47155a9784cd497dcbc4dc3e96f262261246701c7792d45689a4e44b"
- deposit_count: 228
- execution_block_hash: "0x80caca4755897203f034dc16b609c1c2f4564cddad11ba383e79803dfc8b00e0"
- execution_block_height: 229
-- deposit_data:
- pubkey: "0xb110c3a2e0100ca6338d66f81c4fa6eb5cdf0aaaf839ea8e0a67645d958fba5f13bba8b66f7f9d069d571f25cdb8e47f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb8381b33e5ebec8010aec019e024668752bcebaa27b7ec938fe9e2a27d13f56c0e14c7fe115583ef230b5d0fb2d9a59c19f681fbc38f34b2aa9f63a58763f9804a01098031e66e2f7399482719c1729d07c25b852ca442dc620a69054de8e739"
- deposit_data_root: "0xbde6b47792e6754679c58260381c259bbd16097042b3d1c24404f6618b902e52"
- eth1_data:
- deposit_root: "0x9be8f309e2977f393617ff08549158f8185a24bf719001070d47e4fc19ab8806"
- deposit_count: "229"
- block_hash: "0xd9dda4f35c9c3edc515d03b9513be176d9420527d9ca62f2d7f484560d68985a"
- block_height: 230
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x5fb54637467f4b1e7fef955014bb48a73937a490562092a7bd1b99dac451fde4"
- - "0xbde6b47792e6754679c58260381c259bbd16097042b3d1c24404f6618b902e52"
- deposit_root: "0x9be8f309e2977f393617ff08549158f8185a24bf719001070d47e4fc19ab8806"
- deposit_count: 229
- execution_block_hash: "0xd9dda4f35c9c3edc515d03b9513be176d9420527d9ca62f2d7f484560d68985a"
- execution_block_height: 230
-- deposit_data:
- pubkey: "0x879db2b2da4652de6f12a5a9e5f8665daaffa2e4c25fc8609af45b428dd2a35244b66ac2a910dd76c0961e56c660cf59"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa14756fbc7bfaa2c851472eddf1c887d18c23fcbb3d2594e9dc085ed3236ffcd19529ea1905a48a9c666a61c8571958a17bd95397ba545381da98689290fc8e359aaa24397ed33279e739e23ce2eb0f6de4b8c3e5ce1f4d15ed433429300f380"
- deposit_data_root: "0xefc249e2faad07106c09333b4cbb73a021b753a9e13c8eb611b495829b22d501"
- eth1_data:
- deposit_root: "0x71fc589ae852643220368a3ded27a2aced2490b2405e2c7746a1ded7037cf662"
- deposit_count: "230"
- block_hash: "0x58025631a377c39ec1ff81899fc7574e3e918af2fe5b6cbd52afc269b69f27b4"
- block_height: 231
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x5fb54637467f4b1e7fef955014bb48a73937a490562092a7bd1b99dac451fde4"
- - "0x00515eda2b4aff0be9224f7d22352562c340830ab164489eee65b44431d623b1"
- deposit_root: "0x71fc589ae852643220368a3ded27a2aced2490b2405e2c7746a1ded7037cf662"
- deposit_count: 230
- execution_block_hash: "0x58025631a377c39ec1ff81899fc7574e3e918af2fe5b6cbd52afc269b69f27b4"
- execution_block_height: 231
-- deposit_data:
- pubkey: "0xa4cc78a560437549a4924c1d355e81a3467aaf9d7e7e1b4c7df6b39528345bb950c51c5316abe27f8618e5c7ca7dc5b7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae747862da82759f24af4f9103c1ed3f87f235a89fa77853050c607e11a10f4bff05de215e6c6aaaf5b9d6b539451d1003c8531ba3bd379edb89a0ee7b5219f011336fd8232d40a10238559263bcfe81da3f31fd29397f8e0b9cff013b9da2ba"
- deposit_data_root: "0x9e5b59deb9c620e5218e2064db2836bff8fd7cadcee035ee762f8db7c574cae5"
- eth1_data:
- deposit_root: "0x30d14127c55bfb5dbcd6adc091e29a155cea9657dcc190ce17d57875fb723556"
- deposit_count: "231"
- block_hash: "0x6b95be192a6c1967572f0e532c52335f7c273cdbe805373da35ab2ee78f7ddef"
- block_height: 232
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x5fb54637467f4b1e7fef955014bb48a73937a490562092a7bd1b99dac451fde4"
- - "0x00515eda2b4aff0be9224f7d22352562c340830ab164489eee65b44431d623b1"
- - "0x9e5b59deb9c620e5218e2064db2836bff8fd7cadcee035ee762f8db7c574cae5"
- deposit_root: "0x30d14127c55bfb5dbcd6adc091e29a155cea9657dcc190ce17d57875fb723556"
- deposit_count: 231
- execution_block_hash: "0x6b95be192a6c1967572f0e532c52335f7c273cdbe805373da35ab2ee78f7ddef"
- execution_block_height: 232
-- deposit_data:
- pubkey: "0xb0959a30fabda6f21ccfff1b9a4854fbd869e767b253c2f9bc08c4cbbaa3c24f37a7124dd8e67e2b0bdf4b052c2c9873"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb64885eaff19de38042492a996f157cca5fcf0194227e2d06b6aac66c8dd851806072acc35516a314384b5a11acedc2709ff085e2a236ee9b1a7c2247d229fb709c012daf6d0b3a8e1cfcaffd6f7d205d8feb2464cfa4d2c99c2b225d7b179cc"
- deposit_data_root: "0x7f90ce698e743d4711e8b9b3f6ab4461dc9f08f24f98e9a89319c3b0a526f37f"
- eth1_data:
- deposit_root: "0x53f5b42be17a65b15e69dedbb6555c8c16807de1e45febdf338ad2cca4172620"
- deposit_count: "232"
- block_hash: "0x7de5afd9e8b8fee40adb38fb6fae15c8bd6270fa7c2985eeab19ba6cba7f8084"
- block_height: 233
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- deposit_root: "0x53f5b42be17a65b15e69dedbb6555c8c16807de1e45febdf338ad2cca4172620"
- deposit_count: 232
- execution_block_hash: "0x7de5afd9e8b8fee40adb38fb6fae15c8bd6270fa7c2985eeab19ba6cba7f8084"
- execution_block_height: 233
-- deposit_data:
- pubkey: "0xa050c5180ee6cd9daef723caa6367112bc4b06636c3da59c3377e5e7b536942417a29cd5d1dad73011db4492032caff6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9208506ad4ad676f471b05fb33ab7d87b7b1fb7d4a8ef630c87407a568150aa88df852bde74fa50dbcaf3b9f81211c4c1759eed3952f470772d2dbe2c57ed35886530659cf3838ac540d9be98309549ff7121eb959d9f6deed0c25a63fb2a944"
- deposit_data_root: "0xba747d4e778466e602ce18816cff1e7c36f7a8c16531a624a3920df6d7650441"
- eth1_data:
- deposit_root: "0x29f2b6c06fc3cfa95c9960525011a1ec1ea97bcb65ece736ac0714e6699a308e"
- deposit_count: "233"
- block_hash: "0x046a47e1afbda13b44861a64c6013262ce2d2bbd3afc4c0e72f55a049acc2acc"
- block_height: 234
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0xba747d4e778466e602ce18816cff1e7c36f7a8c16531a624a3920df6d7650441"
- deposit_root: "0x29f2b6c06fc3cfa95c9960525011a1ec1ea97bcb65ece736ac0714e6699a308e"
- deposit_count: 233
- execution_block_hash: "0x046a47e1afbda13b44861a64c6013262ce2d2bbd3afc4c0e72f55a049acc2acc"
- execution_block_height: 234
-- deposit_data:
- pubkey: "0x96dddc7430e5f035c0c4d005ef950eea0b3cb8188fa1db85b947bfa69745d4cc0f8ca522b3880823154796fcfedd970b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x88df1ad86744a29bc86506d348e9e3f1f762a1a266ddb6a655a34cc45ea7897cb5467d267022e8e8c9f280ca2aecec081652fc8ac2a3de171c6e240687fe0564bbb5671e46ee029cb3ae63b900838793b89913966a4823499fcc2be104c8b177"
- deposit_data_root: "0x40f5c80a61e389915cd4d3e5f80ab4db55c85a2f4b2e57bf758f445538dcd272"
- eth1_data:
- deposit_root: "0xbfa95468dce6817d6393887438d0a90146367ced8533a2667f78b841e6c4a9d8"
- deposit_count: "234"
- block_hash: "0x28781e828d46a57b76c052c4b3ef44160cac67098a057a94faebc2f4e3540d74"
- block_height: 235
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0xaba4968db31e01e16a317caeaa2d3bc79f6efbe46926a9f8bf6576931d120e34"
- deposit_root: "0xbfa95468dce6817d6393887438d0a90146367ced8533a2667f78b841e6c4a9d8"
- deposit_count: 234
- execution_block_hash: "0x28781e828d46a57b76c052c4b3ef44160cac67098a057a94faebc2f4e3540d74"
- execution_block_height: 235
-- deposit_data:
- pubkey: "0xb1eef7970c10f8bb2a2d70f566657cc0209b198011ee3a4aaec9e7ddaf571fecc03db1042997b1554286e52ea95cce27"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa6274df964c6175a7c789c2244c212bebda8c658fc21f3cc9cc2aaa81294785c9f3985bdf9203709b4bf4b945d25e60e02cc06cc6d9a5a1b88785ab48488d820458986e9561c4e45ec3f5627573fb7e499ca98c5b9461448a1e8c78f77dbe104"
- deposit_data_root: "0x3f6f7e82534853f2c9d372660aa30baf5c68749d16f7e01a4a208b2bb735d102"
- eth1_data:
- deposit_root: "0x000d046fe7ebb4a367257dd30536ddce1ba46896bf412d3b4315ff19c62a17cf"
- deposit_count: "235"
- block_hash: "0xde2f782bde063ebce8d17a6ffb690e59eef61c57854fae148a85d05a1d062c45"
- block_height: 236
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0xaba4968db31e01e16a317caeaa2d3bc79f6efbe46926a9f8bf6576931d120e34"
- - "0x3f6f7e82534853f2c9d372660aa30baf5c68749d16f7e01a4a208b2bb735d102"
- deposit_root: "0x000d046fe7ebb4a367257dd30536ddce1ba46896bf412d3b4315ff19c62a17cf"
- deposit_count: 235
- execution_block_hash: "0xde2f782bde063ebce8d17a6ffb690e59eef61c57854fae148a85d05a1d062c45"
- execution_block_height: 236
-- deposit_data:
- pubkey: "0x85f65540cda46d23cf0ef948b5793b46a81771b4621ffb4b98c6dfa222208ffe3215bfdd436eed5ab124969704752e18"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x82b2f53b7b688fe92b7f3c0f991e2a8877c7da12806e596d2a36fe3d444a5e7fb2ab90b3989d2e0e7e3bd1af6086cc1a05281be5c581ac36e4a888f10460e6b1a5dc9f1de72580932df9a88fab6d0aa1646fd580dc54118bb08670569df173b0"
- deposit_data_root: "0x14f05f69965b40e8362e9ccedea325ba0686bbe2777dcfa7db391cf2176e9dd7"
- eth1_data:
- deposit_root: "0xfc113b844286b5723c0470bacc323281edcb6c74aa79e716649bce8785ac4bbc"
- deposit_count: "236"
- block_hash: "0xad091a6f9838ac87857dc11a206927e15fe263591c391d3aee5ddf3ab5cd19f0"
- block_height: 237
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0x0f7262bce5861c90229709693935a8f977f19c7ea94b4e8bd1f12985baecf8bf"
- deposit_root: "0xfc113b844286b5723c0470bacc323281edcb6c74aa79e716649bce8785ac4bbc"
- deposit_count: 236
- execution_block_hash: "0xad091a6f9838ac87857dc11a206927e15fe263591c391d3aee5ddf3ab5cd19f0"
- execution_block_height: 237
-- deposit_data:
- pubkey: "0x8d016fd1936593cb41b3e94c01ae213a770cfcc1e94e06bf90dd77dfb8721090cd17255aeb4b4da53bc2a70257d2bc5c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac1c8006b0200c3dd436b477bb2b280bb786f28790bf5da9fe4011ac3fadd996d6409642ec024fd238e46c1f3aa84a4716752ece5f09fe5f595a257c2eaa516375f9911255f91e938cf27ba02ee75abb5dcd22d2f25659d1212dc0bf5dc4b9d4"
- deposit_data_root: "0x9cfa02a46e3cc3e3f5aad20774b3f64b1cb9808321b3604b55b87e0868c9bb95"
- eth1_data:
- deposit_root: "0xa18458316c22446c517019010eb193e2277fde1eb5aad56e1e42df9c231b2e31"
- deposit_count: "237"
- block_hash: "0x691970c03abbade8133576a1253209024f4bc0139674b807e6204bc3e23793a2"
- block_height: 238
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0x0f7262bce5861c90229709693935a8f977f19c7ea94b4e8bd1f12985baecf8bf"
- - "0x9cfa02a46e3cc3e3f5aad20774b3f64b1cb9808321b3604b55b87e0868c9bb95"
- deposit_root: "0xa18458316c22446c517019010eb193e2277fde1eb5aad56e1e42df9c231b2e31"
- deposit_count: 237
- execution_block_hash: "0x691970c03abbade8133576a1253209024f4bc0139674b807e6204bc3e23793a2"
- execution_block_height: 238
-- deposit_data:
- pubkey: "0x953e4c8ef12a42ae5376ba23e06cfabf11c5e3fa773a98b487723225f1a2df60be50a54a7d5621bd85be25ddeb73af38"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x933a3fe4013d7669896335b2c866b160b31b1032bf990ffc350d94c747effc2c2e29f189f875246ef57dc6a0bbd143a200c2c48be3182476725fa3844a52f2a069ee18900e1c2b039d11bdfecb4ac068e3a1dd5c73b3d69db0f1b51b240c4f9e"
- deposit_data_root: "0xcd3264430f4abf9cd490f8f5712b274a53c4a32c3333624f39ec75bae8fabe98"
- eth1_data:
- deposit_root: "0x9e37fd0fc2fd4db56f06797479f91b79ddead19653a7aa07c766429cea8bf45d"
- deposit_count: "238"
- block_hash: "0x866e5ee2515e964c4254798b6ad79900f96759665c738b22e7ece20d6e286b50"
- block_height: 239
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0x0f7262bce5861c90229709693935a8f977f19c7ea94b4e8bd1f12985baecf8bf"
- - "0x9cf3b21fcd49adade498b802a1debdb7d2beec431c1aa4372eef06deec2bc955"
- deposit_root: "0x9e37fd0fc2fd4db56f06797479f91b79ddead19653a7aa07c766429cea8bf45d"
- deposit_count: 238
- execution_block_hash: "0x866e5ee2515e964c4254798b6ad79900f96759665c738b22e7ece20d6e286b50"
- execution_block_height: 239
-- deposit_data:
- pubkey: "0x90b3bf8ea91bae7c8d0e33974c65e1ce677328030cf63111d9ee5cbf6d300c72fc033c3c70d6afc21858fb9d2964875a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8462a3226ea043966c38f560258a0628da44dd4ca7daeaf82bbc64b77c21a5a34f2ded52a1ff0c012b6538e8e49d7801045b3705d346fcef4d6cbfdd694f784b4a557ebf6354c0e64554a31ccd8bb0be35c6aabbd8f0be2f02face2853211013"
- deposit_data_root: "0xaeb3b2cc80454c6e05ea47a0511b3a569f488624dca56695d4f984414a0ab986"
- eth1_data:
- deposit_root: "0x3148e7f341bb5610dcaf8209f84e28569aa86f787a4992e1c530fa35ec25851b"
- deposit_count: "239"
- block_hash: "0x1eadc81c31cc7f4b5c446bd88dcba2fa748773b9c6f847b1f81b254a9db5cd29"
- block_height: 240
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0xcfbab008757754f57710fd99c573283e4cbb498498c07b5f6d1a5c1102ee3bd5"
- - "0x0f7262bce5861c90229709693935a8f977f19c7ea94b4e8bd1f12985baecf8bf"
- - "0x9cf3b21fcd49adade498b802a1debdb7d2beec431c1aa4372eef06deec2bc955"
- - "0xaeb3b2cc80454c6e05ea47a0511b3a569f488624dca56695d4f984414a0ab986"
- deposit_root: "0x3148e7f341bb5610dcaf8209f84e28569aa86f787a4992e1c530fa35ec25851b"
- deposit_count: 239
- execution_block_hash: "0x1eadc81c31cc7f4b5c446bd88dcba2fa748773b9c6f847b1f81b254a9db5cd29"
- execution_block_height: 240
-- deposit_data:
- pubkey: "0x9412476b39b4c36ba977e5aa1bda710a773b48c95a6486d0201a978eaf58c51bce7c8b37e34f3bd61322c2f7caf53bc5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8c5224f300841a22377468fa8aa7a8c5d1ddb596c6ec85c7139724cf83c6b0707ec61f9a02a1aa185e553c260835f860f599d2c4afb79bd5506e8f077dee4cedaee36cd6ecf67dc5183110b1d00cdcc6b2fc98a61d41acaf5c207330bb535d6"
- deposit_data_root: "0x65bd202a5b6f083b0e57a1d1a1d99e2cd60a71071788a0ebf89723cf1f98430c"
- eth1_data:
- deposit_root: "0x8e9055eb4be6187b776047300d22266af54af5aa362e78bfe60b8815d30d06a3"
- deposit_count: "240"
- block_hash: "0x6f0584cc8761c8739652bd61a2e7c6f89e6a3e0c748b8555f6c900d566081bad"
- block_height: 241
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- deposit_root: "0x8e9055eb4be6187b776047300d22266af54af5aa362e78bfe60b8815d30d06a3"
- deposit_count: 240
- execution_block_hash: "0x6f0584cc8761c8739652bd61a2e7c6f89e6a3e0c748b8555f6c900d566081bad"
- execution_block_height: 241
-- deposit_data:
- pubkey: "0x8202a977e0d543f09f5f4b010fe308031db9c022058591b4ecc22205853f96fab8a906e31659cec3f20c23deced33fb0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x819cac5109e38a3e23be784a0803836ae5892a7ebf529d5b69ec3483f0765955d21453a7c8c9dbd48a67c6f6137484c9125a886a9562a70333f4a4643c2cf0a74899bd1b6f50501b25b73919a81b3a590e432af6d9d1649c484fd58d38a80446"
- deposit_data_root: "0x3c87bafbdd6e4bd6fd9c9b911859197b0d4e77215d1f0b4a76cb53dfd9a0bee3"
- eth1_data:
- deposit_root: "0xfecc08150b61a8fd00bef193f76e8b08a35b1e230a8fbe5fe8386821042dc30e"
- deposit_count: "241"
- block_hash: "0xffd46f6cca04a453afaaab6759ce73a0883c43146bd59559c0e3547b03104bee"
- block_height: 242
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x3c87bafbdd6e4bd6fd9c9b911859197b0d4e77215d1f0b4a76cb53dfd9a0bee3"
- deposit_root: "0xfecc08150b61a8fd00bef193f76e8b08a35b1e230a8fbe5fe8386821042dc30e"
- deposit_count: 241
- execution_block_hash: "0xffd46f6cca04a453afaaab6759ce73a0883c43146bd59559c0e3547b03104bee"
- execution_block_height: 242
-- deposit_data:
- pubkey: "0xa6071c891f8c353b0ed693c039c54f8ceaef1862c23904ecfbd88b3ca9180a52d7c4ce95bb9673e98ba6ac93a2d5b462"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8492293596dd1459367cc4ed401f6b3c2dab0c4c58045157a782a359483588f7fc072c8fab68311956fcecca8dca20ad0208bf6106be93330bb2c8f188924827efbf388ed1196f0a36c57751ba9241f9e888287f28c08f6f466f14ae39b7a471"
- deposit_data_root: "0xfaf043c9b1a28720d15e0878bf714c21ff2f25732db766df36c30f2294edc890"
- eth1_data:
- deposit_root: "0x25d55cb11a780617ff862a96f6a5d28b03553d6ad721b3fd9b2a969516092366"
- deposit_count: "242"
- block_hash: "0xdc1ba0aeca3dc68376239c9dc4291a18b77e5a6e073c2ce216f78cf916b1bfc7"
- block_height: 243
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x6ca839b6db690b690cfcecf7cc14423bb1fd7b32d682e21d2e2ac03494a37935"
- deposit_root: "0x25d55cb11a780617ff862a96f6a5d28b03553d6ad721b3fd9b2a969516092366"
- deposit_count: 242
- execution_block_hash: "0xdc1ba0aeca3dc68376239c9dc4291a18b77e5a6e073c2ce216f78cf916b1bfc7"
- execution_block_height: 243
-- deposit_data:
- pubkey: "0xb722d39c1d7d9c5ec39961f903efbf7bfd5faa1a3af41749874b52d9a6ecf554b022beebfd42b5d4bc00ecdc726a1c69"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8cd8f6b02f810e9b408185e8d25e0739f91a10d1091f0af98641b558598e8cb0f447f07dcaa702c40ffd3fd50e2fcb1e13fd81b3e6b5541d2c73facd4b1ee023578075d09356b8428e94cf257ebc725b94c13cf383ca033adb26f458477806f9"
- deposit_data_root: "0x084781b3e9bd75b87361a1f8441b80da9923d7c8668720ad8e5755482ef29649"
- eth1_data:
- deposit_root: "0x5e30bf9c714431e60981eb475a64bf5f497cb20bee164b4c2c77fcf330d5cf1f"
- deposit_count: "243"
- block_hash: "0x650a223ced62d289d54524b7d13cf38a72a713b7d76a950da2127bb06567174f"
- block_height: 244
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x6ca839b6db690b690cfcecf7cc14423bb1fd7b32d682e21d2e2ac03494a37935"
- - "0x084781b3e9bd75b87361a1f8441b80da9923d7c8668720ad8e5755482ef29649"
- deposit_root: "0x5e30bf9c714431e60981eb475a64bf5f497cb20bee164b4c2c77fcf330d5cf1f"
- deposit_count: 243
- execution_block_hash: "0x650a223ced62d289d54524b7d13cf38a72a713b7d76a950da2127bb06567174f"
- execution_block_height: 244
-- deposit_data:
- pubkey: "0x98bed18337602301002525627e99e62911e6bc491e2c2bbfa2eef2f4bcf173eb60e493b74e95c3b5256555f20535694e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa30352b10445dccc53569ef6a776814dd6bd35bca75d4960a97108c2ef05e896fc1218863e091e349eafa964df4252cc04aad236601220b9a047fdd8b61cc370514e05c427f83215b19beef3672008bf441e58bc9e848f68617e580d8a3851c3"
- deposit_data_root: "0x714f0a4796ecb56128e81e1fd76733314b4f8d9876254793390161eed47581ad"
- eth1_data:
- deposit_root: "0x58b247bf9a29620b5b3c182f0a579da72ad4126fe2ba57300f6fd58f32aba0e2"
- deposit_count: "244"
- block_hash: "0x84da630cce06cc7ab9def7b0e4ccb64c267d8d2be50f211f991cf5e4e4ce6e5f"
- block_height: 245
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0xa46deb2a2056ceaf788d88266b62aab355e7755244c7ea45646a731284b588b7"
- deposit_root: "0x58b247bf9a29620b5b3c182f0a579da72ad4126fe2ba57300f6fd58f32aba0e2"
- deposit_count: 244
- execution_block_hash: "0x84da630cce06cc7ab9def7b0e4ccb64c267d8d2be50f211f991cf5e4e4ce6e5f"
- execution_block_height: 245
-- deposit_data:
- pubkey: "0xb499f66668919d5f1d82e55171c5961e78aaa70e0fab3a2ccf14aa402379ac66e05d542060e550d8a1d03796ce703a3c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb52925ffbd2205903de239cc9abdfba52c6940f45cfc9f8c0d6998c074022c32fefd229d464724fb372a157a0c74bc87015c05f9b331b96b9354a9060a31cb1a92ceab4e91a689e5aa4156c8dbec1785a319cd74d370a3bf86aa56a431033d66"
- deposit_data_root: "0xdab69f68d68d19729a7255e07d59760c7b6ba098132c4d5d5a1c87af8e5ec222"
- eth1_data:
- deposit_root: "0xf1bd510bc2186b7e3cf6246ba45b1a8be2ec957093caa0f825d8d2ee898b11f7"
- deposit_count: "245"
- block_hash: "0x958e63436b683ab4d02c33db4495fcd0dfd5a72b445e3274b9efc508d4d797c7"
- block_height: 246
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0xa46deb2a2056ceaf788d88266b62aab355e7755244c7ea45646a731284b588b7"
- - "0xdab69f68d68d19729a7255e07d59760c7b6ba098132c4d5d5a1c87af8e5ec222"
- deposit_root: "0xf1bd510bc2186b7e3cf6246ba45b1a8be2ec957093caa0f825d8d2ee898b11f7"
- deposit_count: 245
- execution_block_hash: "0x958e63436b683ab4d02c33db4495fcd0dfd5a72b445e3274b9efc508d4d797c7"
- execution_block_height: 246
-- deposit_data:
- pubkey: "0x92c237d7fb491bcf70aa4e50e71b305bcf71bf5a438b0e08f03fc4f74d5c3c9b8c823049e314d15f8266179b1a90841d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa2bb7c6a1ee2ec8368539cccfb5b2a8588e5e479fda223410cd15341dd5c865dd22695a2a0ef27757b2545adf353df0e0b51f9c9c12b19a7fd0e22cacc81c28a0fad805cd19feb808be5ca4867eabee207e2f38e089b6097f66809b04cd41797"
- deposit_data_root: "0x1cc0cbc5cf5550036124427fca2b43440d4c574e10da612c1b6c583a6febe147"
- eth1_data:
- deposit_root: "0x4ba339c19953b83d57a0600cc2a325b4ab96d46eecbd4b6b483d42b6c3035122"
- deposit_count: "246"
- block_hash: "0x4194ca1e0c55ccaa492a55535bebacaa185efcc8ab9f5fb8ea60ffd90461d3c2"
- block_height: 247
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0xa46deb2a2056ceaf788d88266b62aab355e7755244c7ea45646a731284b588b7"
- - "0xfe1c7788bf7f661ff91503ec1352ef2ba4d8ad3653fe69110da96218c90b32ab"
- deposit_root: "0x4ba339c19953b83d57a0600cc2a325b4ab96d46eecbd4b6b483d42b6c3035122"
- deposit_count: 246
- execution_block_hash: "0x4194ca1e0c55ccaa492a55535bebacaa185efcc8ab9f5fb8ea60ffd90461d3c2"
- execution_block_height: 247
-- deposit_data:
- pubkey: "0xa1f2eb8596281b7e85285bcee8a4156140e069c6f50c02a0dd3b0f40ed62b8e15e7b9c40f6755496e13a94d91faaa194"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3b72e3ec51a30a080e36fb0ad1c350a6f4df753de841d2626581c2f3573b3ceab177708cfe9a64d3c6d243a26df1e6700b014c3f09636bd0911addd3db4be6b8893568c0e1e92b88badec7a7c86e0c0921cb07ad48e3c7f6c27a6c6cb1ea8af"
- deposit_data_root: "0x571c10a7c40e7c4a5f15db4ff249f1e1b90fc1ed392d6dc2c359de9c887950f9"
- eth1_data:
- deposit_root: "0xc8f68085a6d6b9ea9ab9389235e301c66d605c6a1648e659e512d10a340f6dad"
- deposit_count: "247"
- block_hash: "0x86ca50c675d6f26df298aec00b900a9693d04a765494714b8a2c6da02d310338"
- block_height: 248
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0xa46deb2a2056ceaf788d88266b62aab355e7755244c7ea45646a731284b588b7"
- - "0xfe1c7788bf7f661ff91503ec1352ef2ba4d8ad3653fe69110da96218c90b32ab"
- - "0x571c10a7c40e7c4a5f15db4ff249f1e1b90fc1ed392d6dc2c359de9c887950f9"
- deposit_root: "0xc8f68085a6d6b9ea9ab9389235e301c66d605c6a1648e659e512d10a340f6dad"
- deposit_count: 247
- execution_block_hash: "0x86ca50c675d6f26df298aec00b900a9693d04a765494714b8a2c6da02d310338"
- execution_block_height: 248
-- deposit_data:
- pubkey: "0x8f4d945fafc936414122945190a1983192259705205fa3e92b72443a93183eb140ad527d4b1449507a18cd64764c89b8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89f9fb93f365aa814e9939d47d12e479a941b124428a3ea45ff751b336fbfc4e918be34e1f8e1006f011a1182f3fa4530ffd887727627586a9d090ba05c5f035a69fe7da7f3747d9018eff61f281ebcef266db93e508b22273173d7e59337234"
- deposit_data_root: "0xd752ab6ab4c095111b65b97cef47817f4ce89cf1025672ca33053c1c5cc8e856"
- eth1_data:
- deposit_root: "0x9888c051a7c8320f413b98a66f0f4d86d2161c649550a898f3a05d547072e2ef"
- deposit_count: "248"
- block_hash: "0xab019baaf509e52a456129c7b9628360234c5c99d73059d5f3a6f1c320affeec"
- block_height: 249
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- deposit_root: "0x9888c051a7c8320f413b98a66f0f4d86d2161c649550a898f3a05d547072e2ef"
- deposit_count: 248
- execution_block_hash: "0xab019baaf509e52a456129c7b9628360234c5c99d73059d5f3a6f1c320affeec"
- execution_block_height: 249
-- deposit_data:
- pubkey: "0x98a8e7af1994e3d8f383dc4ee6d32a01077694ec93ecfd7ffbc5cd9448938a6c6d35cbbbe8e01a49fa4782f389757b06"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96b654ae3c1bbef1c62c4dbb5ff4a174dd66d699660b3fddb0393dc3f8b675611a8f7c92c9d64a55c70c59c81ec61d9c0630b6609ee9185b075931251f5bfc63be9b5741cd1bff31d08bf63232ea95a3652ddf2012932c617741afb9417c1797"
- deposit_data_root: "0x1b3ff046f35984553c7bc5e78b4ef9633fbd4955e81438f836224ad1a35537fd"
- eth1_data:
- deposit_root: "0xa1477aaa9d366844c18a57e9c0f5281dbc35d8a27c7178e36a78943f2af1f4ce"
- deposit_count: "249"
- block_hash: "0xefe08745ea4a98e988389f4896dec09001efcd92fde1b157958b2a7b5bea1e1f"
- block_height: 250
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0x1b3ff046f35984553c7bc5e78b4ef9633fbd4955e81438f836224ad1a35537fd"
- deposit_root: "0xa1477aaa9d366844c18a57e9c0f5281dbc35d8a27c7178e36a78943f2af1f4ce"
- deposit_count: 249
- execution_block_hash: "0xefe08745ea4a98e988389f4896dec09001efcd92fde1b157958b2a7b5bea1e1f"
- execution_block_height: 250
-- deposit_data:
- pubkey: "0xa7c051843950c482ea373ca3aa30e523911ccfe061c681b16fb8a35ec6e4ff0ada5a25fb2ae70433b18913652cc3c181"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x98eebdf73162c70581f7325614bb7110c6cba9351ca1dd4e275557a9cf71ac8fcd64071791780806cee2e37c18f98e2313e8adfec420bfbf20b35a79cfad2eddcd664a557b3b566437f567f1a5a03deeb48b0c0ce31ba57531f594ca8317fe2f"
- deposit_data_root: "0x357d15b4cce193ddfc397cdd46ab0a749f8a579ab81cd19f1100e041b1147c57"
- eth1_data:
- deposit_root: "0x11c2be42ec7670fab1675225953d5079ce0571d96393b911904526f6be98cf25"
- deposit_count: "250"
- block_hash: "0x65b114ab411f03138a6610b8edf979ba983e536afb438e62fb80ffffbc3cf124"
- block_height: 251
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0xcf504f082f480bc2de32cc4c299b0fd96b1ed6919af3b090f0a9f3f3ecc10430"
- deposit_root: "0x11c2be42ec7670fab1675225953d5079ce0571d96393b911904526f6be98cf25"
- deposit_count: 250
- execution_block_hash: "0x65b114ab411f03138a6610b8edf979ba983e536afb438e62fb80ffffbc3cf124"
- execution_block_height: 251
-- deposit_data:
- pubkey: "0x8f14a40f502a87214891c922345fc2abc6795c28d72f9deb7ebffd7b805888222f7b1d479db1142ed013902987394cad"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85f4239f73421ff5d28f31481729632e20bf4ed4b3ea0a91961dec198922dc1be61be0623b85365dd6db9cec094dad9217683da190c4be92b5d1bb00491314472e3a412f13d651c4c98f054219e621538c9465cd42fd2851950e0ac9a42e62b0"
- deposit_data_root: "0x5be2cc49961bb2f24b8e89e5e9bacc33efb9cb9f9a455e1bb91fff7bc5b6656a"
- eth1_data:
- deposit_root: "0x0df7d0d38d74a5cb89be95258e7c60ce0b9200342553536b064f33ea923255df"
- deposit_count: "251"
- block_hash: "0xb243d9ace275e844a2335d262010f8b3cf19d045bc930d89bb6e6ec738865cb6"
- block_height: 252
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0xcf504f082f480bc2de32cc4c299b0fd96b1ed6919af3b090f0a9f3f3ecc10430"
- - "0x5be2cc49961bb2f24b8e89e5e9bacc33efb9cb9f9a455e1bb91fff7bc5b6656a"
- deposit_root: "0x0df7d0d38d74a5cb89be95258e7c60ce0b9200342553536b064f33ea923255df"
- deposit_count: 251
- execution_block_hash: "0xb243d9ace275e844a2335d262010f8b3cf19d045bc930d89bb6e6ec738865cb6"
- execution_block_height: 252
-- deposit_data:
- pubkey: "0x8e486d8c9ca07b6c4dc1181161ab52508b70980e9af31c97286b55be3df3701d73891bf0aecc6eb7d2e028572bb5c25a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa87d84736b8a674718e17bcabfd512e8a6ccb52eaf11776e2aaec8cb0d9bf91fa59b46b3c21a0023443a9911ba1f6e9f192e18b88ea8cc96362a537f98bac4de9883e4a8b46ce99f8c5407b4fa748a9bd6c438ea076b8eff66a34c43243f1030"
- deposit_data_root: "0x94423ecf41a112308585b194e910a68273a90cb12434e82d0cd936a3b92309c9"
- eth1_data:
- deposit_root: "0xabdddf0fbff2f71cace266b85d33a05b0621daae752c693fe9027725d863a1b8"
- deposit_count: "252"
- block_hash: "0x8c746ea8ee851c0ce8552221531374c1a73ca48d07c2da85ad95328836cde732"
- block_height: 253
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0x5ba7e2c0ce36932281840d77f2cff6b2fc9b10b24953346e039e8d0576ba01d8"
- deposit_root: "0xabdddf0fbff2f71cace266b85d33a05b0621daae752c693fe9027725d863a1b8"
- deposit_count: 252
- execution_block_hash: "0x8c746ea8ee851c0ce8552221531374c1a73ca48d07c2da85ad95328836cde732"
- execution_block_height: 253
-- deposit_data:
- pubkey: "0x91402ee72dd351a735017f11da3176ae5fce3e92369972d0eee22a45d1cc2badd77f627c4a0a9d9c480d65464442599d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa1eb19f9f0c9fe4962b82a001fe8c99c3ecf7b2133202c655275af9ba4581d7715abafb9d9835340a14c52ee7a1a449c0ba1d35ad7bb6ab37fe54d05c644a577c5b86ef3e036c46c0c4ccb3829205e0b4c717d2392abf2ac92e770747643c26a"
- deposit_data_root: "0x00c52950b4b8050d147aeca91703761b297e5d91ab496ac1161f1fef79f7528e"
- eth1_data:
- deposit_root: "0x39b19f70b06e4cdaa2c3e1c87ef0b8039022ac99b00d68deca929ae4f7ba95f6"
- deposit_count: "253"
- block_hash: "0xc0d6735edb092ab85379457c91496c754307a70cab6e50494f858ee371eb649b"
- block_height: 254
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0x5ba7e2c0ce36932281840d77f2cff6b2fc9b10b24953346e039e8d0576ba01d8"
- - "0x00c52950b4b8050d147aeca91703761b297e5d91ab496ac1161f1fef79f7528e"
- deposit_root: "0x39b19f70b06e4cdaa2c3e1c87ef0b8039022ac99b00d68deca929ae4f7ba95f6"
- deposit_count: 253
- execution_block_hash: "0xc0d6735edb092ab85379457c91496c754307a70cab6e50494f858ee371eb649b"
- execution_block_height: 254
-- deposit_data:
- pubkey: "0xaa5b90007d36de7c57235756d39aac060ee48e8a910f0a0c815e71414a0d53e7b0659242079253fdeb32ad18ab90beb9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85e04b0dd29327c3b6509673add484f5236e2fc68e0d3411f7ac5070b5d171b8800cf366a8cc632d9e9b9ea49bad527f0105dc4600d55dff610464d15d70c1103218824db85b2c13a898279e777f843cb3c32afea2ab7dd46494c942fc857da2"
- deposit_data_root: "0xeec4762f004c245237202597a1172ba2594a24318eab15dc61519909d761035d"
- eth1_data:
- deposit_root: "0xcb2db903b62421b1add0e3747dff29b0eaa2046f7e8aea0c22777804c1931533"
- deposit_count: "254"
- block_hash: "0xb3df67d8050a51998dde8c9c9a2ebb92c608018a2c32b1bb4835769bc7303160"
- block_height: 255
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0x5ba7e2c0ce36932281840d77f2cff6b2fc9b10b24953346e039e8d0576ba01d8"
- - "0xc9bd7dd686e17ced16ded792dbb1565f93d9d01b2e551b237d8674891756d761"
- deposit_root: "0xcb2db903b62421b1add0e3747dff29b0eaa2046f7e8aea0c22777804c1931533"
- deposit_count: 254
- execution_block_hash: "0xb3df67d8050a51998dde8c9c9a2ebb92c608018a2c32b1bb4835769bc7303160"
- execution_block_height: 255
-- deposit_data:
- pubkey: "0x851faec0a50c3df9918d1ab44fe7f63f8105d671d8fb83f3a59d291e6d4dc86cf47a6e9402973bfbd7db535b3dc4350b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xabf53104df47484b8c876216dec49ae4c6805c0c7c866fb3794f0699db316ef4e60ed588cd3a2865217db953a640fa61118325f454eb4d2768f2372bc8325b5a979a722faee2bd818d9bf944c89abbefc3328441ecdcbcab2a9f0830bad57a3b"
- deposit_data_root: "0x3fe14e2e6126bae3261e24ff9119ea5b74664a19426da0d091193ae3bb736dd5"
- eth1_data:
- deposit_root: "0xad9929ce3da3cccb228d8f69211d8493147a6df93daed02e410bcbdecbeaca60"
- deposit_count: "255"
- block_hash: "0xff6935719c772b51352c991341ff30606fee102d3dfd07859a2930212e75800e"
- block_height: 256
- snapshot:
- finalized:
- - "0x5424209b0511223b880af7362d8fe72bc0f268f4aa37dbcced5b872a30a1265e"
- - "0xbbe623353e1418ef9492c6e1ca72e9a73bc4d28b00d17bae94476c70ae774043"
- - "0x8b839672af192e30144c2c46a2d14842b4620d58405e9094689262016f3b1ff7"
- - "0x15e5ab79d2e91316abac7981530e445f4c70332f1628d1883a21d17a699c1b4e"
- - "0x151d5a637c3241cca69bf3658d39f77db74646866a4dc1a1d762fbe89eb8f459"
- - "0x5ba7e2c0ce36932281840d77f2cff6b2fc9b10b24953346e039e8d0576ba01d8"
- - "0xc9bd7dd686e17ced16ded792dbb1565f93d9d01b2e551b237d8674891756d761"
- - "0x3fe14e2e6126bae3261e24ff9119ea5b74664a19426da0d091193ae3bb736dd5"
- deposit_root: "0xad9929ce3da3cccb228d8f69211d8493147a6df93daed02e410bcbdecbeaca60"
- deposit_count: 255
- execution_block_hash: "0xff6935719c772b51352c991341ff30606fee102d3dfd07859a2930212e75800e"
- execution_block_height: 256
-- deposit_data:
- pubkey: "0x933dc2f8d407d4f85a1d54953ac47a89c19808eca0d38b0ec85b376ce17c3ef1edebb518a4dce8e976155cb6561a849f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9694a8b0268e018870eb146f9d2a4dda7b9c341b4c82a73d950101d534f167fc0c8d902f37f9589c056108b1b6a3d41a0d815100b4db1232c4393e5f7bdbb23925aa043d68f95ba7b4edd2d4e58465ec63aadc831f99eb06278e067fc68325c5"
- deposit_data_root: "0xb71c9023acf8ceebefff85ec63ced2d0a535e3af465941895e0679b0fc692f0a"
- eth1_data:
- deposit_root: "0xd49c9ff7d98a8d5cdab9ddf57c558dc9d203d282d7ec7faa5c7d11aae81b790f"
- deposit_count: "256"
- block_hash: "0x1fe7203f9539f6116aabb762433e3ec9692de44bdb1342b1b1653afc271b04b5"
- block_height: 257
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- deposit_root: "0xd49c9ff7d98a8d5cdab9ddf57c558dc9d203d282d7ec7faa5c7d11aae81b790f"
- deposit_count: 256
- execution_block_hash: "0x1fe7203f9539f6116aabb762433e3ec9692de44bdb1342b1b1653afc271b04b5"
- execution_block_height: 257
-- deposit_data:
- pubkey: "0x8f7069f51912347df8b721903bd9340ff49e9d436239ea0f4f176e360c4a91aede7657037ae00dcb08a9d7abe9b48d5a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x833313916a5da51c5ba85ecb314c687384faf62db7872fd000ca32a0ee7f4778bb2e5f7a5f4139aac884a7f4a0a1c40808a766bd7acb02c5ee4d6ead05a622b6d20a818649ed08c41afe600e1710f1b5532aee603618c828ee50cc62dc51f964"
- deposit_data_root: "0xb7292e597a4316db41b1ee81280941feb78554bd77861d9b4e4ee85ceb83f536"
- eth1_data:
- deposit_root: "0xd254aeef26718bb674401e75886471ce4a088120fab90318c6e55d063aa04a3c"
- deposit_count: "257"
- block_hash: "0x1df4e3eafb6484a050b5168586d648e4191d90ecdf846800fd0b41ddde11edbc"
- block_height: 258
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xb7292e597a4316db41b1ee81280941feb78554bd77861d9b4e4ee85ceb83f536"
- deposit_root: "0xd254aeef26718bb674401e75886471ce4a088120fab90318c6e55d063aa04a3c"
- deposit_count: 257
- execution_block_hash: "0x1df4e3eafb6484a050b5168586d648e4191d90ecdf846800fd0b41ddde11edbc"
- execution_block_height: 258
-- deposit_data:
- pubkey: "0xb876db47bf1d1868b3a39cdba4171adde47eae91b3631dcb5c59d28cb100ecda604a446ffcb000448c462d72526ebdf1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7302e880887ee702f55cc3fbfa2a8ec3b422317eda123538723588e7119d6111d80457a3805912bd4f07f16cb71c32c09a2bf0ade7ca11fa2303136bcd493c8b8a7c7fff3b94be38684b019cb515d4759574323015b9d53d0c92ce374a5311d"
- deposit_data_root: "0x40f31b70761cdda3e491f945fcfada69d0d985503e705ff9e0db0fde1d58c7fc"
- eth1_data:
- deposit_root: "0xd5c029480bf22b310991b6964481ff2e3e156e9d9a39556026ef809cf282d77c"
- deposit_count: "258"
- block_hash: "0xbc87b56c9955290b90555dfdfcfe36d95abf388b957b8b004ab7aa8682a48c26"
- block_height: 259
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x33caef79ba14b442d517fa8bc4c617b1a5c595ab103f2baff90a65a7f03c8564"
- deposit_root: "0xd5c029480bf22b310991b6964481ff2e3e156e9d9a39556026ef809cf282d77c"
- deposit_count: 258
- execution_block_hash: "0xbc87b56c9955290b90555dfdfcfe36d95abf388b957b8b004ab7aa8682a48c26"
- execution_block_height: 259
-- deposit_data:
- pubkey: "0x9666598b3eaade229b7b255866d279009ac0b42dc55cbec207f3842d51501e2fcd318ce7d2fc40a766382703c8a0ef00"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x960b98ed5f4aec48beaf813e61048411a345de0d5b99593d5017f7a18651567b7d3038e4665fd186c868a4b4b8da865f175ef0158fba21bdf10c0890cd1fa32dc3105da9f295925b96d090516bace0c6e9a168206a21a11b30f8fefce22fbb5d"
- deposit_data_root: "0xc0a4d26a15ce052fbb2873df1b178b41192e4cdeb45895acf94f55d5d58636c9"
- eth1_data:
- deposit_root: "0xda795c832687a92b18a304a4a68190b021082edac866a12e283b6cc4c3eee27e"
- deposit_count: "259"
- block_hash: "0x2ec63ba8ef1e86b8428bb223e6aaed2e3193f59a65de1ddaaeb3cbd96653530d"
- block_height: 260
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x33caef79ba14b442d517fa8bc4c617b1a5c595ab103f2baff90a65a7f03c8564"
- - "0xc0a4d26a15ce052fbb2873df1b178b41192e4cdeb45895acf94f55d5d58636c9"
- deposit_root: "0xda795c832687a92b18a304a4a68190b021082edac866a12e283b6cc4c3eee27e"
- deposit_count: 259
- execution_block_hash: "0x2ec63ba8ef1e86b8428bb223e6aaed2e3193f59a65de1ddaaeb3cbd96653530d"
- execution_block_height: 260
-- deposit_data:
- pubkey: "0xb2b4c1b1777970826b6683ceed5b72da7bec1f6f7cdfae6a599ae0d0d6d912098678327ee31fe383fc2b95bfed48bfce"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa0495982b6c281a33c67883658f6c32a94268ede93853331bae3e492f71ac4514f05b0e89ffddb1e1a8dff4b83dc807219c69ac11d5a2515c845023c566dca7dbcde3ca08855dae961242680efe3f84de27fd04ee3d8c580bacd625ce1618f7a"
- deposit_data_root: "0x6944628944cbac12207257df3a7d14936c9bc8f267eec1e24d18543b00b9c413"
- eth1_data:
- deposit_root: "0x7db45a47b3b9ef4cf211c695fe5682e6e79078b72f4b758d7db497ef4f3c7abd"
- deposit_count: "260"
- block_hash: "0x2d162a08fa97029565b3f57c18af38429a5a4a3f7deefde7b843f481fb7fd0a5"
- block_height: 261
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xe4b758cad7a082639814a7aae047e94921d416986d98b6dfcbc234966bc973ef"
- deposit_root: "0x7db45a47b3b9ef4cf211c695fe5682e6e79078b72f4b758d7db497ef4f3c7abd"
- deposit_count: 260
- execution_block_hash: "0x2d162a08fa97029565b3f57c18af38429a5a4a3f7deefde7b843f481fb7fd0a5"
- execution_block_height: 261
-- deposit_data:
- pubkey: "0x91cecc34498496a68dc7630a6184b1cd7b977772a94d7d704c64284cdc14aa3f4d7c6eadb3bf62eda1a43f2f8d547a2d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa2e8b32322fbe08e071a3100c7f55efa12fedb60e61d10adf35599ad6dff551e7cb22f16882c76e5a5fc03cfbb7cac2916770030f9049ab5075e8371745bfeb58d944bb0cfd9ec44e29e57ab441f96fad3b71a42ed1a3f7a8f13107a5e09ca8f"
- deposit_data_root: "0x709db664502b7eb538adc5890972def651e1e2c0f4fed2b14b473022f3676bf5"
- eth1_data:
- deposit_root: "0x36baa65b71d95dada8a8da1cb67eb6656fa616b6645db7870b07060afdfcbdb4"
- deposit_count: "261"
- block_hash: "0x771faf677259330b1949d0d57781f6ae7745117adb1f2c748b42ba20ec3c599d"
- block_height: 262
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xe4b758cad7a082639814a7aae047e94921d416986d98b6dfcbc234966bc973ef"
- - "0x709db664502b7eb538adc5890972def651e1e2c0f4fed2b14b473022f3676bf5"
- deposit_root: "0x36baa65b71d95dada8a8da1cb67eb6656fa616b6645db7870b07060afdfcbdb4"
- deposit_count: 261
- execution_block_hash: "0x771faf677259330b1949d0d57781f6ae7745117adb1f2c748b42ba20ec3c599d"
- execution_block_height: 262
-- deposit_data:
- pubkey: "0x89dc8480e9d48c7e5a39c3ced17e65170f56f86a96e4bb131e88c3d6eda3daa65265df5445e0ce52090cf34d7fd1116e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x945d9ac700cadcbad052484acb2eb9702915bbcfa44222866ece07891edd00d8ce873f17704412e338f39893af82ce54115bd1e184b11cdfa51937164a1d3576f359c14a903ef669a016cc5398e9e5c6af03730ea0534a737f8457c237141f36"
- deposit_data_root: "0x70c4d026dc4ce6566e02ddb3085517df6d5c742910fe7a36500d76e7badf82b3"
- eth1_data:
- deposit_root: "0x05fb7d7e57be47dd87666d6198c4e197ae9fd0922fb4100535592ac7e0900bab"
- deposit_count: "262"
- block_hash: "0x132a1b9db503b80713fc5a34717cd51069fa6f145340ffee8c0b283c8c2e0606"
- block_height: 263
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xe4b758cad7a082639814a7aae047e94921d416986d98b6dfcbc234966bc973ef"
- - "0x6cf83a85c4c666e9efb82ff97d8cf8fd2d6f4442b0c6c7e029dcf8ae80c981df"
- deposit_root: "0x05fb7d7e57be47dd87666d6198c4e197ae9fd0922fb4100535592ac7e0900bab"
- deposit_count: 262
- execution_block_hash: "0x132a1b9db503b80713fc5a34717cd51069fa6f145340ffee8c0b283c8c2e0606"
- execution_block_height: 263
-- deposit_data:
- pubkey: "0x8219db7b86441850836ae4e27a030e8378e594e5f1d7ee08dac7bc054653d178e6949476887c83a20a213b2bf39e16f7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c53a5ea1061f892c20cf93c1b97c42250908b3e299700090713f36a45421c619b06570d18e2b96168e71dcaafb820bd17331ed302480153fb48a685d679c829ea12e7c93ee5999aa0812ba19da8b8c60899b980401fb17312ae9db58046ae20"
- deposit_data_root: "0x819ccfe405e7220a1d9c053a8676a88332980aef5215f5076f1a3f5033235532"
- eth1_data:
- deposit_root: "0xcca4cb084ab65bb8629ae4dcc8b2fcbe56db2cae8859e206c4da24a4014d139a"
- deposit_count: "263"
- block_hash: "0x27aa5166ec5f9d13e6be7009abc9114701756eb96a5a9110ca40a3e593b0fc27"
- block_height: 264
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xe4b758cad7a082639814a7aae047e94921d416986d98b6dfcbc234966bc973ef"
- - "0x6cf83a85c4c666e9efb82ff97d8cf8fd2d6f4442b0c6c7e029dcf8ae80c981df"
- - "0x819ccfe405e7220a1d9c053a8676a88332980aef5215f5076f1a3f5033235532"
- deposit_root: "0xcca4cb084ab65bb8629ae4dcc8b2fcbe56db2cae8859e206c4da24a4014d139a"
- deposit_count: 263
- execution_block_hash: "0x27aa5166ec5f9d13e6be7009abc9114701756eb96a5a9110ca40a3e593b0fc27"
- execution_block_height: 264
-- deposit_data:
- pubkey: "0xb9ea48794c02725e69d9f6435382b31b3e975de5ead999a09e13746e0ae5a63115af3a3043cd71ebc94c9b051b5b595e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8964f0aaa92e1cd2a2e0df07b02766725afe98d100e863fa5364feaaec05c4159eb6efd5d9409d47ab037a5fdc41ba5300ddd8f1626f81b384a6a3793a70a5bcc8c4361c19540bf923cf6f2f5058832f8c188fbff56be3141d24fb9abd829561"
- deposit_data_root: "0xca07d9e3d7bab36f22f9362f73c6302b8c8fc9c41ee856fb2c0fde28702d6672"
- eth1_data:
- deposit_root: "0xf051452baf67b48585468b8af81fea65efe163d4752bc57fe502dedaebc9595a"
- deposit_count: "264"
- block_hash: "0x7c9c165d2d0ad76293cb31edc3195d7de80f5cff9d5ba5bbd9bf0f384dff028e"
- block_height: 265
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- deposit_root: "0xf051452baf67b48585468b8af81fea65efe163d4752bc57fe502dedaebc9595a"
- deposit_count: 264
- execution_block_hash: "0x7c9c165d2d0ad76293cb31edc3195d7de80f5cff9d5ba5bbd9bf0f384dff028e"
- execution_block_height: 265
-- deposit_data:
- pubkey: "0xadae379b50e15e5f80810abfc544eb28e26301438cfaf8a8a5569f9bfd76c4e653d0da710bb5d34687d47669f6999257"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa56c12741c2b28f868708a31c9cde178d724fc2da24acc2538f54068937fb2d7e76cd4bef53818af4ab71908f3feeb0d17527506fed49643fab936ee040061ec66bd43ae9dc1e414d9ff03f7392a9d26daadcc789117c2e66596c2235fd98f8b"
- deposit_data_root: "0x6449a8db47ed59b97b28d2cdc174f12232041fc3231f388d48cc5ed141ccd2a7"
- eth1_data:
- deposit_root: "0xe077d704ae5725c0d46ff39053c1ae7e15b456333bf520cefdef620ac331c134"
- deposit_count: "265"
- block_hash: "0xeb71722b0fe110a64ecccdb9ecba95d7fb7b7c832086cd5bc67e25196be9232f"
- block_height: 266
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0x6449a8db47ed59b97b28d2cdc174f12232041fc3231f388d48cc5ed141ccd2a7"
- deposit_root: "0xe077d704ae5725c0d46ff39053c1ae7e15b456333bf520cefdef620ac331c134"
- deposit_count: 265
- execution_block_hash: "0xeb71722b0fe110a64ecccdb9ecba95d7fb7b7c832086cd5bc67e25196be9232f"
- execution_block_height: 266
-- deposit_data:
- pubkey: "0xb451fc2c4236ca2393853980019f5da0e5f7d93df90bab1ae34ddb583d0ce3cdece25f23bc1736e065a1f2af1ee2bd34"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93bcb192ee34cf2cb34310583c6ed82b12baa1388f5e85d3e74ef7c9dff413f69f00eff132a686eb786f33bd918fc8870ee0337447202ff82024b20ac35bcd931c34869d33f9e594da910891722146b65e3858be3f6142d1ddafcff50f159b95"
- deposit_data_root: "0xf6e781e7f4285fb05464464c41580de16dcd370ae346a5462bb5791d38808f89"
- eth1_data:
- deposit_root: "0x91a3cef7fd152d3aab06e1f156a428c7f3b19697a7bf32bcbf076c37b4379230"
- deposit_count: "266"
- block_hash: "0xb87c760b0c73bb51052f5a77555e27d38ec417e21af5851664153cc71ea1b7f2"
- block_height: 267
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0x48170ce125065a69a3020c11a7f1aa34ecfaf772a3a13be6737bcba5157f2553"
- deposit_root: "0x91a3cef7fd152d3aab06e1f156a428c7f3b19697a7bf32bcbf076c37b4379230"
- deposit_count: 266
- execution_block_hash: "0xb87c760b0c73bb51052f5a77555e27d38ec417e21af5851664153cc71ea1b7f2"
- execution_block_height: 267
-- deposit_data:
- pubkey: "0xb8c6b853d7f3766c881f4eb0c9986b800188b9f9ab40a492d49e64e8c1e98cefc27ecfe225ff9d5781c0193bca2f77e3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xab4f31e234441c6eb8fc1f41628ff056226de0b0b3016bb48e2d02eb41ae39f7774bf6c6bf7f8e5088504d962e2045fb0acae329fb2e80eea51f332b76cb2f1d08339b6c230c6ca47b4837f5ebed0c087b51c0c29154e5c4e0b587a0a304cb03"
- deposit_data_root: "0x1e826f811c943eec59894f7b90ff11deefdcc1449ee3dd9186a01e14e07f6c15"
- eth1_data:
- deposit_root: "0x480831312704cf1ebb18ce99d3d5d14aee83c31dee4a7768dc84b8f44a8f815e"
- deposit_count: "267"
- block_hash: "0xf65f73d8ffe1df07acfa02b5297f43c4652c159a3cfcdd3bb9f3f1bac7d7ce98"
- block_height: 268
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0x48170ce125065a69a3020c11a7f1aa34ecfaf772a3a13be6737bcba5157f2553"
- - "0x1e826f811c943eec59894f7b90ff11deefdcc1449ee3dd9186a01e14e07f6c15"
- deposit_root: "0x480831312704cf1ebb18ce99d3d5d14aee83c31dee4a7768dc84b8f44a8f815e"
- deposit_count: 267
- execution_block_hash: "0xf65f73d8ffe1df07acfa02b5297f43c4652c159a3cfcdd3bb9f3f1bac7d7ce98"
- execution_block_height: 268
-- deposit_data:
- pubkey: "0x923b10adafbd70ac83cfde90a85bd38e5e919348285b311e020721bc96adc9e9b7e45f8052d1b3ef97301947cbc6d3e9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb8dbe590fe70f90ffcb0e4d7156fb9a763e0a5812a18fb900eb224dbfc1006ea53fe2995beeb8c68de87186093102daa072044fa2c7599d0ddff864035c094435b4bd4159157b8c5c2bb68b713313c33daed3f059742bf74bf9ee140996a8030"
- deposit_data_root: "0xb230a394c34aa022260b632113aac600d6adda8c634e99c4a0ca133d01ae895c"
- eth1_data:
- deposit_root: "0xa94dd2d608ad39920b3d4d36983bcf3fcbf847bfba0fd6efb0f9392538d9508b"
- deposit_count: "268"
- block_hash: "0xf02da506c532e1e1fd10587045c93575c15526820e5ceacab2119c401979948d"
- block_height: 269
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0xe199368557ff186641e9a7d5cb05acac6d482b97df62a1011f0b9fd5c03f5734"
- deposit_root: "0xa94dd2d608ad39920b3d4d36983bcf3fcbf847bfba0fd6efb0f9392538d9508b"
- deposit_count: 268
- execution_block_hash: "0xf02da506c532e1e1fd10587045c93575c15526820e5ceacab2119c401979948d"
- execution_block_height: 269
-- deposit_data:
- pubkey: "0x8860a33d75543d49ad04bdcffdfdf7fcef7228076d4e8150d80c3cda14651963544a683355e256166d995dd3f6b4ad35"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x986c60f5e748e02284435fdd37c2a72a5247e0784ebc99677490e9095f2665b1685a16d7dd48261c922897faa2273fc6030db1b871f208a56e20602b337ef10921b8a3164b128fbfef2566fc0db86c27f392eaddf4745aba700d9a69af3d0ad7"
- deposit_data_root: "0x1c37b6d2caaa5c7bb785e5cf0f444edc230bf9836cf1c8a27f1a0c5665c50c37"
- eth1_data:
- deposit_root: "0xd021c86513c1fd866c766cdedb99464a5c9a2abcb4f6a5563ccd8178cc778b0d"
- deposit_count: "269"
- block_hash: "0x27cdcf3f09175210019c23eac0ac9309bfd56a6654eb9523900ae387500fd99e"
- block_height: 270
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0xe199368557ff186641e9a7d5cb05acac6d482b97df62a1011f0b9fd5c03f5734"
- - "0x1c37b6d2caaa5c7bb785e5cf0f444edc230bf9836cf1c8a27f1a0c5665c50c37"
- deposit_root: "0xd021c86513c1fd866c766cdedb99464a5c9a2abcb4f6a5563ccd8178cc778b0d"
- deposit_count: 269
- execution_block_hash: "0x27cdcf3f09175210019c23eac0ac9309bfd56a6654eb9523900ae387500fd99e"
- execution_block_height: 270
-- deposit_data:
- pubkey: "0x805de41e2e03f52993f465c0cba3886c40488c0ebe7fbbbe65f016e5e6ff971efe2968e09b0d62263cde4c70f6cf8540"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x830ed2435dc71a80676f51b674be560ecd4d7f0b7d2328ccfee8bc207f4480fac75aa62926c2665a00cfdf2a9b5f18cf00313aa3eab4cb83f3224417cbe42a1591ba0260afb464481391930abfb206db57230757da96e033d25ad57ca15cefb3"
- deposit_data_root: "0xd00dd9ec8defab31ac1699c60512ddb92c0b66fdb722eeb8f889ce3f9a36e198"
- eth1_data:
- deposit_root: "0xf20d2b6626fa9a2412b80217d55810beaa23b9d42c0a386624fc99f04622d1d6"
- deposit_count: "270"
- block_hash: "0x0f3d50198252da6bcdd9fa7a62accd5b21e2c3236ed4434a6e30ecfa9a31c349"
- block_height: 271
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0xe199368557ff186641e9a7d5cb05acac6d482b97df62a1011f0b9fd5c03f5734"
- - "0xc68746b2b174136c95a60d0312e6eb45b1d289447eeec15e7126fcdf8a85da9e"
- deposit_root: "0xf20d2b6626fa9a2412b80217d55810beaa23b9d42c0a386624fc99f04622d1d6"
- deposit_count: 270
- execution_block_hash: "0x0f3d50198252da6bcdd9fa7a62accd5b21e2c3236ed4434a6e30ecfa9a31c349"
- execution_block_height: 271
-- deposit_data:
- pubkey: "0xa367b7c50ce66726561d5f4190607e9c1d3feab41f624b9ecfadb6f52e1b300ef98e8913e8fffb2b65cdbb889ff5fb6b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x918fe57e516de9e415db3fd4f1a78843da0f6f76b71ab4ec9d8f91bea748fcab31a90e25b22d69e98cf83f43502cf4ac08a0cec4a3e7aa21d5b876b9728b079c0640becf699ff07b023431d6f872561c7e35f86e15d3abe0c9b2bbdc452fdad0"
- deposit_data_root: "0xa29deb39e17dec8af0ce7d25156ecabd1ebae33d3076a29b4ea8d8b127335672"
- eth1_data:
- deposit_root: "0xe92c7ae8c37c06c234eed3d64804cec30984b01ae852511077750a8e5ce8e9e2"
- deposit_count: "271"
- block_hash: "0x4a4ae702e70fa102e90e05e95bc8163f7cee4224b9a8ade2c97c4ad04d2f104c"
- block_height: 272
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xa175806ecd8f45f5b8a87219a9c345e9e612bcdfc850bf0b51c2b6a60813d7e3"
- - "0xe199368557ff186641e9a7d5cb05acac6d482b97df62a1011f0b9fd5c03f5734"
- - "0xc68746b2b174136c95a60d0312e6eb45b1d289447eeec15e7126fcdf8a85da9e"
- - "0xa29deb39e17dec8af0ce7d25156ecabd1ebae33d3076a29b4ea8d8b127335672"
- deposit_root: "0xe92c7ae8c37c06c234eed3d64804cec30984b01ae852511077750a8e5ce8e9e2"
- deposit_count: 271
- execution_block_hash: "0x4a4ae702e70fa102e90e05e95bc8163f7cee4224b9a8ade2c97c4ad04d2f104c"
- execution_block_height: 272
-- deposit_data:
- pubkey: "0xaf379c89e4f4bec6b942c9e2d8fa6ccd2ec13cf421d80c987af53d5217c932483c4ed17cd1a9c9d7174e2546ab16ebb4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa49410f5cc90cc268e78c2afa27c8cf129f4da16397953dc383e3eafb1e797faa9bb0e9649502829df2c2cf2b7cd715d0d8be34d1e8cc2706933290ce42bdd8bc1a1bcbab9defcdbb0e85309ca92a7c7c0df00b1ba01dd13e74834ff17788d0b"
- deposit_data_root: "0x677f04382b7df90d9e30533f0fea1e1193e6a71e0f3d2fc6621957b406a2d39e"
- eth1_data:
- deposit_root: "0x734e5eceb4244b23ed80e4a9d91f6830c403c9e37a27c8501368ddc1b9bc1b25"
- deposit_count: "272"
- block_hash: "0x615eaf0c08bbd375884ea9de1f7261253ab51971c2b1d8407fa63982d4d6feae"
- block_height: 273
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- deposit_root: "0x734e5eceb4244b23ed80e4a9d91f6830c403c9e37a27c8501368ddc1b9bc1b25"
- deposit_count: 272
- execution_block_hash: "0x615eaf0c08bbd375884ea9de1f7261253ab51971c2b1d8407fa63982d4d6feae"
- execution_block_height: 273
-- deposit_data:
- pubkey: "0xb6c5b136625178a485ee2eba1ddadc84b55e42c0e5a7ebfc8e5e2db651baf3c0a7cff6fb8e94dfccb1ca0a0d48b7496f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8dba1b2ce9ddb0488fbd27b8f0e760844e5242b4a70d188a0fe5e7602161ca591f09b3ddeae404795f02df26930d00e80ef42e30d4d09fd5632c9dde165519725ff4442dc3eb9d86056a5afbe401a5568674ee6f7dbc7f1ef9d5e7e8ec6d4a74"
- deposit_data_root: "0x984f88c7b8523c5a9c9268002fa51558131645074051f28869233e59bba2bb64"
- eth1_data:
- deposit_root: "0x0b1169b7908d522037d597df82f0e4821a3f141ae329527275e975e1f06b44f3"
- deposit_count: "273"
- block_hash: "0x9a12613dd49a16c089530e40aa1c8f06f77c852479a90a28387d068d5884ba45"
- block_height: 274
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0x984f88c7b8523c5a9c9268002fa51558131645074051f28869233e59bba2bb64"
- deposit_root: "0x0b1169b7908d522037d597df82f0e4821a3f141ae329527275e975e1f06b44f3"
- deposit_count: 273
- execution_block_hash: "0x9a12613dd49a16c089530e40aa1c8f06f77c852479a90a28387d068d5884ba45"
- execution_block_height: 274
-- deposit_data:
- pubkey: "0xac210cfd8d8d9547120ba0a786a93318beb172471e9711b764db71376898bc28037160396e32be311a1823e585e8f524"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9917a489a4d766025fe21104187d687a191ab135e68f44282e597ab9bee1197d4cd037d59051d36197be3854c2429964138486367635adc03360ac053251a06df519237d2fa0b72b8540feeb5bb5e6180f137bbbcdc250aa191a62fb9294f33e"
- deposit_data_root: "0x6d90c6f3641efb6dce19f2efb93fc24439111dbbcc6cdcdf60a2f4c0019af2dd"
- eth1_data:
- deposit_root: "0x9604fd80f34acd50e4b641e866a440bfd4697939c358ac3bc91bf25352a8057a"
- deposit_count: "274"
- block_hash: "0x439db7c4143f986853029b0ce493c55804bf4a38e08c9f2bbc19ff22b1a185e5"
- block_height: 275
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xafc140dc42b75f6f96d56352af93e6d41d56ab68fe4b90981a6ef2aca4a11b4f"
- deposit_root: "0x9604fd80f34acd50e4b641e866a440bfd4697939c358ac3bc91bf25352a8057a"
- deposit_count: 274
- execution_block_hash: "0x439db7c4143f986853029b0ce493c55804bf4a38e08c9f2bbc19ff22b1a185e5"
- execution_block_height: 275
-- deposit_data:
- pubkey: "0x8771e8df435244648533c638f725d292deaa9ef3e098ccce30255f860156f9101aea2ab56199d5a8cd2042af7ea57e33"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x813560e954b791856c97ff6bf3bc645f75d58e88a405d804957362b901ff360f625839be68c9c612da31cac55f41b7d009dd46e7847de8ff5c78594ac44dc2a5c91ff1330e1f44e3c8398e44a0021e5508afc438bc3f2d88fc9fee40b6171386"
- deposit_data_root: "0x6cab9ec916767574e8a430f9d5eba9d27c0a90902ca458bb94ce0f50c6d6ebf0"
- eth1_data:
- deposit_root: "0xd55236a200b36a4aa5e760c3135bd62b4ac05255ee43580b5d5bf16322ac92b2"
- deposit_count: "275"
- block_hash: "0xd095a783f5860659c4fbd8e22b2bbb739d9fe8b974da64831e52c4839bc2f8b8"
- block_height: 276
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xafc140dc42b75f6f96d56352af93e6d41d56ab68fe4b90981a6ef2aca4a11b4f"
- - "0x6cab9ec916767574e8a430f9d5eba9d27c0a90902ca458bb94ce0f50c6d6ebf0"
- deposit_root: "0xd55236a200b36a4aa5e760c3135bd62b4ac05255ee43580b5d5bf16322ac92b2"
- deposit_count: 275
- execution_block_hash: "0xd095a783f5860659c4fbd8e22b2bbb739d9fe8b974da64831e52c4839bc2f8b8"
- execution_block_height: 276
-- deposit_data:
- pubkey: "0xa3c94a3ec9d463a4929513b426cc91887c7e09fd038314ada8e5e7a8ce204a7a20247319f91c0746de0e241550aef4bb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x99b1d155a15927ce6ca47e70b7ded4d286509f134e2c58a85595e7bedf9eb7d27408cf7638df5cc64969ee5a502644d20486af547bf3518937fe1253259f9d0bb2e509b1c6b1b0f8510950345522a82927de2d8191aab3bb4bb0ec1cb94a03f9"
- deposit_data_root: "0xe237d745c0911cc07e84746c0e519b09b08b97b06b530a9ddc4e887d53bf8b81"
- eth1_data:
- deposit_root: "0x5df671c2350221cbf76630d9cf5d5ba52a568e846e24a45f2631a577507011c1"
- deposit_count: "276"
- block_hash: "0xa5113dab93745a4a0e8e65ef5f666109d653178cc86cf033bbdedffe8de244a0"
- block_height: 277
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xd2f50982286bcc1b17c7402df3f3c8e5ccb7ac8516cae8783aa22d003b1838ce"
- deposit_root: "0x5df671c2350221cbf76630d9cf5d5ba52a568e846e24a45f2631a577507011c1"
- deposit_count: 276
- execution_block_hash: "0xa5113dab93745a4a0e8e65ef5f666109d653178cc86cf033bbdedffe8de244a0"
- execution_block_height: 277
-- deposit_data:
- pubkey: "0xa647de716dfe7d82e529344bf832f2ac603d7067a515ebb7148fe69cc4330c1c12d3caaf16d6df3a3483574d49a296dd"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93620e7602b38582df7080d48213f86a395186fe16197167e99e8c555d0a7a2f8b818bf2cc884608059212ae1090fc21135cdd2285e1a96271dc200bae45d68bc30a6053a68c5387557827685bdc3717b1754a22473b9193b2ed08fe12936e4b"
- deposit_data_root: "0x454bf4695084db5d52745a0c0fcf55d46b16d40fd982c40df3e64ca30abf2eff"
- eth1_data:
- deposit_root: "0x2cb46c5f7addaa0c11d5f2a617f116ee53714804de67624d12aaed20ee03e07d"
- deposit_count: "277"
- block_hash: "0xc16cb9437067b34e14b0db82231c2466967cf85459de2d923b92fc39afedbcb0"
- block_height: 278
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xd2f50982286bcc1b17c7402df3f3c8e5ccb7ac8516cae8783aa22d003b1838ce"
- - "0x454bf4695084db5d52745a0c0fcf55d46b16d40fd982c40df3e64ca30abf2eff"
- deposit_root: "0x2cb46c5f7addaa0c11d5f2a617f116ee53714804de67624d12aaed20ee03e07d"
- deposit_count: 277
- execution_block_hash: "0xc16cb9437067b34e14b0db82231c2466967cf85459de2d923b92fc39afedbcb0"
- execution_block_height: 278
-- deposit_data:
- pubkey: "0x97dae6c47e2b695734163c4e12ff709e7d63879fda8192ca26a35501dce45fd8748b5ed04519e829d61e5e7a3e379dfd"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8419026bb209d08a2db619c23985a483e4a42af20e10715893985ee289a000c990c4f33693780a3640ded33dd21fd2200781677f590164d65528a4f1c047443e619930b7a3ab3be00e7a6c0df70fa505da34862fb9a539a531c237792dc0ab79"
- deposit_data_root: "0xdd6f4ed981c18b7b2e7bb2f4e0688708fd069d405b0b087315ff02eefe2984c5"
- eth1_data:
- deposit_root: "0x3ecdd5c5beb8def23312392aae577b8950c66c902af8bf99de73b96656be003b"
- deposit_count: "278"
- block_hash: "0x8bd6fb2e4d0410f8eae7eedcffbc2f9ae0e0a31b9dc9d6de94b0bf7668691eb1"
- block_height: 279
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xd2f50982286bcc1b17c7402df3f3c8e5ccb7ac8516cae8783aa22d003b1838ce"
- - "0xd795029ab5b69d8e37a9ff4be1b60af4cf9805d75bb3e2b61fa05fb9decb98d4"
- deposit_root: "0x3ecdd5c5beb8def23312392aae577b8950c66c902af8bf99de73b96656be003b"
- deposit_count: 278
- execution_block_hash: "0x8bd6fb2e4d0410f8eae7eedcffbc2f9ae0e0a31b9dc9d6de94b0bf7668691eb1"
- execution_block_height: 279
-- deposit_data:
- pubkey: "0x897c752e1ed45c3ab22146fe595fd08175a828c69e1e3243e6e1e644792b0bc979924123c0cca7dea405b074e214880e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xafd9fdd20324edeeb6283b1a45e7178f6419260b0581cd71ea46b392d6ddb5ee3b7dcef33bf889f401e6b78c5d3766370f25200d87ace14ebc81992a6c0c7552bced661cf33b1ec285d89ebe94c7159e0f0d78543e1d1362789e54729bce5834"
- deposit_data_root: "0xbefaf00ec4412758aba9bbd73a7a8f4c56dec0523ca462ae5dc6c1f553100248"
- eth1_data:
- deposit_root: "0xa3e6322b128ba1eb9cab42f9e9de032e5ef934e3395e3c070c2e3877a9262640"
- deposit_count: "279"
- block_hash: "0x00ed7d8bb7cdd6256ac0d7f1ad7b9e34302d9e119e9db4078fbb19b8d3541685"
- block_height: 280
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xd2f50982286bcc1b17c7402df3f3c8e5ccb7ac8516cae8783aa22d003b1838ce"
- - "0xd795029ab5b69d8e37a9ff4be1b60af4cf9805d75bb3e2b61fa05fb9decb98d4"
- - "0xbefaf00ec4412758aba9bbd73a7a8f4c56dec0523ca462ae5dc6c1f553100248"
- deposit_root: "0xa3e6322b128ba1eb9cab42f9e9de032e5ef934e3395e3c070c2e3877a9262640"
- deposit_count: 279
- execution_block_hash: "0x00ed7d8bb7cdd6256ac0d7f1ad7b9e34302d9e119e9db4078fbb19b8d3541685"
- execution_block_height: 280
-- deposit_data:
- pubkey: "0x90e6673aa3258396ea9b5e5d4c53b076fc93d4f408008343e44f5d4e49e408942c764d454b435be080ed8e4328ddcf1f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xad7a438ba41385b1078bae963e814a92e922a83efebe6aca14ce1a0a1754ec7d882211ef71ef55bcaa4d87e75b20f9b611837e28ab711d1874863a151a5ebfee310b649ce58aeee5fe7809dbf813a0d1e5786cbcf9286fbb6d649939c781339c"
- deposit_data_root: "0xdc9c1d97e917f6e25ae888d726fca078b28921a5bb9f1ea669ba53b18caaa5c0"
- eth1_data:
- deposit_root: "0x7b3c923bef540d0db79619c5bfb8a2abf74f57c23a1cfd4dec6410feacb6b943"
- deposit_count: "280"
- block_hash: "0x0067d9ff3bd86de63d54114d41770e5b0cb7c8c5120b19530eab3d3bdfe79836"
- block_height: 281
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- deposit_root: "0x7b3c923bef540d0db79619c5bfb8a2abf74f57c23a1cfd4dec6410feacb6b943"
- deposit_count: 280
- execution_block_hash: "0x0067d9ff3bd86de63d54114d41770e5b0cb7c8c5120b19530eab3d3bdfe79836"
- execution_block_height: 281
-- deposit_data:
- pubkey: "0xa7f7669994d4503c6390a44e7b64103861f78d60283580e19d0898948ed55a0b16b6c8fcd86e14341fd9a5974e4eda5d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x837a5a91adc8bd9b06a5b116769ad796b673f5230741af2e8ce61d59c7f3eb80b1a896f36af0f7b1d72c612cdf51eec7154395d1cebf833e0329d4ebc118a0708b2d2429d13324157ee8056eba25c5e0ff6a3b4212c19e437666151de56a0e46"
- deposit_data_root: "0xc760b2ad57feef344b258de4d1ecb020fc392a45187f5aab606d97a308a63ebd"
- eth1_data:
- deposit_root: "0xa06cf7368dcd4b336a8769c80e7ade8ef0d8900f5abe104cececdef2a22f73dc"
- deposit_count: "281"
- block_hash: "0xd67c87e9d0958db9609fdb7e4a3246578abbbc9e36517a6c224196c1d726207d"
- block_height: 282
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0xc760b2ad57feef344b258de4d1ecb020fc392a45187f5aab606d97a308a63ebd"
- deposit_root: "0xa06cf7368dcd4b336a8769c80e7ade8ef0d8900f5abe104cececdef2a22f73dc"
- deposit_count: 281
- execution_block_hash: "0xd67c87e9d0958db9609fdb7e4a3246578abbbc9e36517a6c224196c1d726207d"
- execution_block_height: 282
-- deposit_data:
- pubkey: "0xb8ad8a758c02b9a1769a5f883a41eee5a516165cd2ae19749d60ff634f1175940ea569244830265b2f59b2aeaa434478"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb55d9ffeab85b135b7e21166db97d4defbea12b1beebc795a694062cfcdc5de3db44e1810539c8b22bbc2a930b4cc0fe102a8b233c45b958a7db52b28bcbe9192e191b967ba76f9fce60d4bd30ebfcf0c156b298ed99cbf1df359da8f9b089c7"
- deposit_data_root: "0xd224e7399aef34aebab912dd931e8029d849a75e46d52d3e7af7ef795089aba5"
- eth1_data:
- deposit_root: "0x41e107ab1e7255ca23c4f66b6afaa812e789a822664683cf158c481a32a62e10"
- deposit_count: "282"
- block_hash: "0x8e6819b492671a514f3da060880e5379b0b42de61df7089d479d883c2f25e4a6"
- block_height: 283
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0x5f703e4b8197692608370e14e3f2f2ae87e4817939d05d095009486de7ebe0ed"
- deposit_root: "0x41e107ab1e7255ca23c4f66b6afaa812e789a822664683cf158c481a32a62e10"
- deposit_count: 282
- execution_block_hash: "0x8e6819b492671a514f3da060880e5379b0b42de61df7089d479d883c2f25e4a6"
- execution_block_height: 283
-- deposit_data:
- pubkey: "0x95037a05a0a6a90acadb5cc2156117378faa1c1eb79cacf3b91835e268d7855960e638dc34bbc192cc6b8ca6b942be04"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96ffe4fec99f4e61dfeddeb4e0ce1db5d3f2ec1c7b5608a27dbea3a684705aadd979a4c48ed703904b1afdab4ec410e717a8d892b8c881d95fc0cea3df434f4a2a736b75e12cbfa65354d1452f1c1494679b0c2f82e0278bac0e727cca54ae5f"
- deposit_data_root: "0xa84635d4c80545e945a05b992bf4e018466bf90ce77efbc6c4afcd86e7c40480"
- eth1_data:
- deposit_root: "0xf45ea7c111196d94551e75f4827dc54da7b27159b61f0157001cc501e449ab11"
- deposit_count: "283"
- block_hash: "0x208b9d89c955086f385701344c89f0f7f36d8a12f8126654ff46fffac19738cb"
- block_height: 284
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0x5f703e4b8197692608370e14e3f2f2ae87e4817939d05d095009486de7ebe0ed"
- - "0xa84635d4c80545e945a05b992bf4e018466bf90ce77efbc6c4afcd86e7c40480"
- deposit_root: "0xf45ea7c111196d94551e75f4827dc54da7b27159b61f0157001cc501e449ab11"
- deposit_count: 283
- execution_block_hash: "0x208b9d89c955086f385701344c89f0f7f36d8a12f8126654ff46fffac19738cb"
- execution_block_height: 284
-- deposit_data:
- pubkey: "0xab152bc78eada258d68785ad491422f64ffece7e462ac59ba92ca919f6e2ecb3c3707b34d6159a967b4dd7590c4321e0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa62cef8f23182080da9f5566785c5f614bb68b7ed2480551ff248ba0ff398af1125437bb1703598a3726757e6aa242f30c73e7f1833a07e3944fa370bb35a17bca08a6a65988a8cca0cc544489bebc4f7089ac288694483aa3f0d14913d11bde"
- deposit_data_root: "0x7a9db3084c5390172ef580652bd82ec524081fa698d216f8680acddf3598b5a9"
- eth1_data:
- deposit_root: "0xb14450ae34030b8e3b7357bcd9b403267d507c15e5006ee4df1d5fa5dcf8dafc"
- deposit_count: "284"
- block_hash: "0x705a548444db8857275b1e4daff4e049715ba5c3cd31e9c9ea40d7aa767f76cb"
- block_height: 285
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0xd2b6e86410a770e340ffb7de6ee5cf863a85940c79573f83f25f86aea119f640"
- deposit_root: "0xb14450ae34030b8e3b7357bcd9b403267d507c15e5006ee4df1d5fa5dcf8dafc"
- deposit_count: 284
- execution_block_hash: "0x705a548444db8857275b1e4daff4e049715ba5c3cd31e9c9ea40d7aa767f76cb"
- execution_block_height: 285
-- deposit_data:
- pubkey: "0x847230d7b775a10cb13cbe8b80b7d2e5e613043af2913729fde2404485cb4dcff11fbb08487c860125c9d4828686818e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa97dcbec769d32f79ab1ffb179002460cf80afd587cd7f19c6f8761af07a8819cd82a64d82917e208dede5fdda3392e008516c97578f0fa1f56201f010b00e3a7dcde2d8ce22cd02d24663540889087ba0f7011af978035591f41a26b00d4455"
- deposit_data_root: "0x71aa303f97c1545130a878320efceac5ac755201d7435beb0a6a5bbbd9f76432"
- eth1_data:
- deposit_root: "0x89e2e3db69c005b9af9f2f52537e98e4d99b15078574bfbb0542230f161d7bf4"
- deposit_count: "285"
- block_hash: "0x70ce0316c6eb65c0b81f178a0f234dd62a88b9f1f751b77974158bc26cd78152"
- block_height: 286
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0xd2b6e86410a770e340ffb7de6ee5cf863a85940c79573f83f25f86aea119f640"
- - "0x71aa303f97c1545130a878320efceac5ac755201d7435beb0a6a5bbbd9f76432"
- deposit_root: "0x89e2e3db69c005b9af9f2f52537e98e4d99b15078574bfbb0542230f161d7bf4"
- deposit_count: 285
- execution_block_hash: "0x70ce0316c6eb65c0b81f178a0f234dd62a88b9f1f751b77974158bc26cd78152"
- execution_block_height: 286
-- deposit_data:
- pubkey: "0x811f122742c9f58ceff4b9b75ef59d8a8b5553313c027e18a21f417206d72b66d225c30d9f9f5dbb648d68e537a95cd8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d64c45dec8fd9624e5a673b4be330985f42fb04e32ddcb14f8463e92c8534e8c9dc7ce6dd324d9e46d08535d67024bd0f3d2eb8afe1c571969f7054eee365376b6ef65dd2d79aeaf4b9e065fab99a08f54f7aa4eaa608f542be51155c97c943"
- deposit_data_root: "0x8c2d9422f7f6da9f58a22bf2958c28614b38612f6599a09dbbfb3b6b05a2c9de"
- eth1_data:
- deposit_root: "0x39ed089d07634871eab8445a2e27720f969a75194f7e739b28632596d51afd4c"
- deposit_count: "286"
- block_hash: "0x0ad81ac5b5624db6ae564e1e55a039c9ff07abbfad8541f36b1499a38e34ff01"
- block_height: 287
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0xd2b6e86410a770e340ffb7de6ee5cf863a85940c79573f83f25f86aea119f640"
- - "0xd8e36fc1ec59065a6d776496630ecf9de9417b10f4fba2873ba760bf445dfe59"
- deposit_root: "0x39ed089d07634871eab8445a2e27720f969a75194f7e739b28632596d51afd4c"
- deposit_count: 286
- execution_block_hash: "0x0ad81ac5b5624db6ae564e1e55a039c9ff07abbfad8541f36b1499a38e34ff01"
- execution_block_height: 287
-- deposit_data:
- pubkey: "0x875b740b7de5cd6db43823c3dabb3e0652b132a2b0c7593383420f31c452c3e772885f083932eee347c94ff2411367fe"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x870a4c9e1e8bad7573ca85cf96c85fcee530e3918c0fd5231945d44b93668b09dfe394fee7df5f34641f9a2100d7f8c100758148ba94822633c24ce5c8abfa4922f9dc83ec659a471cb791d2c8f50bb63879125bb240da3f3ddf073034022974"
- deposit_data_root: "0x95dae1cb1d3ceb2b954761d7e3994dfcf890f0af2d932c8ae16a0305f4172e7c"
- eth1_data:
- deposit_root: "0x091a9d9c1cb63e60b98a645f4b92cb819e69c9d72a1a22bbf4ce0aab06fd8f4e"
- deposit_count: "287"
- block_hash: "0x0a2ee6676a0013c27224c31e35877a9f41c87bfcd451d50a496f62094cdddf59"
- block_height: 288
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x004f564bddfe12ca7aeb4708f48538e1d5fe4b3ad2c8b08be819236aa2c67ec2"
- - "0xb96037b213deff69adf6fc2ef3ff23ef01b2a19f085f6cdc4395ef55d13f1eb3"
- - "0xd2b6e86410a770e340ffb7de6ee5cf863a85940c79573f83f25f86aea119f640"
- - "0xd8e36fc1ec59065a6d776496630ecf9de9417b10f4fba2873ba760bf445dfe59"
- - "0x95dae1cb1d3ceb2b954761d7e3994dfcf890f0af2d932c8ae16a0305f4172e7c"
- deposit_root: "0x091a9d9c1cb63e60b98a645f4b92cb819e69c9d72a1a22bbf4ce0aab06fd8f4e"
- deposit_count: 287
- execution_block_hash: "0x0a2ee6676a0013c27224c31e35877a9f41c87bfcd451d50a496f62094cdddf59"
- execution_block_height: 288
-- deposit_data:
- pubkey: "0xacbfea617a3cbc5df59da38133fee49b25a4a27aee878184acbd8cad6c72a2ffd5cf31812e4ded11d7a73c6c7a9a7cb8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb261f12cd1af634ddd037f62c1930120938421469681c3e4ad8abed21ba550a1b60d91fec994000e28bd880da3de709c0af2408c80150b438cf318791dc169983785152bed21b01117f698ee6853bf23948501289e4ccd63d7d87b70d82484a2"
- deposit_data_root: "0xc5c4f40555719fb6d08ab90de29f01a80adde2ede7f5a2338ec0ae24980480a6"
- eth1_data:
- deposit_root: "0x313a8e2fec006ca89b4e20c0945b2f7ba336aed9695b4b03bc06608712cde390"
- deposit_count: "288"
- block_hash: "0x7895648d903ca4cfc86649eb22f8d1c758141f8d3aa89f938f2f25016481435e"
- block_height: 289
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- deposit_root: "0x313a8e2fec006ca89b4e20c0945b2f7ba336aed9695b4b03bc06608712cde390"
- deposit_count: 288
- execution_block_hash: "0x7895648d903ca4cfc86649eb22f8d1c758141f8d3aa89f938f2f25016481435e"
- execution_block_height: 289
-- deposit_data:
- pubkey: "0xaae696196c2730c93099a70860ca5efa86f84e5841e05aaeab2619a772f23eec46d4c72a31b0e458c85409b511b498a3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa99138f2331c3cf13064847011cece90e314742f897c5a629912cf2339ae8e2ee5375bd3a2bd33e164a03b3adde0d40f0243c57233e12f7d5f61328bb6f4e2516bbc784dd6fcd3ca814cb8658499516267b4b1aed34eee7dfcc1b9920efcbe4c"
- deposit_data_root: "0x844286999134010ba50c2a62fbe3af61cb39b66dcb6c74fbd58a9aad32331c73"
- eth1_data:
- deposit_root: "0x1aaf2dc02a54384847050da49a834ff3a3474b4419885b2e37092c885c2a5764"
- deposit_count: "289"
- block_hash: "0x74d07cd3aacb5ed6004cc7a76696a60a64fd2f8a1367d1070b3e9e70316cbc58"
- block_height: 290
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x844286999134010ba50c2a62fbe3af61cb39b66dcb6c74fbd58a9aad32331c73"
- deposit_root: "0x1aaf2dc02a54384847050da49a834ff3a3474b4419885b2e37092c885c2a5764"
- deposit_count: 289
- execution_block_hash: "0x74d07cd3aacb5ed6004cc7a76696a60a64fd2f8a1367d1070b3e9e70316cbc58"
- execution_block_height: 290
-- deposit_data:
- pubkey: "0xae0825786e4f5ada18f212b067a394b52e60b37c98bb22ccdf0416d27b33029678de976370eea92c384ae44bca79386c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb27632627c427944c2fc88f3cf387c3ae3b01bcbdd66fca2e0342c8d99608e86943a7f85783609c2f52bca77c4c703561734b382e423db9b639655ad298c1278d906259b9d73d8a050e78ce06433a6ad5c0e18f22edfdd6e59f8bcc4eff47262"
- deposit_data_root: "0xd4fb8486399925af6ee9cb0675686bf197754b6115bb082560b529ee4b0bc6af"
- eth1_data:
- deposit_root: "0x799fbeae76281fc3802633b4e9cf0e96fccd7cdfeef10763f38d71a9362264f1"
- deposit_count: "290"
- block_hash: "0x7394bcdc109326766ef4bbbc9a79a2e3a0ec7ca68af666caee2628105e29da04"
- block_height: 291
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x7705b49fc5157cced1429cc52e57d903c5bef2f85f33041d5cfb966557058b7c"
- deposit_root: "0x799fbeae76281fc3802633b4e9cf0e96fccd7cdfeef10763f38d71a9362264f1"
- deposit_count: 290
- execution_block_hash: "0x7394bcdc109326766ef4bbbc9a79a2e3a0ec7ca68af666caee2628105e29da04"
- execution_block_height: 291
-- deposit_data:
- pubkey: "0x95ef906a741f50b59bf8fb77c134abc0534fbe7d0c432832d2d1c0ff9bd20090b424df54ffadebb9cc43e5f3812a7968"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86e9c1163ad77136831a5a21680ae3b20e22ea656c108e3db81c698526b2a0f453df4b18c563a6491b4b627f8885e79611a4d5b71a2c2dc72812fd0219314c4ff2cd561cb8acb01fb6b03dc4052b7bcd5231053cbcb28d47da3e6bb3442b5018"
- deposit_data_root: "0x6edb20c206b0c315233ef2716988f6043c49f1a557b934ca778841f252256d33"
- eth1_data:
- deposit_root: "0x87c3659d83ea26cbde44dcc3b5b4c4afab70c1c3c1345cd11514aa7a325b66f0"
- deposit_count: "291"
- block_hash: "0xcf1ebd89ed9130987c74ec2d4af8d83006364bf28784baaadd4c169ecc03ac75"
- block_height: 292
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x7705b49fc5157cced1429cc52e57d903c5bef2f85f33041d5cfb966557058b7c"
- - "0x6edb20c206b0c315233ef2716988f6043c49f1a557b934ca778841f252256d33"
- deposit_root: "0x87c3659d83ea26cbde44dcc3b5b4c4afab70c1c3c1345cd11514aa7a325b66f0"
- deposit_count: 291
- execution_block_hash: "0xcf1ebd89ed9130987c74ec2d4af8d83006364bf28784baaadd4c169ecc03ac75"
- execution_block_height: 292
-- deposit_data:
- pubkey: "0xac3a33ffd0eb0ecdb7baf1a5a4d8fdbd7c2e7558aa073269d2f9b7e9e5c7a1402c30efdb34fd7d268ec5f64db92a76c3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xad36e7b3da78886b41f5e61ad0bec7a5a7f68fb9b6d5bfd0ba5b75c59dfc6ada6b33da3729215c23122d812abc4e8eda06f88f7e414e79224eefcb4bae2f798512cab1cb96f5f1c1ed5e8b81c97967098a3a38b96a1bb2e19bbc819de9342342"
- deposit_data_root: "0x7e435b81ff4fcb487b26cff3b131c5453c05d167c6617c8865879b51bf8fb04c"
- eth1_data:
- deposit_root: "0x53252143b0ff828eec2c69855e5ca87dd5153f5df8a7a24603031e62fc7a2980"
- deposit_count: "292"
- block_hash: "0x1dec0f6cbd0fdfaeb411d008ff1b21c4cab80e38ddab4385464828921e8903d7"
- block_height: 293
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x0730794fdc9fa73177b77e150edf2e164ec8d1917f76a71e085eefdaf0bd3835"
- deposit_root: "0x53252143b0ff828eec2c69855e5ca87dd5153f5df8a7a24603031e62fc7a2980"
- deposit_count: 292
- execution_block_hash: "0x1dec0f6cbd0fdfaeb411d008ff1b21c4cab80e38ddab4385464828921e8903d7"
- execution_block_height: 293
-- deposit_data:
- pubkey: "0x8b1d9ba63bdc005529f0f6e2f442e6649adcec11e0db1d643b3d3e09307cc8c5b3fb84049941b8692f10799011c246c9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb331295d92ea1dde46a7149810b7348a1cfc004b760326a35e61c95afde55c3e1c9798b3e94d8dc8b8a4101746600b470d2b693074eec42f90347e22ddb6dcf539de7b4c9d0bc2ad6d21e59d81228831df635658789f3d1dacea605ddc391719"
- deposit_data_root: "0xaa148346b9b8d2c5c24672977c58e8c35edacef56bfd81028f3fecba2b2442c5"
- eth1_data:
- deposit_root: "0x34e1e67726ccca66adad1c4d54baba739c7c52955a01b7cba29c3d8f2317f5e2"
- deposit_count: "293"
- block_hash: "0x5808234c115cc61500e2a564049a17037ee5108aec392d429f03f58ba8d16443"
- block_height: 294
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x0730794fdc9fa73177b77e150edf2e164ec8d1917f76a71e085eefdaf0bd3835"
- - "0xaa148346b9b8d2c5c24672977c58e8c35edacef56bfd81028f3fecba2b2442c5"
- deposit_root: "0x34e1e67726ccca66adad1c4d54baba739c7c52955a01b7cba29c3d8f2317f5e2"
- deposit_count: 293
- execution_block_hash: "0x5808234c115cc61500e2a564049a17037ee5108aec392d429f03f58ba8d16443"
- execution_block_height: 294
-- deposit_data:
- pubkey: "0x8f9ec3c7b0f5793f3056fee53b16af2874bef12a90bd0ecf6282d55ce6ba70a07071df4e3861ad99da8753677a2a74a3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa81d1bd6fb813b55c286bae7e79f9ad080e65865bc0c34f8309876e22f1db6e06b87abf4b0fbda1ade851d0914f8c4270d2abb19efd831a116a040180a9eae89daa1ef6a69748984c1b8029d33ed4e278d26226833a0d05762f94c389b758b83"
- deposit_data_root: "0xea2af2f7a4f8409ff112a26b16f36e6192581fd5c633f90b165668999c1f9e1e"
- eth1_data:
- deposit_root: "0x21ec4811b4490a5d9c97b40830607f18ed6decc77cafc3328b487ea076ec4520"
- deposit_count: "294"
- block_hash: "0xf86216620bf16f8591322c0b32fe4c594de559b382aae1c535be72771d8dba24"
- block_height: 295
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x0730794fdc9fa73177b77e150edf2e164ec8d1917f76a71e085eefdaf0bd3835"
- - "0x7bad1e86995476e6d8c7a8a05d659145ff02c84f1b0eac70e5964c395c14f8e3"
- deposit_root: "0x21ec4811b4490a5d9c97b40830607f18ed6decc77cafc3328b487ea076ec4520"
- deposit_count: 294
- execution_block_hash: "0xf86216620bf16f8591322c0b32fe4c594de559b382aae1c535be72771d8dba24"
- execution_block_height: 295
-- deposit_data:
- pubkey: "0xb083923ec58581ce049677eb0df25ff6ea0e29938881a9e03ecedf4c7482ccd25dbd2f8a15d6bbdf8eca74a74f444e40"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7ed5863f832a1b984ce9993b33cdded121815178c70538b0926a3f17452142ba546cb751861f739c4303940664348f908ab344bee4e62aacdf26d25ba25cb32b1269f3fd2defd2b740788f2000021c07f0ac20ed927745641f3ea74464ff433"
- deposit_data_root: "0x450d67be526c8cc2dc5b23a24ffbd79a03dc5b4e9685285e381e598bb478b958"
- eth1_data:
- deposit_root: "0x331ae72b1a07010b6967e88090dcf730d1c721b54900e636c7bcf23a4b511e7b"
- deposit_count: "295"
- block_hash: "0x5e382493002589f3487d5ef95d6933de04c0b65a592691966854d900eaf32f74"
- block_height: 296
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x0730794fdc9fa73177b77e150edf2e164ec8d1917f76a71e085eefdaf0bd3835"
- - "0x7bad1e86995476e6d8c7a8a05d659145ff02c84f1b0eac70e5964c395c14f8e3"
- - "0x450d67be526c8cc2dc5b23a24ffbd79a03dc5b4e9685285e381e598bb478b958"
- deposit_root: "0x331ae72b1a07010b6967e88090dcf730d1c721b54900e636c7bcf23a4b511e7b"
- deposit_count: 295
- execution_block_hash: "0x5e382493002589f3487d5ef95d6933de04c0b65a592691966854d900eaf32f74"
- execution_block_height: 296
-- deposit_data:
- pubkey: "0xa41e4e990ba7effeb504f4f0c27924c90c76ec433f2cc59d65619ce9796b80db1b2a6c3fdcd3a3b5ae798c65433ff911"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3eb87a76711659f7821c30c915d68c8853d948e1ca08da89c5f20b390f1c65feea7374c2040b3bbf9c6496af37afbaf09ef6a060d5370a06318053d845a4aaf99e82852a8ccb4dfab2ee3980f8cfda07b08dfdca5c15ce73a67fcd4d5979ca7"
- deposit_data_root: "0x056b0a462a8e8ab1f9cd2d1a3428e3a102de98b075968c605d95bb65dd516095"
- eth1_data:
- deposit_root: "0xc16e10784846d8fdd7bb158f065db835af24031e348baeae33ae24ede22ec3e1"
- deposit_count: "296"
- block_hash: "0x8ffaa2662024d089a5006527ba28bb380b041cc2e81e2421d4deaededb9d3d61"
- block_height: 297
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- deposit_root: "0xc16e10784846d8fdd7bb158f065db835af24031e348baeae33ae24ede22ec3e1"
- deposit_count: 296
- execution_block_hash: "0x8ffaa2662024d089a5006527ba28bb380b041cc2e81e2421d4deaededb9d3d61"
- execution_block_height: 297
-- deposit_data:
- pubkey: "0x8fb481a72fde68d6b21d0f679bcf64c9986e88acd27874cdfb4d2ae7a84e7dac89ca6afd072bdc503b15342ddc899b94"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83f4b1f8e47b6c688f1068e9ecfe223b53090656d44396b24f7192e6fd7cdfd66f96760b8fca2b01c57e0c01c323952008d6e33dbb0fbee95c36dda724fbecfb07dd99ce251bce32d22e2ce36bc45b9e59ffec6ac9aa2e67a94953ea1deab2c4"
- deposit_data_root: "0x8bc82d0cf82a2499dd2b717cfde2c3e68bfc128763e250a4fb50e3f0122accf8"
- eth1_data:
- deposit_root: "0x1add0cbc74e152fa595c6dc87e2d5df9699025429dc658682c635977d03fcd6a"
- deposit_count: "297"
- block_hash: "0xf305397aeec554ea12622d5b37c601710070c0f4856e2b0170856c55f80e07a9"
- block_height: 298
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0x8bc82d0cf82a2499dd2b717cfde2c3e68bfc128763e250a4fb50e3f0122accf8"
- deposit_root: "0x1add0cbc74e152fa595c6dc87e2d5df9699025429dc658682c635977d03fcd6a"
- deposit_count: 297
- execution_block_hash: "0xf305397aeec554ea12622d5b37c601710070c0f4856e2b0170856c55f80e07a9"
- execution_block_height: 298
-- deposit_data:
- pubkey: "0x9792ac6f48e8f90fdabf06dd862bfa48612c72685f259f7f69ce201889daf43e220bbe3795554d1973b497360b81311d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83ed426c80869348bf799aece915aa4c3ecd715df0d83c443758db8d74be8dfec2707bb8cd41a65117b7f484998f59d715cca0f03903248374af59f3013d9a0ea7ec0dff855c632ad47c695186736c62ad52d3c0131f5227bd8d2a977e4b574f"
- deposit_data_root: "0x377acb0a185e15e235bb479f2c7a6eadcdebbe04e96282510656c1c8643c8f08"
- eth1_data:
- deposit_root: "0x90beacf75d211ca5fa19ea7a78d25c2e9a72a9b59652192d5b37368a66d7f71a"
- deposit_count: "298"
- block_hash: "0x141e6a356ffe9bce0d90886c27b5460df7ad03c69635cf28c3a3ffa99dd524b7"
- block_height: 299
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xc60a40ade74fa8bc78d964bb75dbe9e361b8468980dcf4ef30f5712a8e06f20a"
- deposit_root: "0x90beacf75d211ca5fa19ea7a78d25c2e9a72a9b59652192d5b37368a66d7f71a"
- deposit_count: 298
- execution_block_hash: "0x141e6a356ffe9bce0d90886c27b5460df7ad03c69635cf28c3a3ffa99dd524b7"
- execution_block_height: 299
-- deposit_data:
- pubkey: "0x8db6b709638a90a292ecc760d425bd26855a8b67e34286987f3c6aefa0811573e106f54b088b3afa8436156fb36f783e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae4ead5a15f81287a7c7c20d4265d95345637980d27bf0d8edfdb1d7ca2099c9283916e09eae340be93f7db49d76d89b19ae467cecc02bee4d8f47a82a9609db4ed4f5c915c910babbc35d885799b6d6e5e70b9025a6e2e192f8dabe61109028"
- deposit_data_root: "0xddc96174c52bb3bdd22b83e73bda24cafc7203e6166d0ede60c079a367d5ac08"
- eth1_data:
- deposit_root: "0x31dae0097efd30f99ca3f1582a55545fc31326f4046ce06adce7b926155b60b6"
- deposit_count: "299"
- block_hash: "0x34c74dd45b01879ff4a0508fefbf6fc9adccc408bffa5cfe13e68655115226e0"
- block_height: 300
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xc60a40ade74fa8bc78d964bb75dbe9e361b8468980dcf4ef30f5712a8e06f20a"
- - "0xddc96174c52bb3bdd22b83e73bda24cafc7203e6166d0ede60c079a367d5ac08"
- deposit_root: "0x31dae0097efd30f99ca3f1582a55545fc31326f4046ce06adce7b926155b60b6"
- deposit_count: 299
- execution_block_hash: "0x34c74dd45b01879ff4a0508fefbf6fc9adccc408bffa5cfe13e68655115226e0"
- execution_block_height: 300
-- deposit_data:
- pubkey: "0x93ad251e308b778815f925a6de6b11bb7f3d4d8d710cafd66cab8be0b91ef0ada350c2ca2d8f5fbc3ff4f002445680f9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3cf73c28799277452db8bb4e7c5944f029c8228321a655325aac140baf67884f24dd459356818857341088afda6828b06149d514d5b2ff3caf8993ed07129b111798a35a9dc28f526752e6002cee205127893ceea458afb5da8698d0eb4902b"
- deposit_data_root: "0xa01227f9122459ac47d9a6b110e72f74ea18ae68b62ca95a0b76bb4166269eda"
- eth1_data:
- deposit_root: "0x8c2f6e57502350b5d9f26e44419267b541ad91471cab8d5db5ff4184f5bb33a0"
- deposit_count: "300"
- block_hash: "0x193c858804c50b4119d959c31820b38c2beb2bc36f0e0595213c4030cac59626"
- block_height: 301
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xb8f534205d4b218cd717bddf06a06cae872d995a165506cff2e8c12af6a71afa"
- deposit_root: "0x8c2f6e57502350b5d9f26e44419267b541ad91471cab8d5db5ff4184f5bb33a0"
- deposit_count: 300
- execution_block_hash: "0x193c858804c50b4119d959c31820b38c2beb2bc36f0e0595213c4030cac59626"
- execution_block_height: 301
-- deposit_data:
- pubkey: "0xa31e15bea68f0f555e2eb0552f74bb78a755ee77e242799cfeb8a380507d994cf24f46fd86568f46c4ecc7ddcf359ba6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb3e700ee6b7fcd21fe53dee2c22d4da8ca914be0adebfd496396edff50068679a17410d9afbcfffd5f6b0add9d2523e90cdf840ba008e4d58ebe9ebea0115305155c5d3f7b566cbde5f7dd511fef9d543c1fab467e91bac3d4a27ac9ad87957f"
- deposit_data_root: "0xdcf69aa4fa002dbef4af6017e7a178c9c553c68e3f3d9352563491ab58bd82b5"
- eth1_data:
- deposit_root: "0x7615cbc219a8c6a9fb950d887fd850185534967b2a5441902215e584dd2151a5"
- deposit_count: "301"
- block_hash: "0x79363266a5cff13e09297e640ced33e737db69fdc4e8a649939e36578099a9e3"
- block_height: 302
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xb8f534205d4b218cd717bddf06a06cae872d995a165506cff2e8c12af6a71afa"
- - "0xdcf69aa4fa002dbef4af6017e7a178c9c553c68e3f3d9352563491ab58bd82b5"
- deposit_root: "0x7615cbc219a8c6a9fb950d887fd850185534967b2a5441902215e584dd2151a5"
- deposit_count: 301
- execution_block_hash: "0x79363266a5cff13e09297e640ced33e737db69fdc4e8a649939e36578099a9e3"
- execution_block_height: 302
-- deposit_data:
- pubkey: "0xafb329bae0ec756fd1be3ee1eac93550b77177d96558deeec2a6a131e35ccdee653189d4f5bb744f492371605c44a9bc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81839fd0a1d6bcb75751f1c9a3d3b2a8c7812c4e2933d52c0327d69ca7fea84c9ad7c1a4475c88e46d25baeacd41e4e60c5f3ea05c16ec768e011d41c0e3b2edac0d9ae16b4b410313470283ed4086634c080bb7e676493763c459c6d246e15a"
- deposit_data_root: "0x3d5f8d118ae4e4fca8223b2b819c1931cd041443d278b6823c9b4aea22bd57f7"
- eth1_data:
- deposit_root: "0xa80eedd04962726c155bf13aa99c6c56457c99e3d4533ab74a4abe2e961fe9f8"
- deposit_count: "302"
- block_hash: "0x1c6191f59c7eb6f4c8cc5837ccd23de7600c2dffb62c9e1133248baf3cc4e363"
- block_height: 303
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xb8f534205d4b218cd717bddf06a06cae872d995a165506cff2e8c12af6a71afa"
- - "0xa93353e7b0d909e8d19d5d6c466cae15e8e5f2b929758e88d8c35f6ac180c0c2"
- deposit_root: "0xa80eedd04962726c155bf13aa99c6c56457c99e3d4533ab74a4abe2e961fe9f8"
- deposit_count: 302
- execution_block_hash: "0x1c6191f59c7eb6f4c8cc5837ccd23de7600c2dffb62c9e1133248baf3cc4e363"
- execution_block_height: 303
-- deposit_data:
- pubkey: "0xb62df9c59793d5e3a553e9f5b9da4c928105e221898f11847e7ec9a60c091a1a56e0f141d64bb5bac13d424a49798917"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x822390897c4b8d9e0f2d0868afe9cfe5efc14f7290a48717071de84200fdf96d5f4aecf2c577d003f4af4c4f59bbbfc802166746f52794eecdc656c4ec845085d053c4d021d45c639567e24825bbc60572747900e54452fb052f45895ed97e14"
- deposit_data_root: "0x888daeb2cf145994cbd3f25806c306082dd402d4b4420f0817c5a5a19132cb36"
- eth1_data:
- deposit_root: "0x334dbf7b9b0cd5d22f79c7dca388d3baf541e430bdd31883fd7402852febf29a"
- deposit_count: "303"
- block_hash: "0x42bc399b54a8e566243c3ba4e2e1ceeca8eea2b7cd84462b8814229d9f459796"
- block_height: 304
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0x5b1f9c36b45f9d1e8495781e9d8290f328e09b9ec8f382b801aa6354b25b2e27"
- - "0xb8f534205d4b218cd717bddf06a06cae872d995a165506cff2e8c12af6a71afa"
- - "0xa93353e7b0d909e8d19d5d6c466cae15e8e5f2b929758e88d8c35f6ac180c0c2"
- - "0x888daeb2cf145994cbd3f25806c306082dd402d4b4420f0817c5a5a19132cb36"
- deposit_root: "0x334dbf7b9b0cd5d22f79c7dca388d3baf541e430bdd31883fd7402852febf29a"
- deposit_count: 303
- execution_block_hash: "0x42bc399b54a8e566243c3ba4e2e1ceeca8eea2b7cd84462b8814229d9f459796"
- execution_block_height: 304
-- deposit_data:
- pubkey: "0x810ab821a4d4a0707e0f70eb7dbf78a528e2503749e462fda69969ef1aeee9ad2b8d37c77056bdb0feecdf206313d2e9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8899dcaccd1c167c69c6e4d5ab42f03f5a6e9bf1a1d664dbf07fac6de06b59e651147cf78a2924acedb33944a8d11d451189e78c32a646260d0401ebe79dda5c35d00688cc0d024a2f12248b47fe5d4a7a04fdd420aca97e85f86497998f66fc"
- deposit_data_root: "0x0c6eefdd540468d0e9e72aa9c1394441e05788e7f0998cf6f5157466fdde05d2"
- eth1_data:
- deposit_root: "0x3fddb8ccad286ee5c85d0e2d851ee3d45dd7b03bef1a980c60ba49166465af93"
- deposit_count: "304"
- block_hash: "0xb0338e285f4f8d5621dfb6894d21095a58cc89d5d8b0e574edf8efe7ca30ad26"
- block_height: 305
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- deposit_root: "0x3fddb8ccad286ee5c85d0e2d851ee3d45dd7b03bef1a980c60ba49166465af93"
- deposit_count: 304
- execution_block_hash: "0xb0338e285f4f8d5621dfb6894d21095a58cc89d5d8b0e574edf8efe7ca30ad26"
- execution_block_height: 305
-- deposit_data:
- pubkey: "0x80f23973b414503e2ba0a53f67463f332b23fe5fd5466f1a770a6d548fdf4421d9370ae890b54be1cbeacb7a9e31d166"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85a60518498341146050685aefe04587f4f9cbb7210bee705e2018c351d358d357330ca0a81da886788228eb0a3688d202024a72a5c378ccbba3c7fc7fbfcf84d630c0a8cac56ee029b8348d83b6b73b1e7019dadd34ed0272e7e6f0ea8b36b5"
- deposit_data_root: "0x7562d64a4e031ff5e46a3319de670de403d8b14c256ade2aa6c3f69b2e0ae077"
- eth1_data:
- deposit_root: "0x567a327092d5109af0a5b29ad3c445d7444dd00fa1e34b678db5e04b48a54917"
- deposit_count: "305"
- block_hash: "0x30f7bf7c4b84b1e0e14234732b33fd5eaa755838404fd7a9558a0d52b29a072d"
- block_height: 306
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x7562d64a4e031ff5e46a3319de670de403d8b14c256ade2aa6c3f69b2e0ae077"
- deposit_root: "0x567a327092d5109af0a5b29ad3c445d7444dd00fa1e34b678db5e04b48a54917"
- deposit_count: 305
- execution_block_hash: "0x30f7bf7c4b84b1e0e14234732b33fd5eaa755838404fd7a9558a0d52b29a072d"
- execution_block_height: 306
-- deposit_data:
- pubkey: "0x95ce181db92ea8695c006896d2bb9faada9e157a896cf06b5466c304ccc6b09f7b8b10044b9b0689265ee97a6388dcd7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5911e4df04e991fe79576339db9eabcdaa7a691fcf6a07e86666b81f4176fb2cf7bdcd93f7512f3d8a0bef4725c30680e6ee5439ac60e013ea0cdfc8c11c0a044f0a64c7393bd12927b9c51b45b2862311ca1169fcd83b798c1653d1131d98d"
- deposit_data_root: "0x88d50a861161dc2f5a2fd41cc69eca91e1e251d29224d3e813937860204f93f8"
- eth1_data:
- deposit_root: "0x3e8177de3da30a03e473faa90d01ef262563526c5a28c17d22c4bba44430eef5"
- deposit_count: "306"
- block_hash: "0x0168559f9953fd501450a3ff14cd7b48b0b75663a319abd9766d4d9fc514a2e0"
- block_height: 307
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x2685dc940c27a8289d56e5cf4246afc27ad50baf0abef93caa8e379dcb39b41e"
- deposit_root: "0x3e8177de3da30a03e473faa90d01ef262563526c5a28c17d22c4bba44430eef5"
- deposit_count: 306
- execution_block_hash: "0x0168559f9953fd501450a3ff14cd7b48b0b75663a319abd9766d4d9fc514a2e0"
- execution_block_height: 307
-- deposit_data:
- pubkey: "0x8e322c2995e2472a7981466eb4b890d753b2016798cf640ed4b7ea7a3d53e5644361f404c5eec4baa1a55da860b7981c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaeb741e937c13a7f8dfa2b7603c902719786f247a25b0eedf6327921d09486afb8ef66c30b232d6032d4ab5475dd54f407c702a09cad1bfd675ff57f44d100a996af265c6c275c69f0593da7832a81cad4417b82fbfc6a088482b3aa1d856a4f"
- deposit_data_root: "0xc275ba69111f046f57da439d9b3d3e52a7124328b5909b40655e1afe75bfbbf1"
- eth1_data:
- deposit_root: "0xf228d693edc9dde11a393ab4191a7b47ad4eabe0839bba4fcdc6a63cda49f729"
- deposit_count: "307"
- block_hash: "0x6d3facdb3a92f45bf9f2d65576346739d524e703d4057c1d8474b3fe9de8667f"
- block_height: 308
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x2685dc940c27a8289d56e5cf4246afc27ad50baf0abef93caa8e379dcb39b41e"
- - "0xc275ba69111f046f57da439d9b3d3e52a7124328b5909b40655e1afe75bfbbf1"
- deposit_root: "0xf228d693edc9dde11a393ab4191a7b47ad4eabe0839bba4fcdc6a63cda49f729"
- deposit_count: 307
- execution_block_hash: "0x6d3facdb3a92f45bf9f2d65576346739d524e703d4057c1d8474b3fe9de8667f"
- execution_block_height: 308
-- deposit_data:
- pubkey: "0xb6f68789c60d1348b5e24bd6b7ccc18500be7b6ef0099895547a83f63eca37ca4f26fa3517d5bc71bc4a2fb186149179"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8888f11eaefbd7bee2d93a8713415d0452b6cdf794f5095a7f4b7913556b17e969d6b1137048e2fa94af582d4fea848e185cd3df47f5071d49ec86d21389443e4771f31fc466c3bdf211cca260f677769c90d5493b6a0e8a230c455a9f6539cd"
- deposit_data_root: "0xc5256c0995975cc0953677c36413969b40e96b3921007fd975bdb7d5cc883d5c"
- eth1_data:
- deposit_root: "0x301dd53110abda16d11eee1d46ccbc839f8e9adc1c0f0592aa010242f123397f"
- deposit_count: "308"
- block_hash: "0x4c2a9c39824275f99a4ef57cff7778b6fb793cd493d7e96da426f9f5c50b19f0"
- block_height: 309
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x428b54bb40a87f83657cfb7998905b4deaad55f2d092f13b0365b11847bd984b"
- deposit_root: "0x301dd53110abda16d11eee1d46ccbc839f8e9adc1c0f0592aa010242f123397f"
- deposit_count: 308
- execution_block_hash: "0x4c2a9c39824275f99a4ef57cff7778b6fb793cd493d7e96da426f9f5c50b19f0"
- execution_block_height: 309
-- deposit_data:
- pubkey: "0xb50d3fc8e36d2f2eb544c16b959b500160c2b176298e4e16ae5d928856406c86605b8ea6bd802ca1a2d1c9210d6bce61"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa88f8ea391dcba3fbbf6a4ffb58bcb8135d0001207c3656f671fab5669903a3d1fbf1150e856abd0c2d180f5518205d707692aa6a239ab2bea39338b11b0a04cb078bc61fe966feb25b905b1629067a6107bb858393339002119592d03d60395"
- deposit_data_root: "0x768bb277eec0d74fe504242f61cd37bd63a76417f860ea154d89bf1e9209318e"
- eth1_data:
- deposit_root: "0x03403e71434239fc6cf3c51e014029b6dce79899d189cb789ca41ec8c76870df"
- deposit_count: "309"
- block_hash: "0x142755a334e7b0f2ecd19714918edfc8fc49e591dbe27a072f98b929914795c2"
- block_height: 310
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x428b54bb40a87f83657cfb7998905b4deaad55f2d092f13b0365b11847bd984b"
- - "0x768bb277eec0d74fe504242f61cd37bd63a76417f860ea154d89bf1e9209318e"
- deposit_root: "0x03403e71434239fc6cf3c51e014029b6dce79899d189cb789ca41ec8c76870df"
- deposit_count: 309
- execution_block_hash: "0x142755a334e7b0f2ecd19714918edfc8fc49e591dbe27a072f98b929914795c2"
- execution_block_height: 310
-- deposit_data:
- pubkey: "0xa72612ca8f454d74489512d0637191bcac72124f4111f7cd52de8920ee3ea804ee895201ed74527407159220ed00712b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x988ee0d14e460e614b4db31aa0edce326450745ae33898a67f59279ca125a60a420e3fef3440be1502b173cf3b6cf75f16e427739cc02e79804a5533453b752962eb695656c5f7eadb3c13588762fcc743978bd3d6ccd4feeadedbb9bf2b989d"
- deposit_data_root: "0x0275c66e7493040447a4a1ce248051418acdc6c62cbe2e5de0a6ab4737f1c6c7"
- eth1_data:
- deposit_root: "0x80a4bb6bffb48e9c359242c260546b21e0b52020788e5a30a6c06a4ac8728d4f"
- deposit_count: "310"
- block_hash: "0x626aa2fd2714dfff5d15b35def25420116d8ccb50a602513f9596ed98e06040b"
- block_height: 311
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x428b54bb40a87f83657cfb7998905b4deaad55f2d092f13b0365b11847bd984b"
- - "0xeb3f38ea9f413e0b73256ebd08ed8be2b639aced165911e48656e44330d03d5a"
- deposit_root: "0x80a4bb6bffb48e9c359242c260546b21e0b52020788e5a30a6c06a4ac8728d4f"
- deposit_count: 310
- execution_block_hash: "0x626aa2fd2714dfff5d15b35def25420116d8ccb50a602513f9596ed98e06040b"
- execution_block_height: 311
-- deposit_data:
- pubkey: "0xabdcd975ccfab19f10d7ec535f7c0e9e269a34f5eeb653d15ee0505f383274e5a20b3b71bdba0f369e36cea0eae1f5b1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80039f2345c88aeb006695982d70543e37c8cf5a1622b589326d215ff2687396eba8797e896c590878aff20bcdfeecdb0e4e9534df8429e3cc8c585d0a1821c9c9378d4f2335f4dacb7d59794539c7d77306da1f065a126593bfcce78465d8e9"
- deposit_data_root: "0x12463230892e22766c8e4be4bde2f242553e7b213843ef3cb46c4ef6612cab71"
- eth1_data:
- deposit_root: "0xa0dffba4c6f35f9ce7e1e951a12c523651b6aa4bfb17e2323cf26324cce04330"
- deposit_count: "311"
- block_hash: "0xfb60531376af074a51de3a1bbceb7df9fab77acaca749ee4f779abf774252092"
- block_height: 312
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0x428b54bb40a87f83657cfb7998905b4deaad55f2d092f13b0365b11847bd984b"
- - "0xeb3f38ea9f413e0b73256ebd08ed8be2b639aced165911e48656e44330d03d5a"
- - "0x12463230892e22766c8e4be4bde2f242553e7b213843ef3cb46c4ef6612cab71"
- deposit_root: "0xa0dffba4c6f35f9ce7e1e951a12c523651b6aa4bfb17e2323cf26324cce04330"
- deposit_count: 311
- execution_block_hash: "0xfb60531376af074a51de3a1bbceb7df9fab77acaca749ee4f779abf774252092"
- execution_block_height: 312
-- deposit_data:
- pubkey: "0x83dbae1b08eea5bf0a89eb1d0b61e9e0c4e1142610ac8d88d9f3bdef550e3264b54bd47052d481738b92ffbcf6e36f67"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xabec6694b693a184bc5720f1d0c4d8dd8630609076af52ae7fa62c04fa7df7cc3c793d1eb776199a8755e861c9bd35410c3e225f31912cd2fb21694fcf444db989aa5e4eacc3434ac4ecb894fd4f203f1514e3034e328cf5d174ee896be4e26e"
- deposit_data_root: "0x627fbf478b052d8b09b47b17598cb372ef316a9e2df9fee7e04639f9f23a9060"
- eth1_data:
- deposit_root: "0x5c072d54c707ccbcd880507073f57cc01b6f162aea0a100c4523deb9508f357a"
- deposit_count: "312"
- block_hash: "0x4a09a6f7522d4793a3c0f56fd21714035a19d37f18d975a218b34952df576c9b"
- block_height: 313
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- deposit_root: "0x5c072d54c707ccbcd880507073f57cc01b6f162aea0a100c4523deb9508f357a"
- deposit_count: 312
- execution_block_hash: "0x4a09a6f7522d4793a3c0f56fd21714035a19d37f18d975a218b34952df576c9b"
- execution_block_height: 313
-- deposit_data:
- pubkey: "0xb628c432d9d76dd6483ed50938fc4c369bd24b6e3c1a41cc4620f7b513148fb242a76c7577f8766a14770ae597c36aa4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x90be83d06747ca26fd1d38a4847a9fbb02f2433ba940b51f364ca9bacb3924a2ffbc0d6e23366eeccfafaed746e29bce12589c80fb49db1b11df5da16a75aa4605b571efd142c59c07e0607cbbf6c16d989461a515e2a44b4f3c4c561fba0505"
- deposit_data_root: "0x74cc9ddae3f91c1b4bd274ed0ed14c29daaba30aed1632521ef60ca123ce2d09"
- eth1_data:
- deposit_root: "0x7789482c357af66154948684754c641d23d0d2556cbe3f017a9680aabb46934e"
- deposit_count: "313"
- block_hash: "0xad05a4ad4a1dd8968ce13df5c3a6fed1f0899849372b26285fc4288bab0e2b65"
- block_height: 314
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x74cc9ddae3f91c1b4bd274ed0ed14c29daaba30aed1632521ef60ca123ce2d09"
- deposit_root: "0x7789482c357af66154948684754c641d23d0d2556cbe3f017a9680aabb46934e"
- deposit_count: 313
- execution_block_hash: "0xad05a4ad4a1dd8968ce13df5c3a6fed1f0899849372b26285fc4288bab0e2b65"
- execution_block_height: 314
-- deposit_data:
- pubkey: "0xa36425294d9fe4f803acb3ce90947ea5f20cb1c06c4899b80129d8fd7e491f0128d86f98aa987a1578ec1244ae3d5f17"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb19797920d1e40e85dafd881d1193e1b347dc252974d55d0187abfd6e0f2a195746fc24527529581c1f59f3d3bea4d2d0ef3080d515468c273d216711cb3b618d9f7f25f7da3ef789d060cb1811a747a3ec0ab93c149bb8656825451426dc668"
- deposit_data_root: "0x955a4d69a457b02106c01614769dfb29fe7d5c6672da037a22e16619edb5c06e"
- eth1_data:
- deposit_root: "0x627b60a6d46949a3c8dfde03b024118cf57f0b8e3590ab48c2523715e48b9011"
- deposit_count: "314"
- block_hash: "0x2ddf1d0ff89d425c64c78796ae3826cd030caa6ae70fbaa29c24a0d81abcdfb3"
- block_height: 315
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x69106b127afcf2e4ddba6429779d04030f20a0ae7eab086bb65958c789430cd4"
- deposit_root: "0x627b60a6d46949a3c8dfde03b024118cf57f0b8e3590ab48c2523715e48b9011"
- deposit_count: 314
- execution_block_hash: "0x2ddf1d0ff89d425c64c78796ae3826cd030caa6ae70fbaa29c24a0d81abcdfb3"
- execution_block_height: 315
-- deposit_data:
- pubkey: "0xac55318cef8cd8f015f2493d09be7556066e235f618971a3325368f3deba029bae60fba85171762827f1f70c6883a467"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b4f261038c4bff210d1a0925059e46cd0d830b16b6a20da2a8ac9bdde1239f15b21d20550fd5d1878977bf0e0358fec155a9cbd51112d9ecaabaa5d3a56100afe4f18a3a0ade34698d2e84e52e164fe83c4b1140ad4a6d048a09e658c57f8b0"
- deposit_data_root: "0x7dbeb694af44e130ec3a9390893a798e86e787ed494bacfc10a3ef49d8e85889"
- eth1_data:
- deposit_root: "0xc8cc34185cb292295e96bbb5ab092b69eacb7984aebe7f0d88ae077aa6c71e20"
- deposit_count: "315"
- block_hash: "0x48396fede67f0d87fdb841ae3f8dd588552fc1b43141ff5c2dae2f143a305a65"
- block_height: 316
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x69106b127afcf2e4ddba6429779d04030f20a0ae7eab086bb65958c789430cd4"
- - "0x7dbeb694af44e130ec3a9390893a798e86e787ed494bacfc10a3ef49d8e85889"
- deposit_root: "0xc8cc34185cb292295e96bbb5ab092b69eacb7984aebe7f0d88ae077aa6c71e20"
- deposit_count: 315
- execution_block_hash: "0x48396fede67f0d87fdb841ae3f8dd588552fc1b43141ff5c2dae2f143a305a65"
- execution_block_height: 316
-- deposit_data:
- pubkey: "0x9966dc1de264da86652de12f70b4d6c7271026be0b081797589ba126108809b6264e2ec18cd59e90dd2c639bcd9986c2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97dd0583026f23df048ceccb8815d9ae93a5a61cc8ae0e57ef7bee0e0c16f146ba1e0b31c5490f61697c83dd8eabab7f025d724669389df5fcf1abc54f0d7715885d5db3c0f2dda0ecf1ec51fcbf613a9531894f9bec308782b73441a1f29ad3"
- deposit_data_root: "0x0f9245219098e059529bd695cb6a8409d6a7b771146e799ea918c4bc4778aaac"
- eth1_data:
- deposit_root: "0xd275e61f8ffd78a24684a3e46425d38e6dffa2babf29bbf98d3521ef0d6891e4"
- deposit_count: "316"
- block_hash: "0xb4bd7e404339b1e80030772dc8b8f1721d29b9b31516b26eb094eac84d8f36d1"
- block_height: 317
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x587c330aecf776f443ed580dc13abd4d0a36e4f8617e25366dce8a28e796d9e2"
- deposit_root: "0xd275e61f8ffd78a24684a3e46425d38e6dffa2babf29bbf98d3521ef0d6891e4"
- deposit_count: 316
- execution_block_hash: "0xb4bd7e404339b1e80030772dc8b8f1721d29b9b31516b26eb094eac84d8f36d1"
- execution_block_height: 317
-- deposit_data:
- pubkey: "0xb5a83ace1a9e683361435bb484295c11e371316800c073c8beaf1ee1900d5589966ac8266ee11b10b24f671231584302"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9029f10262639dc7a78130c1e0d924531a0939ce02c93df4171d9bda8a055dd270588fb54bc87c0a19a8ae1a3b93f02d1471907debb2c43e052a2bc6c71dc80751c96e46ecdb6e64ee5dbd86669b821e4fb7ef1a863af73a25207391e92c2f15"
- deposit_data_root: "0x2eea6ad287847510e3abaacdd5d8b21bf4c3cb317cee848b5150d76c7eee2326"
- eth1_data:
- deposit_root: "0xf7814cef15936b64805475bca92a6a37105312c8fdb4b6088bbf8d02aaf03a78"
- deposit_count: "317"
- block_hash: "0xb1baae047525e7438d4e06c776b9c14549a2bb0539275ce2d43a54605802105a"
- block_height: 318
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x587c330aecf776f443ed580dc13abd4d0a36e4f8617e25366dce8a28e796d9e2"
- - "0x2eea6ad287847510e3abaacdd5d8b21bf4c3cb317cee848b5150d76c7eee2326"
- deposit_root: "0xf7814cef15936b64805475bca92a6a37105312c8fdb4b6088bbf8d02aaf03a78"
- deposit_count: 317
- execution_block_hash: "0xb1baae047525e7438d4e06c776b9c14549a2bb0539275ce2d43a54605802105a"
- execution_block_height: 318
-- deposit_data:
- pubkey: "0x8428f1acb3bf75a11ca3ff7b9fcb2af1f0c43ae22f08d4ceb586c96f97f5d999273739d348900e2424cd375e5ef68f35"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7a7faad5149b6e8b901414c37b01b5955033c7b7b29aab827b29cdd0a7bb32bcaebe1c67bdc1de99a972cfa52defdf518084a465c3804241e9d3915b441a8a108770f557e5b372ec2f4d7bb127b03585ce8ea85ab35506c51fbdd91ac109403"
- deposit_data_root: "0x37f7ed384f323053073d09ba424f7fcba44ae6b1f50464f210cf880df9ec4e8c"
- eth1_data:
- deposit_root: "0xf1b373962ed896fb473e2e0625acad818126834046cd4f36d43ef3c3fe15a589"
- deposit_count: "318"
- block_hash: "0xe756598b26a44670dfd997e1be73332113f9605d5d8d7f07ee3162f04d72ccd1"
- block_height: 319
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x587c330aecf776f443ed580dc13abd4d0a36e4f8617e25366dce8a28e796d9e2"
- - "0xfef52200f08b898e7c1909fe36e281e60093f925aa8400431e6f2fad81571ce1"
- deposit_root: "0xf1b373962ed896fb473e2e0625acad818126834046cd4f36d43ef3c3fe15a589"
- deposit_count: 318
- execution_block_hash: "0xe756598b26a44670dfd997e1be73332113f9605d5d8d7f07ee3162f04d72ccd1"
- execution_block_height: 319
-- deposit_data:
- pubkey: "0x8e73eafaa8fb6863473e55ef578c4764d9330996a62132a9329ab43f2a45ef2e68637cf48f674c8a0d127d9fb2738229"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93dd39078da197a9ed00edf9ddff70017afad6b5cf9c9c3eb139bd61b362152c6d1d2bfce66fb93445eef99d2ddbbd041371aa6178eeb511229633be0e31fd692628a383b42e11a3e8a219c66bf15942c34658c1cffe86b97857145b0cf14f8d"
- deposit_data_root: "0xaa707e0428d7847f2f87e9dd478d34b093aa50c6bd025d7152f7fc48b5e61f5f"
- eth1_data:
- deposit_root: "0x24873485c0d733699f5309721201310f38e8e8a3fdd5c63dcab7f918a360e9a7"
- deposit_count: "319"
- block_hash: "0x703e8869ebd982b635b6f7f298cddff7ee58d5f8d9518c80c0d5aa0cd5bea3df"
- block_height: 320
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0x22c8f83b80ba6d15c5d143935e2decb02783c33299c81a81495369e44fd7f121"
- - "0xd332180e48743692efc13e599dedfd063f73963ababcf12ee1dbcddab376bcd5"
- - "0xb1125c174cf98e6ea57e02bfb8108d15da2cc5c7f1d49167551a9bf8bc37a7df"
- - "0x587c330aecf776f443ed580dc13abd4d0a36e4f8617e25366dce8a28e796d9e2"
- - "0xfef52200f08b898e7c1909fe36e281e60093f925aa8400431e6f2fad81571ce1"
- - "0xaa707e0428d7847f2f87e9dd478d34b093aa50c6bd025d7152f7fc48b5e61f5f"
- deposit_root: "0x24873485c0d733699f5309721201310f38e8e8a3fdd5c63dcab7f918a360e9a7"
- deposit_count: 319
- execution_block_hash: "0x703e8869ebd982b635b6f7f298cddff7ee58d5f8d9518c80c0d5aa0cd5bea3df"
- execution_block_height: 320
-- deposit_data:
- pubkey: "0xae451c6d18b7a14585dc96423f078be6b46742dde9be4d52907fff934956ebb2332e82c66cc2354eeb2da821e80ab7bb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89bb72ea77d8cf12f08050fe005f9da2e6d31b5348ec1e6e7b46e1084664c5b2f486c7c44773df37ecbdf1ab7c3f86e00fc35ebd2f4d470d929deda82847570be28c6191631235ce4901ea75920638210cdc92f2776889addfefdc77023ec196"
- deposit_data_root: "0x7407798bee346eb5f23e00cdc0fbf7fddfbc35a0ab4c6573296cc0d58fe5dbb3"
- eth1_data:
- deposit_root: "0x2b537afcf4a0b123429379355ab08f2ed8e1f5a15311d37e6dfdb7436d78bf87"
- deposit_count: "320"
- block_hash: "0x4e38625114a763d73cb04258b94c92eda5b6eee0507e18e9f4b562cbfb2060e6"
- block_height: 321
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- deposit_root: "0x2b537afcf4a0b123429379355ab08f2ed8e1f5a15311d37e6dfdb7436d78bf87"
- deposit_count: 320
- execution_block_hash: "0x4e38625114a763d73cb04258b94c92eda5b6eee0507e18e9f4b562cbfb2060e6"
- execution_block_height: 321
-- deposit_data:
- pubkey: "0x953ecb430dfe4f91510dbb8166f07a557881c19112e41a8b1b8b0aa2c3d95c061cdff951044255a3e4df6f529302beff"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x90650885698e776deaeb845e2582dc5a60770c20f08563c429ee2e6657d01e4ae4e0a6464e9669341f3b04f64846a02f05b00b950fb4c5b10363582bce2ac313ec4534758bc293b3b9eab0149217e45b761952b6a894e3f42226d9392d33219a"
- deposit_data_root: "0xc978fe6c6f919724950edef3008541909ddc2965bf9bdd297aa98ff6760919c9"
- eth1_data:
- deposit_root: "0x0d9593241269b53b9aab5168a1db67f2ac6afb5e1811ca34627e5f510fa47c27"
- deposit_count: "321"
- block_hash: "0x101e4774d651227e02db01e67dd883d7ecfa1762fc5773639bdec3394fec49b8"
- block_height: 322
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0xc978fe6c6f919724950edef3008541909ddc2965bf9bdd297aa98ff6760919c9"
- deposit_root: "0x0d9593241269b53b9aab5168a1db67f2ac6afb5e1811ca34627e5f510fa47c27"
- deposit_count: 321
- execution_block_hash: "0x101e4774d651227e02db01e67dd883d7ecfa1762fc5773639bdec3394fec49b8"
- execution_block_height: 322
-- deposit_data:
- pubkey: "0xae629cdd3ee2278a8993feb4e163a9127c4a09857981704fad31e3fbf2e7668136f2943987c7b5619d7e362d1bf9d9ee"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4700ecbc23a35301973959072651da1963b1ec856c7d210e4bf165d7a306c501b9e31fa34e73b4001a1ab3a9b0acdaa0c62ba65f79e3ccfeebee512fdf980dc937a1c34a59bf67f323de0753ffc974ac8047948d924cd9204827b0587fef031"
- deposit_data_root: "0xa35ac1d1af9eab97f2679f3dfaef4a934ab6de575cadb245a45d754ff1c696df"
- eth1_data:
- deposit_root: "0xe3ab2d88fbc1cf4b39a86b71ea1d020c2d8231c69cc6d6eb2523c08b7fba9426"
- deposit_count: "322"
- block_hash: "0xc581458176fa41f0363a1ca199b1926a761489bf6dfacfa6cecbecffac82995a"
- block_height: 323
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x909fdc4a762e835a5b890dc4b1c41ca41b65df75770ac25537840d618375a2b5"
- deposit_root: "0xe3ab2d88fbc1cf4b39a86b71ea1d020c2d8231c69cc6d6eb2523c08b7fba9426"
- deposit_count: 322
- execution_block_hash: "0xc581458176fa41f0363a1ca199b1926a761489bf6dfacfa6cecbecffac82995a"
- execution_block_height: 323
-- deposit_data:
- pubkey: "0x963564994c2f8935ab03230c47dbd3596ca372a892a616c28ed80a582b9ca4a43e6ef58cd2fb2a3f3c03ac02eb272a82"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa470adad0a49fb8d863a31f7a942901ad76014898fb519d0df83215bf4df02db3348d42ffd4dd12c8e2ac0b421994e1b00325ccecfdc0ee8319fa5c135df27fdca2295568890a024178ec4c4b60fe9354c384792f0e61c8949461c8f0f211d19"
- deposit_data_root: "0x2aa0578a29fb670faca20939e663b953e70177df3cc91ba85d38332b4178b9d7"
- eth1_data:
- deposit_root: "0xaedca7ce962cb7ef634eae179f6f58c38f2dc6ea6121c41cdda7ec9438a27514"
- deposit_count: "323"
- block_hash: "0xfa06fa004648cc64acc6bd93a8a309d9494409f073f19d07d8a8221fbcc49635"
- block_height: 324
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x909fdc4a762e835a5b890dc4b1c41ca41b65df75770ac25537840d618375a2b5"
- - "0x2aa0578a29fb670faca20939e663b953e70177df3cc91ba85d38332b4178b9d7"
- deposit_root: "0xaedca7ce962cb7ef634eae179f6f58c38f2dc6ea6121c41cdda7ec9438a27514"
- deposit_count: 323
- execution_block_hash: "0xfa06fa004648cc64acc6bd93a8a309d9494409f073f19d07d8a8221fbcc49635"
- execution_block_height: 324
-- deposit_data:
- pubkey: "0x893f6809ed7bfd91951ba78b29c2eed9e8147ed63f01749380a0b6bba9bfd3c7654f05d2aa77fb7a096b981745615055"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaffa69acb9ec862c2e6a48e490ac305a1f7b9ea17b95c5aa416bb4f8f7682abcb8fd9f1074f989f99b780eeb8ba2f03015f8901fb0b0c2c90570452da90c0ecf591a739d6bf8e6e1ec13ce9d4644a4517e44a8bc923d1688732af77cf4e3a2bd"
- deposit_data_root: "0x5b62379e4f53e1806f256162f584ccac600b1b11d21ea858bcd61d8cea1b168b"
- eth1_data:
- deposit_root: "0x637c3e9b84ad5037a6e90a895f20d1b5ec49a3266ee9e3b3c4c632ce3f3f012b"
- deposit_count: "324"
- block_hash: "0x104902e1b47f88b3220f39f473f2f47d0e5b8f12041e12b6f1796ddaf70b962c"
- block_height: 325
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x829bab24c40bf37b3bed73fa4dd76eca6f03f8cdc0d73ec6decd58c56626fdca"
- deposit_root: "0x637c3e9b84ad5037a6e90a895f20d1b5ec49a3266ee9e3b3c4c632ce3f3f012b"
- deposit_count: 324
- execution_block_hash: "0x104902e1b47f88b3220f39f473f2f47d0e5b8f12041e12b6f1796ddaf70b962c"
- execution_block_height: 325
-- deposit_data:
- pubkey: "0x868207372934c6e8133df3c6a1d4a993cca26a06616d8f3de0c593a4cca3005d6e1a73b41620b05a31eb44841fc20932"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8485459f5c442443a0075bce597ec6428477bc1f2634fe463397f35b39fab15fe876f1d9c22dc0a9eea20a546f92c39f175ff8402decdffda89f03d074d0c6abd9b95ead19f2b015e9cd6637c505131a38f94c0cc1f39e79152ab5fded97d295"
- deposit_data_root: "0xc19bad7ae315d2679d0a9a44b416955031393874ad7d4f86924ab2e7412dd86c"
- eth1_data:
- deposit_root: "0xd7162fb64e8276d1d722de19732d3d13cc63963606dd5afd722c901721b001ad"
- deposit_count: "325"
- block_hash: "0xf56c5c31b8721f20db972d51c8dc999755b33f49f051f8ecc343a6ce30ba1695"
- block_height: 326
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x829bab24c40bf37b3bed73fa4dd76eca6f03f8cdc0d73ec6decd58c56626fdca"
- - "0xc19bad7ae315d2679d0a9a44b416955031393874ad7d4f86924ab2e7412dd86c"
- deposit_root: "0xd7162fb64e8276d1d722de19732d3d13cc63963606dd5afd722c901721b001ad"
- deposit_count: 325
- execution_block_hash: "0xf56c5c31b8721f20db972d51c8dc999755b33f49f051f8ecc343a6ce30ba1695"
- execution_block_height: 326
-- deposit_data:
- pubkey: "0xafa8898fca81793be528c433c00c9838be077b05b7fee5c82c2ff1bea10834f3aae64e2d5b8e3cb3e4a8104127f2b99e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83536ec416710222ad12669bf77c64062b11d01bbf986d900efb37174e45673764941a630a641d4971bcc1ef031bf6110f7f65599ae492f7e2581af7fbe532aae11882007c3f89736eb7c840b21d194f2805e4016b0cb554255ca59343d741ea"
- deposit_data_root: "0x119dec41ef12a9e3fb28da1a750b117e63d1d0f59a65668984336eec709b8061"
- eth1_data:
- deposit_root: "0xa6f2b846a99b787bfd81acf69ffafca4811ab7c97ba50fbd2ddcf2dc508cd5b9"
- deposit_count: "326"
- block_hash: "0x5d0b737eb0d181195028dd01961a295c8e2baaf0d9aefd647bf884032089245e"
- block_height: 327
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x829bab24c40bf37b3bed73fa4dd76eca6f03f8cdc0d73ec6decd58c56626fdca"
- - "0x6352a5698a39b09b04e0d89ee74b46a579de3e4176cb60ec11c6aad278f2e0ce"
- deposit_root: "0xa6f2b846a99b787bfd81acf69ffafca4811ab7c97ba50fbd2ddcf2dc508cd5b9"
- deposit_count: 326
- execution_block_hash: "0x5d0b737eb0d181195028dd01961a295c8e2baaf0d9aefd647bf884032089245e"
- execution_block_height: 327
-- deposit_data:
- pubkey: "0x9685e2fb1018a705d32745ac6bd64d7bc5861679753d5f886a9439c1f8f85cc247b392035fcae82233aa39a6be24515a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d766fcb28fe1c2c80c93cfb974f700b2b413dc9abcf0621f623fc8f7059e7d2ede209c75a426c7cbc264a08435790831645cbf7f6f977d9dde8e1382db0ca6f8d7c153e47c7f9a2bd5afc1c09b2d5a0d60b4c7357fad005c53d6e29ed369d57"
- deposit_data_root: "0xd469915f8ff96a6b4944ac2cfb6cfaf5086b4502819e279ddc3d079da18351a9"
- eth1_data:
- deposit_root: "0xefe013b8db2bc21b289a80f7eac2d726307ff64d7182c92d3c38f8bf5b070ed3"
- deposit_count: "327"
- block_hash: "0x7e26828262c78521add66b854b9f6202f38c1b9425f93b7bbe786da0ca6a9d41"
- block_height: 328
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x829bab24c40bf37b3bed73fa4dd76eca6f03f8cdc0d73ec6decd58c56626fdca"
- - "0x6352a5698a39b09b04e0d89ee74b46a579de3e4176cb60ec11c6aad278f2e0ce"
- - "0xd469915f8ff96a6b4944ac2cfb6cfaf5086b4502819e279ddc3d079da18351a9"
- deposit_root: "0xefe013b8db2bc21b289a80f7eac2d726307ff64d7182c92d3c38f8bf5b070ed3"
- deposit_count: 327
- execution_block_hash: "0x7e26828262c78521add66b854b9f6202f38c1b9425f93b7bbe786da0ca6a9d41"
- execution_block_height: 328
-- deposit_data:
- pubkey: "0xb41c965012fdbf74f551e0a1372202f5814cedfe541336f5954020ee2ef23043efa6baa200cbd22b34acc5462ca3e9cd"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x86db0292465a7a813f4e6da0d9dc4df20852b088a096b5b569251f544f4e98d2e3125926f1ed97fbcddc356de8461ca1173e9466d181b5f7fc63f772313bc3bb5e37b681c845b5cec8954762565b0614c0413da52147e461bda26ac718afd166"
- deposit_data_root: "0x2a5c7ed2c0ef2938c1edeaa39bbe965c3b7ddfbf544553892c02c2b502c19f33"
- eth1_data:
- deposit_root: "0xa7a049ceb8533aaaee37c8540f1ad14e400ce325de95ef3ff6d9a5a30277aa80"
- deposit_count: "328"
- block_hash: "0x7368b2a4ec10255ec111a7b79ef69efee937e637da93706c68907df2eb5ec722"
- block_height: 329
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- deposit_root: "0xa7a049ceb8533aaaee37c8540f1ad14e400ce325de95ef3ff6d9a5a30277aa80"
- deposit_count: 328
- execution_block_hash: "0x7368b2a4ec10255ec111a7b79ef69efee937e637da93706c68907df2eb5ec722"
- execution_block_height: 329
-- deposit_data:
- pubkey: "0xa8a7015ac1ac3ec6678478167302dade9eedced09f899a60decc8060f972141a88be910f959aa155cceea322f375ae72"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3b80ecbaf373ff93624739d4fe040d037ebcf3ef906b294b3b908325547aa217b930b0663b2d9589aab52084a028b370c455a452f4ca2ac2156bc7f4283f96c1b3a770d05d9570dfd57844142aa167091359e2a2364de250d22ba06533e4736"
- deposit_data_root: "0x59397bf83c3fc9c58074f1e8139affd9df65b46dd060f498562079145f499f34"
- eth1_data:
- deposit_root: "0x638a7dd7929e0e9ce2efd35226d44a66c555379ddb234e778244064ed44fb3a1"
- deposit_count: "329"
- block_hash: "0x32438de8960d5072d117ed3497e8c3ae169df2c634103b6e708bc04bce0de62c"
- block_height: 330
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0x59397bf83c3fc9c58074f1e8139affd9df65b46dd060f498562079145f499f34"
- deposit_root: "0x638a7dd7929e0e9ce2efd35226d44a66c555379ddb234e778244064ed44fb3a1"
- deposit_count: 329
- execution_block_hash: "0x32438de8960d5072d117ed3497e8c3ae169df2c634103b6e708bc04bce0de62c"
- execution_block_height: 330
-- deposit_data:
- pubkey: "0x83a7860b2ff27518453860637b50ed63adfbda9a2f36432e949268cdbd5a6cc10985acf9bbb57391393823d71328c85a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x973582f2e9868c13e6f8f5bf798e2111c785281e0659e1adce01524406daaa5d2da5a70c141e84da6891941b632a22af157d1239c5d8a03dbdea8157d7c3f86cd0b316ce06150e18986aca9c84740b1a389bd60234e8f95c9a3d5bcd7f4ca6b1"
- deposit_data_root: "0x249592161dbff13774225e1fb6d8a41c4bdc86213ff6ad2fd5bfaa0b4c9b814d"
- eth1_data:
- deposit_root: "0x2676fba7f7791a8dc588e76fda0a40390988f860b6fcf543d91bdaab3f889344"
- deposit_count: "330"
- block_hash: "0x1c1926c17a2879fb7535863b86d080bfdb32f0213e74ba6895ab8801771bb20a"
- block_height: 331
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0x491c63b1a2fc1989cb6be00597134cd056a4ccbcc142850c5834a24da3a58686"
- deposit_root: "0x2676fba7f7791a8dc588e76fda0a40390988f860b6fcf543d91bdaab3f889344"
- deposit_count: 330
- execution_block_hash: "0x1c1926c17a2879fb7535863b86d080bfdb32f0213e74ba6895ab8801771bb20a"
- execution_block_height: 331
-- deposit_data:
- pubkey: "0xb7458d704a414e012c62a3d19c27da6b0ed9dc77dbc1a328e736043e156eef0af395853ba915bb246a2a4178febc7ad9"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d51031827dc04649b8825a745eb56f32168064ec6efeadbf8e6d639b21e826ef5c61f890e816bfc66e87bbf85759d240d9c5a95d602ec1ba173fca94959c3a84b164b1d7bc6098bcdead65318f9900c79f9cda30584fd450914613cd174b425"
- deposit_data_root: "0x579accbbe17b59ac71d9923a7cf7b851ccfd509caeb9fccda56c538dacf1744e"
- eth1_data:
- deposit_root: "0x24d257c531f4a7c0979f1778496a0e422e76f120dd5e6f97af72ba9c19b30369"
- deposit_count: "331"
- block_hash: "0x5d1c3942268956fbe23bac62b814488414664aaeff9a047078a2790f0ccbec6d"
- block_height: 332
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0x491c63b1a2fc1989cb6be00597134cd056a4ccbcc142850c5834a24da3a58686"
- - "0x579accbbe17b59ac71d9923a7cf7b851ccfd509caeb9fccda56c538dacf1744e"
- deposit_root: "0x24d257c531f4a7c0979f1778496a0e422e76f120dd5e6f97af72ba9c19b30369"
- deposit_count: 331
- execution_block_hash: "0x5d1c3942268956fbe23bac62b814488414664aaeff9a047078a2790f0ccbec6d"
- execution_block_height: 332
-- deposit_data:
- pubkey: "0x8a6785d9912cb5be712bf51c08da89f9a3c7942869176d1a24f114f430715064f48c35d37c1c1d1eb9b9322ecfdcedb0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa19c204bfe842f321b5eb4921bfeaaf7275ccbe56531bff038b7e534ab98b13179245d804cbfe08eaa635b1f0c9271ed09754a00cbc617ce22610a78c7a621e92be914288e5412bf2568f784273c59e3d2a529c45c72689a2817a19489fdc109"
- deposit_data_root: "0x3998111d43f8546fc032329d81489551501ccd9b835b0c738866336f442f675f"
- eth1_data:
- deposit_root: "0xcf48923ed77d78c9655d703dc1920f4824c269dd652f2999757e589abbad0247"
- deposit_count: "332"
- block_hash: "0xa0bbc1be8518265a9f0c090c6a3011529e0066b978151c1751962b6ee6439fe5"
- block_height: 333
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0xfad232bae67341101a570b10f6192e9d46fd997037d7350c72506c8ff80f9c2e"
- deposit_root: "0xcf48923ed77d78c9655d703dc1920f4824c269dd652f2999757e589abbad0247"
- deposit_count: 332
- execution_block_hash: "0xa0bbc1be8518265a9f0c090c6a3011529e0066b978151c1751962b6ee6439fe5"
- execution_block_height: 333
-- deposit_data:
- pubkey: "0xb855cac3f2635d485914e4b25b953b066dd5942215b38677d16d3fa6aac5b7f8d0849398ef946674e88514fc83c42491"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa1a4a04d87aa7051d721623609478467070098d8ee9310292a5c98ce5c49185d2fbeb8225a964906f23b4b8d864a47dc0025a10d94953de9b4846ed342fc3e97485d278f9c286417a54eee5496b9f3c1f1e51cfd3396688931f888c241f95552"
- deposit_data_root: "0x6566a16b18a8c515bff85c5cfaa9d0dd7873c39afd6a50e7655d15198fc3d37f"
- eth1_data:
- deposit_root: "0x601f76fb38837cf4733da9f152e37859b1be5e1d18d341ca181b87df6b56320c"
- deposit_count: "333"
- block_hash: "0x2b03e78da06e7a66393fa47a4713ecd2f0eb79a016ad42e2e57350e9a6c1340d"
- block_height: 334
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0xfad232bae67341101a570b10f6192e9d46fd997037d7350c72506c8ff80f9c2e"
- - "0x6566a16b18a8c515bff85c5cfaa9d0dd7873c39afd6a50e7655d15198fc3d37f"
- deposit_root: "0x601f76fb38837cf4733da9f152e37859b1be5e1d18d341ca181b87df6b56320c"
- deposit_count: 333
- execution_block_hash: "0x2b03e78da06e7a66393fa47a4713ecd2f0eb79a016ad42e2e57350e9a6c1340d"
- execution_block_height: 334
-- deposit_data:
- pubkey: "0xae8aa6029e2318a91b3b6ff77e2792905a690d7ad0ac1f97a7887ca4891642d267b7e208f6bddf407fd8c4e10caab2a5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9077969feb76785e0c70a27f1cbbe4ddf95a0d492ded0730d542b4efd8194b44761f9af983f5169a3b04894db5ec0b620f20b332626a3a41451bd2fa7699750a7422b7c3adb2886bf009cc361b35ecea393d2e6539f16af3cc29b12adc52b007"
- deposit_data_root: "0x212acb543447a951ec9bc344e0dd2816b7cf8292ed26e09341b39c463bf2c1d7"
- eth1_data:
- deposit_root: "0x17ad9aa2ffcb568adfee07a4ea93693926ef5e196f325c0c0b1e282433e2526e"
- deposit_count: "334"
- block_hash: "0xeac3f8860c586f736f0bfbb5132027e74d76b0060a0751e96ffee1d90eb57707"
- block_height: 335
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0xfad232bae67341101a570b10f6192e9d46fd997037d7350c72506c8ff80f9c2e"
- - "0x98ad3ff4a62e454b2468ff55af20008d2d05198840dd8fa50ef9c637bf07086a"
- deposit_root: "0x17ad9aa2ffcb568adfee07a4ea93693926ef5e196f325c0c0b1e282433e2526e"
- deposit_count: 334
- execution_block_hash: "0xeac3f8860c586f736f0bfbb5132027e74d76b0060a0751e96ffee1d90eb57707"
- execution_block_height: 335
-- deposit_data:
- pubkey: "0x98a5e4ffd62c3b8eb39f6230d242efb74701f42380663af26fcbf106ad1b0f02339aa6d9eb5f2f073b01f2c85062d89c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa611b0ecfe36d86f891951236a218d1f9a64abd697b4e861b2c8849b6b9b1f23287dfdfa1c2c45ca6fec8dae2e1163d1022836eb27982c328955eff7643e031c407ed8629b8c39c8d30bf3b115d0629baa493ead81959b962e42c4ea44b69403"
- deposit_data_root: "0x4b2e8ce40e43537b4a92f303966172fa604c02f1c1747d558f561c4a9915e649"
- eth1_data:
- deposit_root: "0x6b407936ac387168556937334d1fd4d42efc8b83e2979abc7b9440264dd81e8f"
- deposit_count: "335"
- block_hash: "0x642c02da32878eeec84d0c17ff498fba2173c61acf4f268b1f4d937a8261d92e"
- block_height: 336
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x68037963cd0454c7fca9c176f22dd9e308d606acf005cb7b2c5c800b9d443189"
- - "0xfad232bae67341101a570b10f6192e9d46fd997037d7350c72506c8ff80f9c2e"
- - "0x98ad3ff4a62e454b2468ff55af20008d2d05198840dd8fa50ef9c637bf07086a"
- - "0x4b2e8ce40e43537b4a92f303966172fa604c02f1c1747d558f561c4a9915e649"
- deposit_root: "0x6b407936ac387168556937334d1fd4d42efc8b83e2979abc7b9440264dd81e8f"
- deposit_count: 335
- execution_block_hash: "0x642c02da32878eeec84d0c17ff498fba2173c61acf4f268b1f4d937a8261d92e"
- execution_block_height: 336
-- deposit_data:
- pubkey: "0xa7723c37795ac53e3ebc25b9dd55af10080490e872a18724b0bd3c7fecf8ab18f7d6abd1b49bc755048a3f9b1bb136ed"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x82d29cd5f8a497b898dcf8d03b7b4e43e2ab362898d80f1b8cedfce878eda388aab81dd2249c4ea11f0359ca666ecdcf12dc23fb637063a23a42f6f0140d74040faf4cedf86ffde4d4ad31a3115a652c53e3e69b8c6041341976bba45451319b"
- deposit_data_root: "0xaafd33e6d9e12cd2b3c9b01a65440dd47914a24fa5ec0a54f1a8fdc04d2a4cce"
- eth1_data:
- deposit_root: "0xb16b2f7f6c0d8dad74c340492d57d24b032a221ae10d86ee1525f0221fcc690f"
- deposit_count: "336"
- block_hash: "0x0671e4bb3a224e145648e03b323fc2034eae6d285f280842370bffc9b75211b8"
- block_height: 337
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- deposit_root: "0xb16b2f7f6c0d8dad74c340492d57d24b032a221ae10d86ee1525f0221fcc690f"
- deposit_count: 336
- execution_block_hash: "0x0671e4bb3a224e145648e03b323fc2034eae6d285f280842370bffc9b75211b8"
- execution_block_height: 337
-- deposit_data:
- pubkey: "0x865f9a725b49135bae6c011f778bb311a514a73911924e4630a5fedac29e1b4d127308ac8b0d623e7f246c668b827f35"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x98df5e77c8ea74dcc876e84a85bfb829d3f8e6349e1295daae0f7817e47d62788ef5509ef4c7cfe12ca4928c2f8708380b880cff39db85f02a3ae414529cf8ea708d745cdffaec6785a09f78e31a38b6eda8a1849c987e16a896d1fac4baa936"
- deposit_data_root: "0x4c1a708c3fd48341741103c34da6335e37373ce7706ce809aaac4ac88d1a8253"
- eth1_data:
- deposit_root: "0x796573ea2cfd71631491eb7a44bfd33ad6d1be1b3e446549409773724d8990ff"
- deposit_count: "337"
- block_hash: "0x76f57ebaa44d6bf4b4edd91f646b8f872bc1386822617d4e438412858e69fd19"
- block_height: 338
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x4c1a708c3fd48341741103c34da6335e37373ce7706ce809aaac4ac88d1a8253"
- deposit_root: "0x796573ea2cfd71631491eb7a44bfd33ad6d1be1b3e446549409773724d8990ff"
- deposit_count: 337
- execution_block_hash: "0x76f57ebaa44d6bf4b4edd91f646b8f872bc1386822617d4e438412858e69fd19"
- execution_block_height: 338
-- deposit_data:
- pubkey: "0xa663aaabc4aae867b7bc4feb03558f9c906be74fbd1cfa931b88191a1817c8393778ef45b5cb107cbf860e9cce540212"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b7e2a3f92460dfc0e12f13ae76c2949a08fb6407ef52ca0b5059def233c0764955401253ef03f2bed3fc6feea5a09f008969ab976cfaf7a649a930b552285f4441f0d06c0234b81ee37dbf8eac19a50c8276979ade3c7bf773249a45c477e31"
- deposit_data_root: "0x1500846f0a4b55b0ed41b84c3028f1df35be19bb4f82dd1a84c6b5fde4d9dc21"
- eth1_data:
- deposit_root: "0x955590f03dfa34324c77e65b555d2dab80e5d4da4594deb99c7564eed667b840"
- deposit_count: "338"
- block_hash: "0x1d34b11fbd4c5364cd26c59d0d39dab70bb4406ab876409eb98a505f474c12ab"
- block_height: 339
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x02937359af82fb5ab508a78d0a5455edc12d42abc01d457cb808ae23ffe4f3b9"
- deposit_root: "0x955590f03dfa34324c77e65b555d2dab80e5d4da4594deb99c7564eed667b840"
- deposit_count: 338
- execution_block_hash: "0x1d34b11fbd4c5364cd26c59d0d39dab70bb4406ab876409eb98a505f474c12ab"
- execution_block_height: 339
-- deposit_data:
- pubkey: "0x970d2002cd899a503a0a007d6b5cc6f8ea9fc7e7db1de06b5297daa7f365d066e69cfd179197229508bdf93161904330"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb286275d11239f69f057de9e85f5f26466f0b316dd0a904a4ea87def5aec3808f7c5379d8303666902819449fab7efab1564ee7e1fabddb6f475530fee84042b76ccff7eb8a1c4788fef17ce15aba2ecdf8aac1ba25af4f9c47bf66491dc6e4d"
- deposit_data_root: "0x7fd3c53f7f63b048832cf0492598920d87f4a205dbd16e53c4bb6bc9c9c9d43e"
- eth1_data:
- deposit_root: "0xf75235a060b1c539b96b12e4d23245f341777cac99f556f4d686c0cf44688538"
- deposit_count: "339"
- block_hash: "0xaedd455c7e89005ce8a0cd34b997eb55456eb21d7dfd08b0c1978717614285af"
- block_height: 340
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x02937359af82fb5ab508a78d0a5455edc12d42abc01d457cb808ae23ffe4f3b9"
- - "0x7fd3c53f7f63b048832cf0492598920d87f4a205dbd16e53c4bb6bc9c9c9d43e"
- deposit_root: "0xf75235a060b1c539b96b12e4d23245f341777cac99f556f4d686c0cf44688538"
- deposit_count: 339
- execution_block_hash: "0xaedd455c7e89005ce8a0cd34b997eb55456eb21d7dfd08b0c1978717614285af"
- execution_block_height: 340
-- deposit_data:
- pubkey: "0x81fc32376cd95ab4456f645030a9ccba182da956571ee1136916fe655c8bf08f05244e204bfbc87f696472b3cf3bab83"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8e625f0c45db2539e488bd2272774e46699e690e45fd6e88fa42204d9798a24aa1ea432498172c25671d65450b2ff8d008bc9d87276592803f9568cd46e4d46e1da49db778158256fdc10d8e4dede5194cc51d684887f31a4ff2725113deff26"
- deposit_data_root: "0x8d6754cda9a15e4c2b26cd6c030a76af60e0dec4e17a008f30164ed9ba746cff"
- eth1_data:
- deposit_root: "0xcb7ce227d926f427218766a5fca5311ec8111498381867d4fa68212857ec0e41"
- deposit_count: "340"
- block_hash: "0xdc73d2399512a4f010ac368d10034f9ec2ca191af40dc0be3c768a0c56bcf02b"
- block_height: 341
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x691d6c3d1788448165cd972951b94cca4485afc7571864393cb986aca78a99bb"
- deposit_root: "0xcb7ce227d926f427218766a5fca5311ec8111498381867d4fa68212857ec0e41"
- deposit_count: 340
- execution_block_hash: "0xdc73d2399512a4f010ac368d10034f9ec2ca191af40dc0be3c768a0c56bcf02b"
- execution_block_height: 341
-- deposit_data:
- pubkey: "0xa42f4e4ec8732b5a4fbffea9e17a6c208db024f36a899f90671b1910a1dff4b18996b517050f4aacb548640bdf8fe844"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa9bd07d645a9db4c36bf8bb92478ee618c92414a1619a04cf6d39f5ca4fe37fed016b0332d9e9ba62247180f26b001d40c7ffdd2522fa4316e5f1980b14259b279e98da54c01a65d1355d6ba3e827b36476854eef5fce97f01690bd45c9eb7bc"
- deposit_data_root: "0x0cb2bb82034b6d90b373320449a801ae41fdc49cb4610e8bde86a2073cf91e3b"
- eth1_data:
- deposit_root: "0xc8efa837e5b208a1252d1c5caa6e2da3377532093f952df3d8a655cf0960144c"
- deposit_count: "341"
- block_hash: "0x281cce8e3af1cba285ad4a6533cbbdd4b16f7c646351d2594c47a54d84685a01"
- block_height: 342
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x691d6c3d1788448165cd972951b94cca4485afc7571864393cb986aca78a99bb"
- - "0x0cb2bb82034b6d90b373320449a801ae41fdc49cb4610e8bde86a2073cf91e3b"
- deposit_root: "0xc8efa837e5b208a1252d1c5caa6e2da3377532093f952df3d8a655cf0960144c"
- deposit_count: 341
- execution_block_hash: "0x281cce8e3af1cba285ad4a6533cbbdd4b16f7c646351d2594c47a54d84685a01"
- execution_block_height: 342
-- deposit_data:
- pubkey: "0xb4368a6946801366550e764247f27c24bed3c5830a49be21ddeee79a67d71e0aff3d5cc0a9b1e18bad5c9e655ad23502"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4e0e77af815e173a20d602fbc5148918012820754d736dd34549761392b3d8a81af062830ee3d851125ae056201dbab1246b20bbe4d92a3e11f913fff280acefb6dd64508591e1ab9b02a300bad6ebb54e205c80923d892a8db4564c3945856"
- deposit_data_root: "0x3c15bff5b52d7d846681e0cd70606a0ee32b276c9408b42601fde515b35f196b"
- eth1_data:
- deposit_root: "0xa10f1b573d7d012d556954b1fb79a14483d8d45db59f475f2ed8bd0dd38a2f79"
- deposit_count: "342"
- block_hash: "0xfcef96a865323635b735de16d7a4e79e58e00efb50920ae9b7f55cbec4dc42c4"
- block_height: 343
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x691d6c3d1788448165cd972951b94cca4485afc7571864393cb986aca78a99bb"
- - "0xe8c655eec2a2badc6e31a521cd3847d22c7d67433e11aa8304ba846ef1b4616e"
- deposit_root: "0xa10f1b573d7d012d556954b1fb79a14483d8d45db59f475f2ed8bd0dd38a2f79"
- deposit_count: 342
- execution_block_hash: "0xfcef96a865323635b735de16d7a4e79e58e00efb50920ae9b7f55cbec4dc42c4"
- execution_block_height: 343
-- deposit_data:
- pubkey: "0xa4a216ff9a365d29e027a557ae3d4f52bf4fa11654c4314d65a319810fd799c8fb2d129692d7d68f6c134cde9de5d2c6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb62b67e03a9b18faa69f527953e53ca8dc3c14ff793e274314c0495118e52e01651bf43cbce50daf8c93756a43a32f6d10f697c1a37842f1def52372e984fab30010f35b5105f1079563979690d46edc71c80fa6bae135b49a2d7b0a01aad0bd"
- deposit_data_root: "0x0f433740b767093be9a8d4e8ee049901f378187296b76b352595542022e6bc19"
- eth1_data:
- deposit_root: "0x0cccf3ad07bb6129c55118f363f08f6a7eab37150d087d713ab9e4b93c9e3825"
- deposit_count: "343"
- block_hash: "0xfa34f90576211ca0acfb7db7cbf1529ddb54a8f319986a7c133b79e15c65f945"
- block_height: 344
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x691d6c3d1788448165cd972951b94cca4485afc7571864393cb986aca78a99bb"
- - "0xe8c655eec2a2badc6e31a521cd3847d22c7d67433e11aa8304ba846ef1b4616e"
- - "0x0f433740b767093be9a8d4e8ee049901f378187296b76b352595542022e6bc19"
- deposit_root: "0x0cccf3ad07bb6129c55118f363f08f6a7eab37150d087d713ab9e4b93c9e3825"
- deposit_count: 343
- execution_block_hash: "0xfa34f90576211ca0acfb7db7cbf1529ddb54a8f319986a7c133b79e15c65f945"
- execution_block_height: 344
-- deposit_data:
- pubkey: "0xa814035503cb1adcfdef259521573a5193dfa1e8d74e22649ad1b2b01a44fc6c2352100bc42d6c48584ff1d3a430537d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c4f917adb8706a169c9f93c6bbe2186fd84a81e86f9adaec27391a485afc8e9130f5d940129208437ac6be31ddb50b50eeefceb47751b664ff119be7aee930df8bff802a819c3e9d08e0cc453b7544bc8089b8b9f63c8dc7e2411d997aaecaa"
- deposit_data_root: "0xea73c129f0be1b4bb10e06fbbe409b22e94e0e4ad06411ee5ef1142fd61b3c64"
- eth1_data:
- deposit_root: "0x5a82e52a1ed416eee15a1c097092f7518b4c53a89bf44c76046cbdb4866aee0d"
- deposit_count: "344"
- block_hash: "0x625d21649e1542510b4fa7f2570067aec4ecdbaade993f1b33f7fc0448ada465"
- block_height: 345
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- deposit_root: "0x5a82e52a1ed416eee15a1c097092f7518b4c53a89bf44c76046cbdb4866aee0d"
- deposit_count: 344
- execution_block_hash: "0x625d21649e1542510b4fa7f2570067aec4ecdbaade993f1b33f7fc0448ada465"
- execution_block_height: 345
-- deposit_data:
- pubkey: "0xaaa334a2fb779ce6de3c557025ff9bf17243deb3f09a37f6719356b54afd9be09a7b82cd589758779544a08cfd3ed5cc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x951f84c57cf1242ce760108e8b5e6ab1b9ea7bbf8ce40198f6a10f2d55838320c9f6e0c2bed2d9eaa4aa3837a9394fcd1562efaa6daeb5b8e0b183924d9786bd2eb94b31952577611f3e1eec834e44fcfab0cacec4632aba7d1ba5a15880f339"
- deposit_data_root: "0xb6d2d582e7c0f6d7dab60416797b7c84771fe30cb380b25be8c6c0ca12d7c54c"
- eth1_data:
- deposit_root: "0x9c2315289da9d6fa488347b4856f84fe558e5e7e186b44256496a538a126f880"
- deposit_count: "345"
- block_hash: "0x51046db7f7057439306e943428b8271dceee739b9c2473f00c516959dbec5bfe"
- block_height: 346
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0xb6d2d582e7c0f6d7dab60416797b7c84771fe30cb380b25be8c6c0ca12d7c54c"
- deposit_root: "0x9c2315289da9d6fa488347b4856f84fe558e5e7e186b44256496a538a126f880"
- deposit_count: 345
- execution_block_hash: "0x51046db7f7057439306e943428b8271dceee739b9c2473f00c516959dbec5bfe"
- execution_block_height: 346
-- deposit_data:
- pubkey: "0xaac004b4b25584ba8c906671196db57d7a4f159cfb430b1590d61d94c5c22cb694c25bb6ee850421db260d063e096145"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac4f0ad93d329006d74a5e51870edd9038900d3e080f74ad8e3362fff86e616566dde3416b752f7b900e235bcf01f58b06862f9678a0dd11d481224afdca5ee9fdaff661e74b4cb70cefb7f691b76a822fa278008f9b611ba9cbb5a0234ccff9"
- deposit_data_root: "0x8b7c5eb357e9e4abb96dc68302fa6e93c3067abd623b9338a1afa7ac8e16d63b"
- eth1_data:
- deposit_root: "0x5ce81fb6b5ba660b0fd450e1c1d8ce22f1b02dbfa8d4f1df5062d70e3aeb66e4"
- deposit_count: "346"
- block_hash: "0x51050db6a05c59f2dfcdf79b39dc420a5d52ad575ce0f08b436f6ea02325d0fe"
- block_height: 347
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x5a89c435553780c594308fa4372c85b8ac39ab611cbdd7ada19bb99116c7cb4f"
- deposit_root: "0x5ce81fb6b5ba660b0fd450e1c1d8ce22f1b02dbfa8d4f1df5062d70e3aeb66e4"
- deposit_count: 346
- execution_block_hash: "0x51050db6a05c59f2dfcdf79b39dc420a5d52ad575ce0f08b436f6ea02325d0fe"
- execution_block_height: 347
-- deposit_data:
- pubkey: "0xad7b6b1ba1f7950cc8e2b5b0cb9041666361eb023b1deff783420482970cf58213497d64cfc91cf06762dd511b0aac31"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5abc0b6d2aeeb6156bd77d50cb67115abe5b519e46a9275f60d02128e2048da62556ff24746037f710a4d5cae3d924c1916f896829525603a9c8a4f7c737c7e9255344686fdb590bf8dc9a6ed3e4803727ace8ac5346cdc650aaf87444cf316"
- deposit_data_root: "0xcca6725f342e727e05d46aacf15407b225f054ee8edcde7c1e46554ab4d258d8"
- eth1_data:
- deposit_root: "0x46aad6ffcc251664c097e6d284162dc501d4d1625ac3585cc2bee8bee47ad946"
- deposit_count: "347"
- block_hash: "0x9660d6f0d6d69745bc825562e29c177a86f4ce447e9d90f417f66696454551b2"
- block_height: 348
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x5a89c435553780c594308fa4372c85b8ac39ab611cbdd7ada19bb99116c7cb4f"
- - "0xcca6725f342e727e05d46aacf15407b225f054ee8edcde7c1e46554ab4d258d8"
- deposit_root: "0x46aad6ffcc251664c097e6d284162dc501d4d1625ac3585cc2bee8bee47ad946"
- deposit_count: 347
- execution_block_hash: "0x9660d6f0d6d69745bc825562e29c177a86f4ce447e9d90f417f66696454551b2"
- execution_block_height: 348
-- deposit_data:
- pubkey: "0x846f3af6ac23b648a5ea3cdb60b2086e18e42b2837a9d689625af534792f9489a1b22cab64476533993f34149fed1a0b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae4c2827395dc47a9303a2ec5f5337b5fadb67e813e4bdf0bee32ea1f0a0377e50f1f381313d4d8db576797ce1f1edbc1924e110278ce87761774b7fa6250f81f0563a2c757ce24b7e57143a396087a2a14dae9f06c2787cfb247e8726df18f3"
- deposit_data_root: "0xb6be3a5becdd7330a4e3fe5176fc77cc1cc107629421a6c373ccf5cf89d12546"
- eth1_data:
- deposit_root: "0x473a9d413c0619796c3ffa906b9ba7774339cc08d3f30d468d868ac3ea1fef6e"
- deposit_count: "348"
- block_hash: "0x25df98dc1923be776e2e9732e5e667a77f6dee8af43bc1f198dcd43025da3589"
- block_height: 349
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x08b50aac114125944b1e0be249589266d73343598f6094b9e13f1c04c4f895fe"
- deposit_root: "0x473a9d413c0619796c3ffa906b9ba7774339cc08d3f30d468d868ac3ea1fef6e"
- deposit_count: 348
- execution_block_hash: "0x25df98dc1923be776e2e9732e5e667a77f6dee8af43bc1f198dcd43025da3589"
- execution_block_height: 349
-- deposit_data:
- pubkey: "0xa8784f36c1a8c6e739b090d982480712ff04c9231190b97121c86c84a35cbd561d3372902017ea71fb99ce2a6582f362"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaff0df82cd7d8b804a9f5f62f493936e0d77be3631c1f0d9d295dac98c3d019f534774519582503694a723820031ddb8184de493e5df34c2fb875ee4a0be4c82571b6623546b666d1ce1c539175662b42dc963e6205a243d758f7e1e6c040449"
- deposit_data_root: "0x8920aa96089e1b189ba5b62754537f9ae53cf2e3f6d0d9c18385bc2566712a24"
- eth1_data:
- deposit_root: "0x69b38abb0d6cb1a2914ed20b9c04e2110e2374dcae202360845a9f730e2005b4"
- deposit_count: "349"
- block_hash: "0x74905823b1a94f841f1763c2b21604f9ddd31727e12a0c4405a50b70903c105d"
- block_height: 350
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x08b50aac114125944b1e0be249589266d73343598f6094b9e13f1c04c4f895fe"
- - "0x8920aa96089e1b189ba5b62754537f9ae53cf2e3f6d0d9c18385bc2566712a24"
- deposit_root: "0x69b38abb0d6cb1a2914ed20b9c04e2110e2374dcae202360845a9f730e2005b4"
- deposit_count: 349
- execution_block_hash: "0x74905823b1a94f841f1763c2b21604f9ddd31727e12a0c4405a50b70903c105d"
- execution_block_height: 350
-- deposit_data:
- pubkey: "0xa398c76ca4aff66b20dfea97e1bbea311a5491b6de44cbcc979bd368818eaef834f188ad6fb413c3120b1af141637cdc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb345cf97868f004b66e78cce43b072e515e647c10b7a06970bf335d4eb67d423977bcbae4ddd3479fc243117a639443a0f730fa27c9173a1fe9c1a336d99aad931e813fc84f11112453bae446b01a363f5a8962bb2fda2957f5cadd0bdbcc840"
- deposit_data_root: "0xe1e4024334ffdcc89d3c6bb0f633afb6b8cf63e1bf0624dd29e980035a80b1e1"
- eth1_data:
- deposit_root: "0x249ae18bac8cbeb1bfb2970234b73368a09d8a2ed6fab14c1a0608887b22c95f"
- deposit_count: "350"
- block_hash: "0xe55ef2c7c927098d257769da87f33354267c4f720bd31ee699cae6fe6c23b9ab"
- block_height: 351
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x08b50aac114125944b1e0be249589266d73343598f6094b9e13f1c04c4f895fe"
- - "0x540b74da4539ce3fc72ade01431e3b30606bc85b85cc5cba0c12c3a166746e9b"
- deposit_root: "0x249ae18bac8cbeb1bfb2970234b73368a09d8a2ed6fab14c1a0608887b22c95f"
- deposit_count: 350
- execution_block_hash: "0xe55ef2c7c927098d257769da87f33354267c4f720bd31ee699cae6fe6c23b9ab"
- execution_block_height: 351
-- deposit_data:
- pubkey: "0xaf54a32535604e042dc5a7e296a762f3ddc1fe00741eda9acb8f54be49a8244750d6d8f15a10d9384afbd26bccb662af"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa6286e34d6eabfd35e2e69f1541ce7574229d152a95b693b1073874d7505399babd68b1e5d373c5e3a60bb85360d43a51715914324b85b6d52ecb42f129bb1658959ee201c581e717a1ec40e281fa2ba26e2d93f1def180d2d13a58ff9b875e4"
- deposit_data_root: "0xb1c68778c0ec68fe070016e011f0efe683dcf0d5ccc5ce4a41506027de9409ab"
- eth1_data:
- deposit_root: "0xf653f23a48facb6c1c9b5d7df3387f77ed798e75556b335237fcfe8e40e6832b"
- deposit_count: "351"
- block_hash: "0x22fbc60289a0213fd65514e255963d148ffac49400e25fc2fec770a6abc36890"
- block_height: 352
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2be3d691d07573381ecaa9be38f015a03ca00046e7433389a53d83968989b137"
- - "0x61af53fab3c4897138fbefac5b631a96d505678a097ecfe9a2f9a7905c8d9683"
- - "0x08b50aac114125944b1e0be249589266d73343598f6094b9e13f1c04c4f895fe"
- - "0x540b74da4539ce3fc72ade01431e3b30606bc85b85cc5cba0c12c3a166746e9b"
- - "0xb1c68778c0ec68fe070016e011f0efe683dcf0d5ccc5ce4a41506027de9409ab"
- deposit_root: "0xf653f23a48facb6c1c9b5d7df3387f77ed798e75556b335237fcfe8e40e6832b"
- deposit_count: 351
- execution_block_hash: "0x22fbc60289a0213fd65514e255963d148ffac49400e25fc2fec770a6abc36890"
- execution_block_height: 352
-- deposit_data:
- pubkey: "0xaa41628c60365750c75cf91a8d4097047d61c624b01d4f298ac90a66409cada1bb99cf42a2577ba173a94745dd73d6d2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96b47d0a7ea06103c1ccf89698c71e8e05bb361aa564c6a0ddde8cb35ca0827d4c6fc03ef762f9f8919907deb4b7e2c10210757f9a0e03c7edc7e93afe48c3049841940bb352d015fcc404dd065d9aa947aba87074344fa29e126d83165f9e10"
- deposit_data_root: "0x5809f4140599df5900ef54b70e678188108fcb84993cdf92f63734e016683a36"
- eth1_data:
- deposit_root: "0x8fbfbcd57a3f6f5dc37eb7ec56d7e273892dc5e321c1365d220becc4ae65eda2"
- deposit_count: "352"
- block_hash: "0x5fa4ed804971ad0bc19fd3038282bb697dca9c7aaca9b413f54fb261e843352e"
- block_height: 353
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- deposit_root: "0x8fbfbcd57a3f6f5dc37eb7ec56d7e273892dc5e321c1365d220becc4ae65eda2"
- deposit_count: 352
- execution_block_hash: "0x5fa4ed804971ad0bc19fd3038282bb697dca9c7aaca9b413f54fb261e843352e"
- execution_block_height: 353
-- deposit_data:
- pubkey: "0xa4623cedd189249799b7c9afb49960dd86f31572a6edd594dc9d147bd11b368b66afaff6a2dcdecfa873f88991e5a8d6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa53f69cf2e224bfff70ba77e95b49525e4222ff8f3967a79bcc6244995e48501db0556fc79fba5fb32bcf1cf45c1ba8f17c0eb25eb5fbffc63344807e2627b49e03f8d8e8e9017c0a65f35702f2353eb576141fb10970655d63ac5d89a2e87b8"
- deposit_data_root: "0x79ac2faba3df339c9a4c1035da2b4319b9b6e007a70479b528b6eb6008281e2a"
- eth1_data:
- deposit_root: "0x3d14a58b5cbc0e3146ad1778955f955c855ae299c4dbb24494e291aac4bca411"
- deposit_count: "353"
- block_hash: "0xd45a6c4a1391e32940ab1a47bde642ebbeb12849a6909615c317474252c04075"
- block_height: 354
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x79ac2faba3df339c9a4c1035da2b4319b9b6e007a70479b528b6eb6008281e2a"
- deposit_root: "0x3d14a58b5cbc0e3146ad1778955f955c855ae299c4dbb24494e291aac4bca411"
- deposit_count: 353
- execution_block_hash: "0xd45a6c4a1391e32940ab1a47bde642ebbeb12849a6909615c317474252c04075"
- execution_block_height: 354
-- deposit_data:
- pubkey: "0xa58a5d3d29c1331b6f4f977ee08afdf95c067db26c21a591b15db682f93d223acd4e031c98434ec7be34922496ec8ec1"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b2019cbdc2fb49df3257128d61a4e0fa63f451b09a86ef0e5b3084d42a7647d076f03771c996322ce65a4ee05a9bbbc0e7a108e2b816bdb39db1ebe2cc10856864cd8dfa2a042d42fed42236d88b37ef286bff4c5e3176140f140773ccd5505"
- deposit_data_root: "0x4e2e9ae16bcb8f83129a723e664b4e2d1dbb436655d0c2bfcacf416ca71b3bd0"
- eth1_data:
- deposit_root: "0xfc17404478ee17d526ec0e6d7b7f392f0cd2edf08cd20ea72a6b7cafb0bc5d1b"
- deposit_count: "354"
- block_hash: "0x48e867e23f93afbce5c768c3e7b24afc6f67bbf23b03ed35f673daaa22e150cb"
- block_height: 355
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x0e5edf133dd9d31c962d3c832701f118549e950098920f374a8a7f4b1503424c"
- deposit_root: "0xfc17404478ee17d526ec0e6d7b7f392f0cd2edf08cd20ea72a6b7cafb0bc5d1b"
- deposit_count: 354
- execution_block_hash: "0x48e867e23f93afbce5c768c3e7b24afc6f67bbf23b03ed35f673daaa22e150cb"
- execution_block_height: 355
-- deposit_data:
- pubkey: "0xa31ecb88e06673a2c3ea98a969827babdd0c6a8fc9569d70c024640f31084c7fc2bc8f00eb65023a008e0b47b3d2e364"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9212c805e5710672e72e9cbf49ab23f0b8849bda05c2eb97599849b0966e814956cceff71141ee1c90a5090e7388e6ce167364b1a5a843e08ab11e42fcb452e70a9b34cde657637ba57002054819440d51b7fefc316897c2dc396e36e3052251"
- deposit_data_root: "0xe29cc36e9033d65ab7c3214886e01b4071597f461fba82ca0d5b6e2716a96c2e"
- eth1_data:
- deposit_root: "0xbc150ef54a71de32ae1cdc80595d7102bcfb75391a31596cd08f93ac573f82db"
- deposit_count: "355"
- block_hash: "0x91e6f47ff5874c78e63536737ed9fba1fd13418ad4adafe5d8afa6b6096d7175"
- block_height: 356
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x0e5edf133dd9d31c962d3c832701f118549e950098920f374a8a7f4b1503424c"
- - "0xe29cc36e9033d65ab7c3214886e01b4071597f461fba82ca0d5b6e2716a96c2e"
- deposit_root: "0xbc150ef54a71de32ae1cdc80595d7102bcfb75391a31596cd08f93ac573f82db"
- deposit_count: 355
- execution_block_hash: "0x91e6f47ff5874c78e63536737ed9fba1fd13418ad4adafe5d8afa6b6096d7175"
- execution_block_height: 356
-- deposit_data:
- pubkey: "0xae32f510734cfe1a05f1a49888185191777008667a62a3b5d71f4b249a5a0421d762c98c0dd0626e17f6326ff525e63b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb278d4156302165853f5a95e5a38a57aad92e6388d231f1616c024ece355b83f9b4ba41f1bb60fc0ae5aca0c1457b5090e84bd06d28288890b17a2244288e4421a4fc1534b190ed3e520a471701e5142eb4374f3e372f4e7b0d754e943455b54"
- deposit_data_root: "0xea9cace5a73c0c0a4cfc34fe161fe4a0aa802729c46451cd375a524f84032e1b"
- eth1_data:
- deposit_root: "0x4ece22540ed44b8d7e55a580ef7afcd709ada5004c4505db558a4fa0ef39e949"
- deposit_count: "356"
- block_hash: "0xf9854d07f70ef80e24c9dae43433d2a284b89ee66e5e8912a4ebb92246a268da"
- block_height: 357
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xec97a0de415ce5348ebe21219a3cbe17938f07344276f64ec40e1dced411c131"
- deposit_root: "0x4ece22540ed44b8d7e55a580ef7afcd709ada5004c4505db558a4fa0ef39e949"
- deposit_count: 356
- execution_block_hash: "0xf9854d07f70ef80e24c9dae43433d2a284b89ee66e5e8912a4ebb92246a268da"
- execution_block_height: 357
-- deposit_data:
- pubkey: "0x9407a54a336fb7632ed16da2929c6ed1e2a8a969990d15f9f322734ee60c00757dec74e4c0224e813efeb1c9be42c09e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xafd6a5b56011fdc9d506d7c468993d690e2416b8322a5117fbfaeba9e4f15a6518d1f6b4b6917f381e96e396f8a5ff0c13eb33425c2247af685cc4723322d0e1596a3e1d0013871ac6603ef6fa4c74eddf2707f60e19fbb84073113afaa9ce5a"
- deposit_data_root: "0xa27fecc07480ce7de9e8fdcab0a5371632f26446c6a1a7e5594cd3b05f91c879"
- eth1_data:
- deposit_root: "0xb6e2c6e1112b2143ea4480f062c4c7c648307419c43032304281f44bcfe04578"
- deposit_count: "357"
- block_hash: "0x624663feb3f1449b2b425c886c243ab42cb4bbe01a06f1d47421134df7b63475"
- block_height: 358
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xec97a0de415ce5348ebe21219a3cbe17938f07344276f64ec40e1dced411c131"
- - "0xa27fecc07480ce7de9e8fdcab0a5371632f26446c6a1a7e5594cd3b05f91c879"
- deposit_root: "0xb6e2c6e1112b2143ea4480f062c4c7c648307419c43032304281f44bcfe04578"
- deposit_count: 357
- execution_block_hash: "0x624663feb3f1449b2b425c886c243ab42cb4bbe01a06f1d47421134df7b63475"
- execution_block_height: 358
-- deposit_data:
- pubkey: "0x8fe3971515fb25cbe62a03e4a593dfb4cc3563bc5b7866dfe300b958a53f07fdde463fc7abfe349a2eedf38d569cd126"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8f51e38f6033d91644cd646777b584c8ee985d18951ea4f184e5f321806b111881584c65d411542e99899832620664c60c6bee1be977e63041276f81f6daaf7b1931cdd4c725faf85b5186f2001b18e4e6cfb2c562cf5360bf76f1783ad54b7b"
- deposit_data_root: "0x28cf518415e14159c030d4c9ce4e1737eb8dafd10f8c9f3668c1a157b5f5ec3e"
- eth1_data:
- deposit_root: "0x0b066def513f0615242e17a3fe521dcd78226abfbfa040203591f1f9587b3877"
- deposit_count: "358"
- block_hash: "0x3492958f15fa544dbe4eac07ce27c1ade01e53ce22cff0aa6e5688a50a53af73"
- block_height: 359
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xec97a0de415ce5348ebe21219a3cbe17938f07344276f64ec40e1dced411c131"
- - "0xd34bdde7bf541ae5af14a22f182fe4a5087d292e96c952ec405b9c04fd71645c"
- deposit_root: "0x0b066def513f0615242e17a3fe521dcd78226abfbfa040203591f1f9587b3877"
- deposit_count: 358
- execution_block_hash: "0x3492958f15fa544dbe4eac07ce27c1ade01e53ce22cff0aa6e5688a50a53af73"
- execution_block_height: 359
-- deposit_data:
- pubkey: "0xae99451101dde8ce7d7f1b784fe2a1fe0974cd3d7e8d2d3c775892cdc2dfc021eb9f7a5b60681fe7369ec88884e6299a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa9e4c4aa80a317292a1d42a7dd6d18cfb04c7087a078332b7ca9c1fdac29b8019a2f6f2cb3034362a63ac7ceed7616510b6c45212fd0ebc2b7851293c4c46d1aa3eb99b7df62891c30e83d2a1a58f5bc91ad4278655f8482dd14bb0941ab37c9"
- deposit_data_root: "0x69b84b7fa3b0dda0b7eaf825ac386bd2416359a1c076743901c727adfbad4022"
- eth1_data:
- deposit_root: "0x0a872a65e20b1d6eb13282886f5082a99b3ac36e5636c6b7667d6f7b454c136f"
- deposit_count: "359"
- block_hash: "0x05f878ea1b32f42d1b5eb823c090f2789b19a062bc3495d80402a3077ccab36d"
- block_height: 360
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xec97a0de415ce5348ebe21219a3cbe17938f07344276f64ec40e1dced411c131"
- - "0xd34bdde7bf541ae5af14a22f182fe4a5087d292e96c952ec405b9c04fd71645c"
- - "0x69b84b7fa3b0dda0b7eaf825ac386bd2416359a1c076743901c727adfbad4022"
- deposit_root: "0x0a872a65e20b1d6eb13282886f5082a99b3ac36e5636c6b7667d6f7b454c136f"
- deposit_count: 359
- execution_block_hash: "0x05f878ea1b32f42d1b5eb823c090f2789b19a062bc3495d80402a3077ccab36d"
- execution_block_height: 360
-- deposit_data:
- pubkey: "0xb5dd36fb996d68fb9dff117081435088b54509db6c3bdcbe58bb3711fd21b62f22f7ffef9b8ead2031c0c187717ca738"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa704de41a3d802906eaa920016df241c8e6a483b25b6a144811305341d631c9159b7453c16fc7266c005d20a362b52ea1322e545ccb84f995f863b30f5b31d0af2824cbd21cf7dfce43fb369cb77cd92dfa58ea2c515d99c4b1e82b30a4001ba"
- deposit_data_root: "0xe392df1901cb47c60f7a23312f4938957258d1e4552775a6c9e1716318ebc23c"
- eth1_data:
- deposit_root: "0x566ee27dc76d160c182b89a8152d85644ad00ae1a6dffa89e096d383f612e4f0"
- deposit_count: "360"
- block_hash: "0xe3a5318a234c6d5ceddb72a5dbcdd3d1424a17d8ca7b08bc7bbdd55b6aa0d9c3"
- block_height: 361
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- deposit_root: "0x566ee27dc76d160c182b89a8152d85644ad00ae1a6dffa89e096d383f612e4f0"
- deposit_count: 360
- execution_block_hash: "0xe3a5318a234c6d5ceddb72a5dbcdd3d1424a17d8ca7b08bc7bbdd55b6aa0d9c3"
- execution_block_height: 361
-- deposit_data:
- pubkey: "0x9376161dba759909776ec807351e1cdafbff9a9d817babba680c953344a80dcaa38378ac6a7fb3079d909f5907310336"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b38fdafe54fb8e27ad780c4fa0910777e6d0f8ece579bfbd4a0cf121eca3de1e1e19dfdf284db7516d25265f9c989210ed3894e1c6c6e3365d99e9f3357b39bcf791ea2e08c43059e2adc753ea6c96a68ca0134395f7b8cb25662d87339157b"
- deposit_data_root: "0xb1df04177e3328845d9af042b46eb4b7b5d4d0c8c884a28c2ad183ed23801013"
- eth1_data:
- deposit_root: "0x77959d8e2c2c5ce3fda7eb96f376f88a281224e3eaf3fe232d20d35eef2d4f2e"
- deposit_count: "361"
- block_hash: "0x42046b4ccdbc910edab7da07038bb06f7cf7a9f01da446b7896260e2fb0a797a"
- block_height: 362
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0xb1df04177e3328845d9af042b46eb4b7b5d4d0c8c884a28c2ad183ed23801013"
- deposit_root: "0x77959d8e2c2c5ce3fda7eb96f376f88a281224e3eaf3fe232d20d35eef2d4f2e"
- deposit_count: 361
- execution_block_hash: "0x42046b4ccdbc910edab7da07038bb06f7cf7a9f01da446b7896260e2fb0a797a"
- execution_block_height: 362
-- deposit_data:
- pubkey: "0x8d92d91ccf259f1c3df11d2e4e92cbe047a9b278ab9ee1341835a08da4c957950a70f51d62bbefd4c6f3c01511e39796"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83b14219e42c4389f315892b1f7bf34a7d9649aa91086b2a3a5d06fa5822af504b9f46364e39a5406a33bb8feb3baa540f90dda0d091ca6cd9df322bb81e1220af8a63a3ac9f5bea4db7ea883d8e7b39df07c59f7d478c9754455e84f556d1dc"
- deposit_data_root: "0xb65dfed61fae9bb5cfe7b84bb94b11aed1949d8c0f2ab1bad962aa2639ee9ea5"
- eth1_data:
- deposit_root: "0x8ce66b4067fd288192b5cf456c79dbf793d86adf144f0ded5837fa2f916330dd"
- deposit_count: "362"
- block_hash: "0x30caf55961a0afa34e0ea7fe1c82badaf3bcb966c3e27b5f6d28f5dc90cdac8f"
- block_height: 363
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0xededa6672e4f4f520b91640b5d0e396d02af2d267ed8a7f99ec6844a81bd3197"
- deposit_root: "0x8ce66b4067fd288192b5cf456c79dbf793d86adf144f0ded5837fa2f916330dd"
- deposit_count: 362
- execution_block_hash: "0x30caf55961a0afa34e0ea7fe1c82badaf3bcb966c3e27b5f6d28f5dc90cdac8f"
- execution_block_height: 363
-- deposit_data:
- pubkey: "0xa95aa6bfc756de15cb1a21d05b465afd5bf806faee4e662ec335d1e093299632f9498dff50c71844e28d98b0d2cb9e29"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xab509e72eb0293f13ff2cb2dea99e6289562f8315b1f70c913f1a7705b45c6398150df3cc1991edd1ef7d0c72cd0925712a04bf9161f3f7d5548ec6f0ec4c2271054fcca875d6258a204d5478a4396dafcb2d99083ef2c990111cbe6c9b62b07"
- deposit_data_root: "0xf0a5d8ef855f6d121a251189ad5dfe512c221f0f27e4f7225fc37e163001359c"
- eth1_data:
- deposit_root: "0x8c048d62dd48e2676a75bf37278cf8a81934a702809656d92f153568b81893a6"
- deposit_count: "363"
- block_hash: "0x7dbc675b430d7c2de00d444ad4babab187b9590770a385b9c34b97f8f9db8bf7"
- block_height: 364
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0xededa6672e4f4f520b91640b5d0e396d02af2d267ed8a7f99ec6844a81bd3197"
- - "0xf0a5d8ef855f6d121a251189ad5dfe512c221f0f27e4f7225fc37e163001359c"
- deposit_root: "0x8c048d62dd48e2676a75bf37278cf8a81934a702809656d92f153568b81893a6"
- deposit_count: 363
- execution_block_hash: "0x7dbc675b430d7c2de00d444ad4babab187b9590770a385b9c34b97f8f9db8bf7"
- execution_block_height: 364
-- deposit_data:
- pubkey: "0x89f4dc26316e4037269b4afd3d92f7aa9d768be37dd951829657941f2220f7546071ac46a72d715a1af71689982afe61"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7be13f710902b118aabf1b4e84f6e67bb72bb4df89a9444dffcdc9db966fd451b4f16cebfa6546a41f0b7ec4a52baa206133d4190cbcf26b266d5f0dda6231d720a0cfb21c671008b84b230f851a4e9bdb87c78f81a2c4cee31bea858596c68"
- deposit_data_root: "0xbbd775efe2df031eb9719e580ea4259844d508dcaeb723b6698c3896dee27771"
- eth1_data:
- deposit_root: "0xf5ed206c675198fb290d0298805bdd34ecb569f3a14bcddba8343424118d0609"
- deposit_count: "364"
- block_hash: "0x8969f759d3bd762bf45f15e4a30f4c733ac0a822a698027610cac5618cb35e91"
- block_height: 365
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0x6ad91868ba8f36bf1cf9fc3a3226e8fa1b5b3182911ab1db6c7bfd830938d689"
- deposit_root: "0xf5ed206c675198fb290d0298805bdd34ecb569f3a14bcddba8343424118d0609"
- deposit_count: 364
- execution_block_hash: "0x8969f759d3bd762bf45f15e4a30f4c733ac0a822a698027610cac5618cb35e91"
- execution_block_height: 365
-- deposit_data:
- pubkey: "0x812c4ef835a77db7ead5b86773755711051cbc34cfdc4be7eb41a99ce5094f7d12412a7215275cd9ae8d8426eb91dfb4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa6785218f754ef90bb5d5b308a6b1bd2078c6d1c03845c874515ae4fb2da4b44dd4d34dcfaf5a5057b8f90d0e9154e56155038a0dd687eca319de2270b634a6d0038f72a05b6c89e85c00c53a4ef259dbe3f1300c7bf4c63c2fd1e7b62488abd"
- deposit_data_root: "0xdae505a2425fa70ac7714c907d1918d77c0ef04f4654bc884353791f0b148071"
- eth1_data:
- deposit_root: "0xbab7a3b70441e52c82a2a43408ca1f6957abf9f2189daca60838341f23a14cbc"
- deposit_count: "365"
- block_hash: "0xc56ca86bea734411f9a9a8ce247094bbd5d632888cdbe1938df31acb880e662d"
- block_height: 366
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0x6ad91868ba8f36bf1cf9fc3a3226e8fa1b5b3182911ab1db6c7bfd830938d689"
- - "0xdae505a2425fa70ac7714c907d1918d77c0ef04f4654bc884353791f0b148071"
- deposit_root: "0xbab7a3b70441e52c82a2a43408ca1f6957abf9f2189daca60838341f23a14cbc"
- deposit_count: 365
- execution_block_hash: "0xc56ca86bea734411f9a9a8ce247094bbd5d632888cdbe1938df31acb880e662d"
- execution_block_height: 366
-- deposit_data:
- pubkey: "0x8cfd6c4fe7aee61657f1d6e5cff1d41d24bafab7ceea78d2f5d680f8b51aeea83ddbb39bf6978bbf1327a2d240012551"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8e2e30e4d30c5401f9fa6260da87b0468c53580f230c36255690955f4fddf3433da05d174390d687b79749afac5870c19b33d828ee655d6084b4a346df8d0aef3ef8491e99855e80d9e6413d0e28ae091303e3af2148166eace0d828eecf868"
- deposit_data_root: "0x2873cca6fb60ed389212d5624bc18fdd882ccfb57d60c6fa5858bcee68ce8f8d"
- eth1_data:
- deposit_root: "0x31afd21b630f676a5b7673355f85afc5c2b4206ff10a7200586b0a61e918c632"
- deposit_count: "366"
- block_hash: "0x6d39ef06bbcadfcc1889b64112e7060c1f2065d6b254466e765603decd8b505d"
- block_height: 367
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0x6ad91868ba8f36bf1cf9fc3a3226e8fa1b5b3182911ab1db6c7bfd830938d689"
- - "0xca7eee30dc4dae479488e27d2be31d92c9f9e2e3cd1b76c56bd8c0f895399c1c"
- deposit_root: "0x31afd21b630f676a5b7673355f85afc5c2b4206ff10a7200586b0a61e918c632"
- deposit_count: 366
- execution_block_hash: "0x6d39ef06bbcadfcc1889b64112e7060c1f2065d6b254466e765603decd8b505d"
- execution_block_height: 367
-- deposit_data:
- pubkey: "0xae7c6ebb4d7b5f462da2004698a6dc54f1e55ef0f3ecd0bc155c9b58f67a038422e209492c86c986d8f24f5261126f51"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5e4a27b8a2a022d4f4748b6277a7a3400866ccbef70d8b13578af0227c4491a9fb4934e23342bef47277ebbecebbcf101334a722540f70c1d3d768c870cfbf2cc3fba8cb7260dcb794b455083f4a092e54d441d5acee80b57d9d9ca8ee34057"
- deposit_data_root: "0x0b99abe0654b3fdb3e10c60bf63da44170f75887fb61a4be8119ac5d7f84f7e0"
- eth1_data:
- deposit_root: "0x25e729835c195d00e120e374d28e26a9e19eeab013878aebbc5b37b29f2c61a0"
- deposit_count: "367"
- block_hash: "0xb187bb0435d4f02e62beaaf1833b7ae3cd93e1acc0fc9dbfdf24f6d0b48d3d1b"
- block_height: 368
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0xc93d9dcfae7c9e728958d0b093f1fe4ae72fb7d51eb5bc91a9a106e417426fc1"
- - "0x6ad91868ba8f36bf1cf9fc3a3226e8fa1b5b3182911ab1db6c7bfd830938d689"
- - "0xca7eee30dc4dae479488e27d2be31d92c9f9e2e3cd1b76c56bd8c0f895399c1c"
- - "0x0b99abe0654b3fdb3e10c60bf63da44170f75887fb61a4be8119ac5d7f84f7e0"
- deposit_root: "0x25e729835c195d00e120e374d28e26a9e19eeab013878aebbc5b37b29f2c61a0"
- deposit_count: 367
- execution_block_hash: "0xb187bb0435d4f02e62beaaf1833b7ae3cd93e1acc0fc9dbfdf24f6d0b48d3d1b"
- execution_block_height: 368
-- deposit_data:
- pubkey: "0xa4ee2d6f77a08089c71194ab48c338632c6b1041c326a483033aecd1bac1baf5de221053ea15c9fbdb8584edec6a731f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa868efa2a6b92d1cc547bf3352b67b142dcb106cffd3510caa09eca8071bac276d217af7aec4551b8da80f1dd7c5d62117c74d40e9204580cf0d68ef795e9c226ca17a0cc54f8da1fd5c9ed4a9721c27f646d3c8166cf711de031d1442793bd7"
- deposit_data_root: "0x8ecabb629b1e1da971d5edf0f68c6f7e56a15adf30f5a224ced581e1307efa17"
- eth1_data:
- deposit_root: "0x71a7e69529e1627bebfe2eb84e5387960b67bfb45ea7c73b36e9f26b039abb48"
- deposit_count: "368"
- block_hash: "0x24625a939c0317893b0a4ff7e485998efedcc1219caf706cdcf98a955ac6eed0"
- block_height: 369
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- deposit_root: "0x71a7e69529e1627bebfe2eb84e5387960b67bfb45ea7c73b36e9f26b039abb48"
- deposit_count: 368
- execution_block_hash: "0x24625a939c0317893b0a4ff7e485998efedcc1219caf706cdcf98a955ac6eed0"
- execution_block_height: 369
-- deposit_data:
- pubkey: "0x82d62ceb1242d6dc6527d8f885fe301f4313b87e7e336a34a8d3a898ffca180dbc624f45e1dc07695cecc54023207400"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xafe8ea26e0356b1ffe34ee1f6e50d8f046ab3d7eaa3decae78fede0b56b8b04903031de2fb45a877b80ad5baca8dc6d900adf83f4617563bf9658627a40b601f5ee3e53980bc51584ee4c05ce88c3ca720b1214697668104dae210e7cbffaaaa"
- deposit_data_root: "0x73aa59f819c871ac6651030e64fbeb030153e12d230d516c22b768230dd7c65c"
- eth1_data:
- deposit_root: "0x427c76f57c454b3d1154f3df3f645e88551b6d51f544aef9789dd63f26dfb705"
- deposit_count: "369"
- block_hash: "0x791a39d5642a805a00de9be73ed412bb5870ca828e2b8bd41e1ef0919336860a"
- block_height: 370
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x73aa59f819c871ac6651030e64fbeb030153e12d230d516c22b768230dd7c65c"
- deposit_root: "0x427c76f57c454b3d1154f3df3f645e88551b6d51f544aef9789dd63f26dfb705"
- deposit_count: 369
- execution_block_hash: "0x791a39d5642a805a00de9be73ed412bb5870ca828e2b8bd41e1ef0919336860a"
- execution_block_height: 370
-- deposit_data:
- pubkey: "0x9337d74573784dae1f5badff018e4f1c5a2f19d1b57ac07a2f12dd628ed97a4b3a4c84ff4c7d291063f78ec15ec163ca"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96eb75a5657091aa6019a5b6755aca55b675e7ea964b4e88c4f3528d47768cf37b5edc524325b3f969ccfab550d0e3f4027ea30bb3a2ba00c9cb850a7391a7d37175b5f790ef21b710b25bfa0e48b18ea67d8f51c77fda44da5356750a1d77da"
- deposit_data_root: "0x0bf34b47edadc088a1567b156f78bf0b3ba212689efb7262d3e992f106b79228"
- eth1_data:
- deposit_root: "0xa7bda8ebefccf3bf5ec32d0a67a48d1266fdcc537bea36a2c2e721aa2149be77"
- deposit_count: "370"
- block_hash: "0x47a677735c1aa41443778a8f1d010fd55ec000d87ea1b41d9f7b06e3ae6108f3"
- block_height: 371
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x415cb916cdf12ea2e3a80a5a17730fb71ba09e3dee19953b2144ff451717f33a"
- deposit_root: "0xa7bda8ebefccf3bf5ec32d0a67a48d1266fdcc537bea36a2c2e721aa2149be77"
- deposit_count: 370
- execution_block_hash: "0x47a677735c1aa41443778a8f1d010fd55ec000d87ea1b41d9f7b06e3ae6108f3"
- execution_block_height: 371
-- deposit_data:
- pubkey: "0x91fa5a8682921fa6dce932b8a9cd3e58ac485c03ef81202f69635f463ced2b366a85a3b6aff905542840c05b5739d7d4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8360efa2ef67875dd7e4ec4d36b39f47adcee01a71d891c61a398413a3fd4e4d26f47f4dd72e4eb193f309d65409567302f99039c476d4f43a03d47285af9d9cd4ae8ab5ee1b9f6f0fc2c90511704414619a4de063ae1248fafc7d0c3822ec6b"
- deposit_data_root: "0xde1d11e466b6199447c8461b2b04c55cc78b3d53aba3dd0f663c2eaa0e6f3d8d"
- eth1_data:
- deposit_root: "0xa6897fb6ab9ffb723e0af72cf18a2f1baa6356017f5931ac3a96050d0a02a0ba"
- deposit_count: "371"
- block_hash: "0xb6ea6ec5773f90cd394c362390e482e0526049017d7027be09902e00dd800d05"
- block_height: 372
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x415cb916cdf12ea2e3a80a5a17730fb71ba09e3dee19953b2144ff451717f33a"
- - "0xde1d11e466b6199447c8461b2b04c55cc78b3d53aba3dd0f663c2eaa0e6f3d8d"
- deposit_root: "0xa6897fb6ab9ffb723e0af72cf18a2f1baa6356017f5931ac3a96050d0a02a0ba"
- deposit_count: 371
- execution_block_hash: "0xb6ea6ec5773f90cd394c362390e482e0526049017d7027be09902e00dd800d05"
- execution_block_height: 372
-- deposit_data:
- pubkey: "0x8631b733c42dcdc91e0852655e1513864b50fd75ca1078a205205afd3d2c0de2cb2da63c06f4f547212132fd66bd7d16"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4258cf976f155bb4eb8566777cf34184a34b1c8090f931c9160c0b616afae1182256741674af7df73e11ff1db5dad7e165d952269a1aa8a68a523e87a9de14d00c3a928e97a1e7e74aab45331d12f23ec55fface9826bec0c71d3d985624b49"
- deposit_data_root: "0xf449648967e51c3ddd171deffae8afbbd69753f29f5f65659a6a2c6bfe4191db"
- eth1_data:
- deposit_root: "0x96fb5489ed0128e41f8d22f65a9e02b05e3febfa35b4a0c2ead831cb68e0f1dd"
- deposit_count: "372"
- block_hash: "0xe7dba8e784a1897ee5404a1cfb172fd5e5897c784e72596431b8b6cd7caf0fa6"
- block_height: 373
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0xfdb57c8fa36c5390b466ad79c9bcd9f3991ab173af3c339170f8c82eb63f0251"
- deposit_root: "0x96fb5489ed0128e41f8d22f65a9e02b05e3febfa35b4a0c2ead831cb68e0f1dd"
- deposit_count: 372
- execution_block_hash: "0xe7dba8e784a1897ee5404a1cfb172fd5e5897c784e72596431b8b6cd7caf0fa6"
- execution_block_height: 373
-- deposit_data:
- pubkey: "0x965258ea99b6f1eefc8d8196fad346c44b559e00fb31baf7cdda18e25b185eaafa91e3e366712514ab3ab855f41c9600"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb70f284e086d2d8d95b2fc7adf1937e52732e39294ef3b836df58c7cd8cb3fbada21137cd66070b82799cce72a4d741f0b66bfc892c5c3ec6ae1aa6e583f2abc05994af795607753085b556955cbd33df389e9ed86addc952a78a8f959c42711"
- deposit_data_root: "0xb2b1703e6974ab25bd10e04e11c2e1f427cae39f2a5cade05266982616651ec6"
- eth1_data:
- deposit_root: "0x5af7c0eefdca4998093fee555e6b38acaf0ab646a17afb02712b2fc83f405d20"
- deposit_count: "373"
- block_hash: "0x5967feb20145233cf4deb33b3595e0f074a8c3af859acde36bf21d8d412020f6"
- block_height: 374
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0xfdb57c8fa36c5390b466ad79c9bcd9f3991ab173af3c339170f8c82eb63f0251"
- - "0xb2b1703e6974ab25bd10e04e11c2e1f427cae39f2a5cade05266982616651ec6"
- deposit_root: "0x5af7c0eefdca4998093fee555e6b38acaf0ab646a17afb02712b2fc83f405d20"
- deposit_count: 373
- execution_block_hash: "0x5967feb20145233cf4deb33b3595e0f074a8c3af859acde36bf21d8d412020f6"
- execution_block_height: 374
-- deposit_data:
- pubkey: "0xaff02f3635554e57d140069596a9c3463e85408521b2349b6d1d5c4223874086dfa5a58f8ca73256ebfccc63fb88e58b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa04bb8b421c6e3a97b2d678db62adffaded29db686da4adfe0e05dbb50e55cb95631a5298136778ac5d0fed413b291cf042ea8fd3406cb4cb196bdf190eac79e2e3526943df94b58465e40925255d38fcf6238069bfab4a3349d7e02490ce24d"
- deposit_data_root: "0xb2bf57e882657383825bc6f7228e5a6c1c518c48de44a855ac853b521d8d28a2"
- eth1_data:
- deposit_root: "0xc88fceb356cfdc6fd64eb70a98fb873d921cbe2bfa77f357695682a1db122bfb"
- deposit_count: "374"
- block_hash: "0x4cbd9a54874e2dff03520d5313f7d0f436fd15e2e6adf2010430159f3c884345"
- block_height: 375
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0xfdb57c8fa36c5390b466ad79c9bcd9f3991ab173af3c339170f8c82eb63f0251"
- - "0xaa4ae80e4b97e7e7234fbf9b4581551d8b01473b0e06b9ae16eda5add93de3b1"
- deposit_root: "0xc88fceb356cfdc6fd64eb70a98fb873d921cbe2bfa77f357695682a1db122bfb"
- deposit_count: 374
- execution_block_hash: "0x4cbd9a54874e2dff03520d5313f7d0f436fd15e2e6adf2010430159f3c884345"
- execution_block_height: 375
-- deposit_data:
- pubkey: "0xa166c85614c5b0d5af165a42ab98515c009b6eccb740213e6ec1268e35aebaa73b8c9b22711aac0d5087f2534604eb36"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2f0a3f9d23101580d45e327cb58559a0eb0da2ef98ba8296040c0189c32cf5d400e49e45d408961a44ec1755f303be516949f3ed899d1b0afaa4cf3c237f7c1dcf538539d48c8b013601db131b2753b456bfa683922a1be60f306c491958146"
- deposit_data_root: "0x635116788f81411826a4bab6c7b0c4d22d8a100053efca983cafed46f19c1128"
- eth1_data:
- deposit_root: "0x41e8cec2e3a73c8bf38474b5ca18043b11f11c9ee9eb0cacc2ffb740e5a57c12"
- deposit_count: "375"
- block_hash: "0xafa631155e92b5e36aa357fdcb2c59894f96d85f0cd7e7704da84c28de104088"
- block_height: 376
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0xfdb57c8fa36c5390b466ad79c9bcd9f3991ab173af3c339170f8c82eb63f0251"
- - "0xaa4ae80e4b97e7e7234fbf9b4581551d8b01473b0e06b9ae16eda5add93de3b1"
- - "0x635116788f81411826a4bab6c7b0c4d22d8a100053efca983cafed46f19c1128"
- deposit_root: "0x41e8cec2e3a73c8bf38474b5ca18043b11f11c9ee9eb0cacc2ffb740e5a57c12"
- deposit_count: 375
- execution_block_hash: "0xafa631155e92b5e36aa357fdcb2c59894f96d85f0cd7e7704da84c28de104088"
- execution_block_height: 376
-- deposit_data:
- pubkey: "0x967633e5396683a4d51ac8e531194d8243fb808b3237c5ff635afcc0c6ab3fab8443cf9bc7268c25c85d5c9d3b42463c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x920074fe4578a343f3c10a152857b1301b3bd370b5fdc6e9f806f46f59360c24cc06b6736572613ec332d06032280b2117f89e75a93ce3102032f5326382113bbb300c6b3e5ce36921f661212338f5342683ede2eb3505bb4ac720cc3c60263a"
- deposit_data_root: "0xfd47af7a32eeeebd5d5e99faf7988bc11d295a16351dd61802acf29bb7c7c48d"
- eth1_data:
- deposit_root: "0xc334c97c33e4fbbd1cb28802b5845db45ba26f0583b88374f650c08f577a4629"
- deposit_count: "376"
- block_hash: "0x0477978ff52a8aadcc642ebf3e523c6fab4b2be5cd8e92abaf545f1f4974aabc"
- block_height: 377
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- deposit_root: "0xc334c97c33e4fbbd1cb28802b5845db45ba26f0583b88374f650c08f577a4629"
- deposit_count: 376
- execution_block_hash: "0x0477978ff52a8aadcc642ebf3e523c6fab4b2be5cd8e92abaf545f1f4974aabc"
- execution_block_height: 377
-- deposit_data:
- pubkey: "0xb3dab04913697100af2268f8d71e4daaa6475d08785b4ab816d1a9d209703abdb3e890dcec518c88cb5983d30e977408"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84f73f81a47107e055c2332123f547da1c2d16e3434b8f2a2cfc18d2f23c17257cd047b6bc12cef2c1e32473afa897f802ada46f50d4c910ff4048927c64c3983e42c8c5e3681da8ed296589b8481314ddf847049451cdc7e429520f2a2f5ef3"
- deposit_data_root: "0x6dad28a69491a04e60893860dba1bc4be2ddc602499a2c1893fbbc9f3a24ebd6"
- eth1_data:
- deposit_root: "0x2817a89668f5bbc79855acf38ecd0089aebd5aed31a3a919aae56f2609d16eb4"
- deposit_count: "377"
- block_hash: "0x5e0a1b630591445514724260df8d60a7c36529f0d6c532b19b8115681c754df6"
- block_height: 378
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0x6dad28a69491a04e60893860dba1bc4be2ddc602499a2c1893fbbc9f3a24ebd6"
- deposit_root: "0x2817a89668f5bbc79855acf38ecd0089aebd5aed31a3a919aae56f2609d16eb4"
- deposit_count: 377
- execution_block_hash: "0x5e0a1b630591445514724260df8d60a7c36529f0d6c532b19b8115681c754df6"
- execution_block_height: 378
-- deposit_data:
- pubkey: "0xa4bdf84013dca6a9af8d56d0bec9767a969d7b0b88802ef0eac99a9551dcbc7e03336e63943d8cd072be2d2915d9db25"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8da17c87dc9aad2a3ac17331e00065d70a1c5351f063d22e23f9047d45938cec61ce0f0eba5966a85694dc30298fce9f1726b82286483f93c9ee867095eb398daa696e6ff40d0b525c1d249f48359d70f7f115c53f45a517d1dc1d024a40991b"
- deposit_data_root: "0xd9d6dd6ace596c76d133833e081bfb09dae6f0b3fb68ff016b2c3157e19ecc16"
- eth1_data:
- deposit_root: "0x0c72dbb6dec2b4a4f0b06aff6b28e5d323de1238e9c38b01414d588302cf341c"
- deposit_count: "378"
- block_hash: "0x613eb202e2e6e48ddab9d97aa5bc39164d7dac1613890ea7840783b6abc54c58"
- block_height: 379
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0xe1fb9fc453a915b6bddc83453cbc120de96754c37d0aabe33eae0320527ced59"
- deposit_root: "0x0c72dbb6dec2b4a4f0b06aff6b28e5d323de1238e9c38b01414d588302cf341c"
- deposit_count: 378
- execution_block_hash: "0x613eb202e2e6e48ddab9d97aa5bc39164d7dac1613890ea7840783b6abc54c58"
- execution_block_height: 379
-- deposit_data:
- pubkey: "0xb83a5503f8875dba99bfb8077c50b56120456f836cbb8b89a24e17d88c76071ed9b08a54500ad8e24382a43fa67df89a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb5eeec2defcdfb4015ec6f688f641a597f533106ab62765585e59e86a27e807cf322008469bd8e3649fd7ae4a367ff8a05956b65081161d7f227bc72a5385696e36a77a1c9b77d4bd553be66e1166efa80b9708605f6480dbf72ffa229a43c29"
- deposit_data_root: "0x174145bc6f9323ff01709c7c767c1a2f3e2608a17e8393966c64a5f1a34ad0b3"
- eth1_data:
- deposit_root: "0x32dc12145beb7653b4766efb4d84b1590f50be40852bb4281f0f29c0e1c5d874"
- deposit_count: "379"
- block_hash: "0x76901b62737505430cab3df9d5e8bcf58ec8f86c3db8c95a3cd14838a28a923b"
- block_height: 380
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0xe1fb9fc453a915b6bddc83453cbc120de96754c37d0aabe33eae0320527ced59"
- - "0x174145bc6f9323ff01709c7c767c1a2f3e2608a17e8393966c64a5f1a34ad0b3"
- deposit_root: "0x32dc12145beb7653b4766efb4d84b1590f50be40852bb4281f0f29c0e1c5d874"
- deposit_count: 379
- execution_block_hash: "0x76901b62737505430cab3df9d5e8bcf58ec8f86c3db8c95a3cd14838a28a923b"
- execution_block_height: 380
-- deposit_data:
- pubkey: "0x83e32149769b6c9091f8921195802c8948cfd2b6c9bf9760e70641757719e028d0e65c85bd0fccbc10b81cbad1c87d9a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93b8c60e836c5181647760ae65b7b5f14a89c2b09dbfbfd96aad5dcd2f569414e50e0008e821b9abf0b7b7e7c7e389a00b7cd596c6410826d484d31aa303a134c4f518d7351abf82d8d745944924bb3240ffa81d2bbfb4b2ebe1cc241aa9bf65"
- deposit_data_root: "0x8970139619fc0b0d1fcb5f385618ce7d725d20c55c85a77aea8b749d5ae5dd33"
- eth1_data:
- deposit_root: "0x1fcd7cba4e2a28308ec039550a5044e24d2e76576f39e7e5d6d08325cd8f820d"
- deposit_count: "380"
- block_hash: "0x941b810b7df953ef1c939599bf5f91fa02b40c02ecdbc9db3b835903b85b4ee9"
- block_height: 381
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0x05b6bbc7f807ab0dcc2cc1033e4743bfa978b4068e735ef860846a4ef71e4ef3"
- deposit_root: "0x1fcd7cba4e2a28308ec039550a5044e24d2e76576f39e7e5d6d08325cd8f820d"
- deposit_count: 380
- execution_block_hash: "0x941b810b7df953ef1c939599bf5f91fa02b40c02ecdbc9db3b835903b85b4ee9"
- execution_block_height: 381
-- deposit_data:
- pubkey: "0xb3b60189b0b7dec69db000719fc89cc811c60e70b80d764af86a9dde1c4becba8e561d9f4ca5437481f01b0d7d1fc807"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x959a30b65aafdc7e021fecd8d5eba6e2b0a4d0dd63aff40824a6a3b9b1b63804be39acce4df08e4025ed5445c606761d0f0090182aaed4727b7d5da87b0437e3a5ff8b395e9e4d241fc3f822ce92717733c58d54172fb14e7ca07aaa85243835"
- deposit_data_root: "0x4282b4b40da830d37635588ea701f4837f32e70f1a4177192b5f3f9e53991a86"
- eth1_data:
- deposit_root: "0x391f2ad9469d6191d978da35b42beddd2f61857f0ca40c88b395913d472c1b83"
- deposit_count: "381"
- block_hash: "0xdc138b7ce041cc906320c6e6180e0410b939b18fa470ad5531bb3eb5484dad2c"
- block_height: 382
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0x05b6bbc7f807ab0dcc2cc1033e4743bfa978b4068e735ef860846a4ef71e4ef3"
- - "0x4282b4b40da830d37635588ea701f4837f32e70f1a4177192b5f3f9e53991a86"
- deposit_root: "0x391f2ad9469d6191d978da35b42beddd2f61857f0ca40c88b395913d472c1b83"
- deposit_count: 381
- execution_block_hash: "0xdc138b7ce041cc906320c6e6180e0410b939b18fa470ad5531bb3eb5484dad2c"
- execution_block_height: 382
-- deposit_data:
- pubkey: "0xa290656399af969e0a3c03ab8529b6b0173e40c049101115120628fc09d549256f3a358f4cd858e02a9bd025a3e01dd7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3cc5bb444b669055ebe709357821e7e18e273b2bef53252325b7dba386016c718cf01557b29f1bb465d3fbf13f7fe1a090b1d24145d090c89e8d6a4ad67b0f23b0bb60fa897bbd65b020c97450e34d7ae4ee61e0685727fab624af4d866ecc7"
- deposit_data_root: "0x1d58a6e4b2fe07612286e5452c9c0bcf810331fdcf21e40471e007178d7ec239"
- eth1_data:
- deposit_root: "0xf40cb049da0e82cda435267314359e780d03f4490204998272fa00a9bd6dc6b5"
- deposit_count: "382"
- block_hash: "0xe1768f362d8733dc9330f62b62842ae31dd708e9d58a0ef208fcb174527cddc5"
- block_height: 383
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0x05b6bbc7f807ab0dcc2cc1033e4743bfa978b4068e735ef860846a4ef71e4ef3"
- - "0x1c38bcf92acf3077bcb07ca54de94f552d3128d9f5abc93eabaabef945993183"
- deposit_root: "0xf40cb049da0e82cda435267314359e780d03f4490204998272fa00a9bd6dc6b5"
- deposit_count: 382
- execution_block_hash: "0xe1768f362d8733dc9330f62b62842ae31dd708e9d58a0ef208fcb174527cddc5"
- execution_block_height: 383
-- deposit_data:
- pubkey: "0x8633815ef4ecf32dfd3e6221d877176ef1460f7147edae206349cc816431f1a2d60fc547e6dcf0bd31111fce6a822328"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x877082c5d8d68ce8a2547eb2fa81d42c67b1a0a0da9f62ca4f3ebb6a9f3f5853a627b3cff7e8700a801af5f81e9fd42f0f6dd0952a070a88b3c2ee73adf17e72cc8751ec6dc2f1a513bbe86e25eefd129d532e50ad77223116fb5912233bb858"
- deposit_data_root: "0xc11805cef7cb401d83cfcf73cee9526e60d319d708fb6d19761dfe576352f404"
- eth1_data:
- deposit_root: "0xb93ebaadc7951cd5056e2f900ee21ff1b94a0ef410be2345e9daa5798ee47321"
- deposit_count: "383"
- block_hash: "0x12fcdcd7f54e4f71eadbf4f1c91ab1b40ef47344411169c930298858a1bca8fa"
- block_height: 384
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xc9521569f6cd236e7893e6e538cfe9b294455c57d6738e0d5402dfb51e9edcfb"
- - "0x2e17dc08bed4ab4138ea54b4389d7956de63422e1f873bac51997acd6fc8a70a"
- - "0x7472f8762e7585ee829a64478023f69abff5f1a3c9c0b7eb37c5e0e530fd27cb"
- - "0x14503e81d68b81b6107b25a5cff097ac43e0ded9988b742805a287d02c1ac8ec"
- - "0x05b6bbc7f807ab0dcc2cc1033e4743bfa978b4068e735ef860846a4ef71e4ef3"
- - "0x1c38bcf92acf3077bcb07ca54de94f552d3128d9f5abc93eabaabef945993183"
- - "0xc11805cef7cb401d83cfcf73cee9526e60d319d708fb6d19761dfe576352f404"
- deposit_root: "0xb93ebaadc7951cd5056e2f900ee21ff1b94a0ef410be2345e9daa5798ee47321"
- deposit_count: 383
- execution_block_hash: "0x12fcdcd7f54e4f71eadbf4f1c91ab1b40ef47344411169c930298858a1bca8fa"
- execution_block_height: 384
-- deposit_data:
- pubkey: "0xad5539f19d8358478970caa4fb524b274867ca7449141a21fbd07e6b6291177200e9dca369b665e12ed40dea80b69cce"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x99788b2afa65fba3d50ac737cc372707a61a66423e03ca9a96b2bad066a3e939d61ea38ff6abcce5d89dacddde104e701318854c92d09513078171314dfd7f894e818db650e6385bf42748af1b6775d3c7f78f0e344ba1f2e7e01bd812da6c85"
- deposit_data_root: "0xd381809adc653a2cd994826ee024c272920803b10751c15699eeb345a8640448"
- eth1_data:
- deposit_root: "0xb7dd432c5408611d1368a238e7a462ba9294b34e29406a499ead95c513360199"
- deposit_count: "384"
- block_hash: "0xdee05ca3f55492ca6f2e09310db9339bfe0dc2e250f129950c5a430178c04398"
- block_height: 385
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- deposit_root: "0xb7dd432c5408611d1368a238e7a462ba9294b34e29406a499ead95c513360199"
- deposit_count: 384
- execution_block_hash: "0xdee05ca3f55492ca6f2e09310db9339bfe0dc2e250f129950c5a430178c04398"
- execution_block_height: 385
-- deposit_data:
- pubkey: "0x981a72fc476e4f532a10da80f235deb940e4cb6597c8e0f868171488f0eeb5fcc988048dd9ea3bef015aaec0cd79081a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84dd84cfaf29083c34505098112ad7f439c066376256a5869e77cb6e702070d864684ac093e37eb26759aca78505bcf5189047ded56671cb09b0eb630ffce2d6407747fbed2530efeb0dd07beab083eaed840e3e8440319f97aad670cefc83fd"
- deposit_data_root: "0x298c5a5474ec0f8a9a1e151a9ee7fc14ea9597803b32884678851dab464385ba"
- eth1_data:
- deposit_root: "0xfc0287e35ac5abcb9e2eac1a295d56d943c303bbb69ed02009c816a1e95ea769"
- deposit_count: "385"
- block_hash: "0xe9257489f72b1836a2f5243c212386fe13e7f1302fde45c66355f7f053ef088d"
- block_height: 386
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x298c5a5474ec0f8a9a1e151a9ee7fc14ea9597803b32884678851dab464385ba"
- deposit_root: "0xfc0287e35ac5abcb9e2eac1a295d56d943c303bbb69ed02009c816a1e95ea769"
- deposit_count: 385
- execution_block_hash: "0xe9257489f72b1836a2f5243c212386fe13e7f1302fde45c66355f7f053ef088d"
- execution_block_height: 386
-- deposit_data:
- pubkey: "0x9282d6526651dc5e7caf69877a2209d4346bb231b3caed98fec1c95ce3eed284da0617c4d1722e7c316eecebf73601f4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a07056d6cbc4955204e276e443ff9d0b7a22247a7481efd0329dd3f40f7935a8d1a7057ae628f58e4979550025eeb310ac822934b696c3f1988586a32b3b050f4bd34a74b522fbd8e94d6ac66b0127b95d3ff2e0a4d721c2564cead9c8714ab"
- deposit_data_root: "0xc39e707c0c1997a5199a59f529dac27feaa0591599dade101c6bc98e39c500d0"
- eth1_data:
- deposit_root: "0x531ee9c8985bee7183a5dc8fa5639fdf10c28f326426db8a657b0a5750cdbd51"
- deposit_count: "386"
- block_hash: "0x7f66e053d87f7f7b0687a29bcb1b42034b3a318d2918fb763a75a2f7e252cf4a"
- block_height: 387
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x6eb578b1e3f55c300c0071b7f22d0ee4d4a1b7a8415e8756521f9f68caca8852"
- deposit_root: "0x531ee9c8985bee7183a5dc8fa5639fdf10c28f326426db8a657b0a5750cdbd51"
- deposit_count: 386
- execution_block_hash: "0x7f66e053d87f7f7b0687a29bcb1b42034b3a318d2918fb763a75a2f7e252cf4a"
- execution_block_height: 387
-- deposit_data:
- pubkey: "0x836f2b3e00dfa069e4f315454cca69a56a36b6d32514ac81d168e34beabc42ea8a27918d60fe14a8c93ccf040faab02d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d45bf64b1cdfabf3d9d5f86008ed55b03b2e8ca881d85c0131ebde4834c423a8da16e0abb9e963b7b7a3b5e8229dfbe04c89313f74b9e8f319a5f27d19af4c01605129e6bad45047308c4e5d024e47f69a1f84863a770927434625853032b70"
- deposit_data_root: "0xe21a86f0256ac65cb7260bbf774eafa1ca0467dacb31a1fbe35aeb795000470a"
- eth1_data:
- deposit_root: "0x897cea6ff0ca2f5472bbae1583e7d256c8fb1cb9729a415ed2d6fd497ecb83ec"
- deposit_count: "387"
- block_hash: "0x1a8b424e0faa53f76a7a87fb68d980aae685c81c9e79734f883c5a3116bfddcc"
- block_height: 388
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x6eb578b1e3f55c300c0071b7f22d0ee4d4a1b7a8415e8756521f9f68caca8852"
- - "0xe21a86f0256ac65cb7260bbf774eafa1ca0467dacb31a1fbe35aeb795000470a"
- deposit_root: "0x897cea6ff0ca2f5472bbae1583e7d256c8fb1cb9729a415ed2d6fd497ecb83ec"
- deposit_count: 387
- execution_block_hash: "0x1a8b424e0faa53f76a7a87fb68d980aae685c81c9e79734f883c5a3116bfddcc"
- execution_block_height: 388
-- deposit_data:
- pubkey: "0xb4d3e8864dc26809ed314a03e60c7fbe63ce8921dcb52affa19837e59639513782a1e526823f77fc9564d8fcc15bb0ba"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8768e4401b70479e0e321cf92cc78d75b597714854e2b28ebe847e50090e3a0c9dfa3e226f80b6b44e070bda975b11a10990f572268d88d9a0060051998c3151bf839bf91b05e417ce5d98978dfdaea0166cac0b3bccddbe52133c47cc5b3917"
- deposit_data_root: "0x67c70be65243658ef363ce8536fd2c09c653a3cd1be0cb7673f8a103ae07b7dd"
- eth1_data:
- deposit_root: "0x707a55c126befe50ff91b08a62770102096b0a4c87aca8ea8821733237f9b4fa"
- deposit_count: "388"
- block_hash: "0x016e4d950de17f13291f14596645de6ae51e40614ce2e39c02159e18a7c9414e"
- block_height: 389
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xafae78b562f726681144ff9aa2563edbda5e907e1eb32ee2babf8792cca6c552"
- deposit_root: "0x707a55c126befe50ff91b08a62770102096b0a4c87aca8ea8821733237f9b4fa"
- deposit_count: 388
- execution_block_hash: "0x016e4d950de17f13291f14596645de6ae51e40614ce2e39c02159e18a7c9414e"
- execution_block_height: 389
-- deposit_data:
- pubkey: "0xb35c3469a78ea17878cbb166377b8aaea461a0f7d58cc5f77862cb9a232c5a95452d523362808b661cd24a1e0baa67ab"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x93c7d303f1562b87c5f15c0d45026ba2f5ac22a3ccba6a96310a8962192e0577f6464223375100a8f053cb9fdc03f3e40a91ebe2014116b316a79bed10235831dad5c2886e0cee562b06f2098c70a652196cfa73585d4850f16853eac161d702"
- deposit_data_root: "0xa9dbd218ea842ca62f1647881f4fc2e3bf1dd7a67a4b99eef47d43d74c34ce59"
- eth1_data:
- deposit_root: "0xd9d9f4dadee20fe6a1213a8e4919fe470c34b5315061c12c3326281be071b803"
- deposit_count: "389"
- block_hash: "0x6ebdc4ce688958aa6c4d76d6ee80bed95457f73964cbfa10b2553a44158e1a94"
- block_height: 390
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xafae78b562f726681144ff9aa2563edbda5e907e1eb32ee2babf8792cca6c552"
- - "0xa9dbd218ea842ca62f1647881f4fc2e3bf1dd7a67a4b99eef47d43d74c34ce59"
- deposit_root: "0xd9d9f4dadee20fe6a1213a8e4919fe470c34b5315061c12c3326281be071b803"
- deposit_count: 389
- execution_block_hash: "0x6ebdc4ce688958aa6c4d76d6ee80bed95457f73964cbfa10b2553a44158e1a94"
- execution_block_height: 390
-- deposit_data:
- pubkey: "0x800044ce43a3eec0738b16300361bc744173822642fdf7184a7ac58f6b315478c03f8b57efc36b37c262e08b66260dbc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb0515fc2450c616acbe03511afc4c02b85e0e2ca0793135a3926fa0b55665f37a181379c67f0bfbca09743436891a3a012b8d06ddbadd8ae84a7526b52168b3c19c075917482b5e6347dd134c5a4304d3d4f69310c4a51f611b61756a732acde"
- deposit_data_root: "0x86f5cf1fcdedaef646198af6429d7bfd31f55700f6f9c39625d93b6de78b01bb"
- eth1_data:
- deposit_root: "0xa62e54acb14771006dd11ca8e80ccb43520f1921a58c955e555cef5e45750ee5"
- deposit_count: "390"
- block_hash: "0x1a7e29fe5e78f36f6249c8d0afb846a437d99ec96465d6c64a8bd1fdca8640c0"
- block_height: 391
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xafae78b562f726681144ff9aa2563edbda5e907e1eb32ee2babf8792cca6c552"
- - "0x879021b47e1a1c0942dad2c1b18300857aff607246ec88ae3ff1558391e07509"
- deposit_root: "0xa62e54acb14771006dd11ca8e80ccb43520f1921a58c955e555cef5e45750ee5"
- deposit_count: 390
- execution_block_hash: "0x1a7e29fe5e78f36f6249c8d0afb846a437d99ec96465d6c64a8bd1fdca8640c0"
- execution_block_height: 391
-- deposit_data:
- pubkey: "0xa3fe94ea52c28c985a901f8d895f8d2493dd1d939da8f775c7e595379431d557b83efce814b3f2d9b5a463c8ab5234d0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84653812b348ba58c6eeddbd85870a0a3109da32bada6c5fb0ccb4f360c1d63866cc3548b03b066c0ff568f82b6bc4ee0e0b6665459569329878cb2a9cf5ee6169ff8b47ebefdc104e5cc3abb9caedd508bce5d02e6a5997b0f2c75f3b31781a"
- deposit_data_root: "0xf4f62e401aa56826818ca1a510a840ef08f374eb55e4c193fc58c64d15dfd9b6"
- eth1_data:
- deposit_root: "0xbb7338e44b9b1773d9a2537d33916a39047df59cf8a83b83ee15c4ebd7061f17"
- deposit_count: "391"
- block_hash: "0xc54fa15d7cf7e89fe249a3d43dc9aa194d89b7ed0709a9c453d63725a36b4bb0"
- block_height: 392
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xafae78b562f726681144ff9aa2563edbda5e907e1eb32ee2babf8792cca6c552"
- - "0x879021b47e1a1c0942dad2c1b18300857aff607246ec88ae3ff1558391e07509"
- - "0xf4f62e401aa56826818ca1a510a840ef08f374eb55e4c193fc58c64d15dfd9b6"
- deposit_root: "0xbb7338e44b9b1773d9a2537d33916a39047df59cf8a83b83ee15c4ebd7061f17"
- deposit_count: 391
- execution_block_hash: "0xc54fa15d7cf7e89fe249a3d43dc9aa194d89b7ed0709a9c453d63725a36b4bb0"
- execution_block_height: 392
-- deposit_data:
- pubkey: "0xb04bbe642a86b34459811d60affa8c72efaa288a34d4f2e5799807ced34747ef09ca47f90645d36c0a43fd9ce592e41f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x87b573600a6f5a6af8a6c8493ee98b9b179cf34aebd27ff4f063982a34464ea2faea6896f599dd885b0812f2829529e8066a5ef915c4b756ffe094a5c9e33c12ceb27daa3f272e2b8532bfda9724b799662a8c9030d4671f03224c391e283977"
- deposit_data_root: "0x08525bcafc67d143769778c202899f3bef45d03b0b4c47f40782dbd2d714ecf6"
- eth1_data:
- deposit_root: "0xa3b155eea9ce7c9e359bdfeaaa3226882a88b472ebc2f6dc20d63249f87fc31a"
- deposit_count: "392"
- block_hash: "0x54ddd2ee62cb4efc55efbf284b7c86b390754e6f0ebbb8a92c3546648444f7f6"
- block_height: 393
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- deposit_root: "0xa3b155eea9ce7c9e359bdfeaaa3226882a88b472ebc2f6dc20d63249f87fc31a"
- deposit_count: 392
- execution_block_hash: "0x54ddd2ee62cb4efc55efbf284b7c86b390754e6f0ebbb8a92c3546648444f7f6"
- execution_block_height: 393
-- deposit_data:
- pubkey: "0x80609da89da3d8a011674d17aacc7378a9ed907455c914c3adfe80d9d5ff1b903cf0195f7999cd27af91de5177af295d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa38c302d9ccd055c116a22a63757dc3cf5a4dbe498beaf638f0d90446ee263292b388036081585309c41b39c6d88622819cf63b6a5fcf985d5b6c01190b5d08627bf7d13dbf0ad9bd4b2489e1f4f1eb970c1e29c9f76406e49e04275b2bc65e2"
- deposit_data_root: "0x55cc13b5b52558f81535da2bf312b7430662936ea5e8f78f1042d174acfae930"
- eth1_data:
- deposit_root: "0xc4950b3e40fadc566118b3124e334889bd809244c4fbd2fb4e2e00dd940c6052"
- deposit_count: "393"
- block_hash: "0xc9e0def5a794986bc01573227a104a80465d774957b94c3fb5f66f6507226276"
- block_height: 394
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0x55cc13b5b52558f81535da2bf312b7430662936ea5e8f78f1042d174acfae930"
- deposit_root: "0xc4950b3e40fadc566118b3124e334889bd809244c4fbd2fb4e2e00dd940c6052"
- deposit_count: 393
- execution_block_hash: "0xc9e0def5a794986bc01573227a104a80465d774957b94c3fb5f66f6507226276"
- execution_block_height: 394
-- deposit_data:
- pubkey: "0xb929600f99e80e834dd9220a02e8b395bdd8cdfd9f93f201e6cd89ae1950e0789f93862082f0c7efd45e4b69224bd92a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x98aba9f2310ac87434cb6e273c5bf0854789024046d4eecdd20edc20d59e9c9585e3be1a9197a928444de4ed37e582720dfc1fbf5a765c7cab9bbccf5d91b27413b681e853690ebea5aa8b757f69b9c2bcb704a9bbe9667573f1820ab1ebc524"
- deposit_data_root: "0xe6c9a1e53fa2bc6dfb3a0efcb15d5b61a0b00d40c05e85fdc7c73c22c0f1fb2c"
- eth1_data:
- deposit_root: "0xbb0d4f28737877ea198db2552a20e83fa21712d68f256fb4c47b00bc79a6e725"
- deposit_count: "394"
- block_hash: "0x07a4841aeadb48375c77cc7bbb85952ed2a2d8590b379cbc8296b93e5bea89fa"
- block_height: 395
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0x0d997180aceeb9c78bfd8dff8c8f847e603e9ef4da82207e9ef96fa26dd60c18"
- deposit_root: "0xbb0d4f28737877ea198db2552a20e83fa21712d68f256fb4c47b00bc79a6e725"
- deposit_count: 394
- execution_block_hash: "0x07a4841aeadb48375c77cc7bbb85952ed2a2d8590b379cbc8296b93e5bea89fa"
- execution_block_height: 395
-- deposit_data:
- pubkey: "0x9052bae965368c78db0d638faf2ea9beb0e42b469adabbba09f85936f948a1cd77cf811a20ae759498770855068adae3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8fd3066f0eb12e45912dad9e0f03999efd048f5c3a7cd0ef0c1b28469d734e0900faa8208d9f3c2ea4475c4b0edef88f01a0b0c265ff4adda81d58422b1512db9e12fadc2ee56a87d17f98cb1d403321af314954be68de1ef1626645c9d0b58b"
- deposit_data_root: "0x8041edc01aaaba30de8f64e99b463e7884fe5d7927a8e1ac0f8c26e4eeefac63"
- eth1_data:
- deposit_root: "0x159cb3175d894680b3f9885f0bd4fdf130731ae6fbed0bb8ef6c8ae22d3c141b"
- deposit_count: "395"
- block_hash: "0x6f29a9e99967a5b3ae5da3eca55e429b68e12c0a3ccf3765743baef29c1509aa"
- block_height: 396
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0x0d997180aceeb9c78bfd8dff8c8f847e603e9ef4da82207e9ef96fa26dd60c18"
- - "0x8041edc01aaaba30de8f64e99b463e7884fe5d7927a8e1ac0f8c26e4eeefac63"
- deposit_root: "0x159cb3175d894680b3f9885f0bd4fdf130731ae6fbed0bb8ef6c8ae22d3c141b"
- deposit_count: 395
- execution_block_hash: "0x6f29a9e99967a5b3ae5da3eca55e429b68e12c0a3ccf3765743baef29c1509aa"
- execution_block_height: 396
-- deposit_data:
- pubkey: "0xa7c693916f59a0ee41b13d045632d4c5e8703a0e1431b50ba0450834747e41a6634ab9c0c1efa6af140f2072c29cf7a6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2b6db61ed48e65d9b02339ec3dce5b65082ddb6e88f2a9d68bb008213c2f413e884df2e36a2df4ef4872a1d7918d8d60b4b0cecf20345016d9fb90f823950b40b56686cfd73a60f366e89c0664b512fa6b1fa7e03d10407e5391a01a793f180"
- deposit_data_root: "0x58e50fcd08de046408f42ef030f88327a7090e3f28d86b90c33226f625d8591d"
- eth1_data:
- deposit_root: "0x5659e739fa58f5bac4607770ad5735be507757cc931e78a32971dba1062f9f79"
- deposit_count: "396"
- block_hash: "0x98492c4ba8ab648f0b7347fd237f6c97e28f8c9276202b7ceeceb4e2b55a4caf"
- block_height: 397
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0xf317c693e0d6b8255336757d18a3edf61408bfb581694def9ea146abfe6ee676"
- deposit_root: "0x5659e739fa58f5bac4607770ad5735be507757cc931e78a32971dba1062f9f79"
- deposit_count: 396
- execution_block_hash: "0x98492c4ba8ab648f0b7347fd237f6c97e28f8c9276202b7ceeceb4e2b55a4caf"
- execution_block_height: 397
-- deposit_data:
- pubkey: "0x83a40895d9005f007df9ed7fdb17d820d3d66fe419480cede7518e1f54e4c1e2a97ffd71fe2f01187c3707cde5bf9915"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96d6a5708588333bbad7bf98de64425be3f93c823588a7f30a2391d2fea7a68d4d46572edf9b5884a3669648b6233f970049e50e232746643e3e7edbdc733853ecff22492cb6d7befaf83f4f9331a9d8f1b4bcb7e28f2d1bdfd94903f7c121ba"
- deposit_data_root: "0x4b89dcec503cf535c9cb9f034604ad431a3baa5f8ad939a9fee0f17a518c58e7"
- eth1_data:
- deposit_root: "0xfe07bcc8cf3812b6959665a4d69ac7dc10210db6de6b5cb3cc3ab4e3731a553c"
- deposit_count: "397"
- block_hash: "0x9adc7e62cd440bc4c77546efdeb7d185348964c8b7d899634d8c442ae02f0cf3"
- block_height: 398
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0xf317c693e0d6b8255336757d18a3edf61408bfb581694def9ea146abfe6ee676"
- - "0x4b89dcec503cf535c9cb9f034604ad431a3baa5f8ad939a9fee0f17a518c58e7"
- deposit_root: "0xfe07bcc8cf3812b6959665a4d69ac7dc10210db6de6b5cb3cc3ab4e3731a553c"
- deposit_count: 397
- execution_block_hash: "0x9adc7e62cd440bc4c77546efdeb7d185348964c8b7d899634d8c442ae02f0cf3"
- execution_block_height: 398
-- deposit_data:
- pubkey: "0x8ee8e926da165b8f34d249d194864a3994278aa4b829295480edac18395167fa016b2a4ffb0b0f3c89d18622bec2409c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96e64eb4225338a95db3620d53f114ce50c67c76f2775479d43b43dc99cc49203bf4cdb0a2f32ae8bc38871d5ea159f71573f7f17cff542489bcf03f71757e447cb1d3a88fbcb1849d406547f2ea18acdda8999dec66c611c66572435d27843b"
- deposit_data_root: "0x6f8c0bddde78f7897c2d2fa74c01ad7d54767bad64e1a110cecd9a13ffb11f31"
- eth1_data:
- deposit_root: "0xb10c6eb035b9b3ceaf4c5fabef893bc0e20d0fc473677948cab48835462cc8eb"
- deposit_count: "398"
- block_hash: "0x1aafe4f6b5beb8fefa9b9f17b11e8c330f1485d6b915bba56cd48ee2fd300ffa"
- block_height: 399
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0xf317c693e0d6b8255336757d18a3edf61408bfb581694def9ea146abfe6ee676"
- - "0x2a66533bacc64203fa52d8f62fd219a28a45bcbb7c0e29db839a9d9b19a5f91a"
- deposit_root: "0xb10c6eb035b9b3ceaf4c5fabef893bc0e20d0fc473677948cab48835462cc8eb"
- deposit_count: 398
- execution_block_hash: "0x1aafe4f6b5beb8fefa9b9f17b11e8c330f1485d6b915bba56cd48ee2fd300ffa"
- execution_block_height: 399
-- deposit_data:
- pubkey: "0xadd60d6bf2abc6935ffebfe463c9b305ed2c898a00e2a84b997c014e140a7b254dfddc5be39e406ef0a893c4d67dd1ba"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x956032f3c008672890406790f1f6df66918c5b34b5c99bdd3e9e573b5c9eeb38457dad357d91bf63a5b40712f033196717c67639a675074a273d807ed38cfff57d5ae0a5da85425cc5e09a4fba69ef1ac8fde490e2acfcccf84593275ac13b6e"
- deposit_data_root: "0x9af6c4251177b012f498c5a6444e89a07f3b1f99c0c47c4370943fb4a19875a8"
- eth1_data:
- deposit_root: "0x2986d1af8658f87aab3fc101470d46c5875124b69e93da963cd7ed8a0815db27"
- deposit_count: "399"
- block_hash: "0x3f9fb82bf76f4d04409151836ea7e82696193cab3ba0a6505f8fea426708f118"
- block_height: 400
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x7e5837337e12008bc00095f95c4579a110096a154443242630b70a200c8eb25d"
- - "0xf317c693e0d6b8255336757d18a3edf61408bfb581694def9ea146abfe6ee676"
- - "0x2a66533bacc64203fa52d8f62fd219a28a45bcbb7c0e29db839a9d9b19a5f91a"
- - "0x9af6c4251177b012f498c5a6444e89a07f3b1f99c0c47c4370943fb4a19875a8"
- deposit_root: "0x2986d1af8658f87aab3fc101470d46c5875124b69e93da963cd7ed8a0815db27"
- deposit_count: 399
- execution_block_hash: "0x3f9fb82bf76f4d04409151836ea7e82696193cab3ba0a6505f8fea426708f118"
- execution_block_height: 400
-- deposit_data:
- pubkey: "0x8f48795cda6795e9af514489989a9f9e8b6db2b52a36881e4ba166327153d6db922e5148db044b27efe1831b54e16270"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89b774642bd7faeefc6435c7184df11dd2fb34464f7ece0430b69d220032f77eccf6187839c5d7e233d463b48640bba211cd063cc9b638a954ea2c782919656980c7491ca632a83538146d9e6156ddf6f7260fb5ad1b4756549ba7a1b1f2cc1b"
- deposit_data_root: "0x70721ee8848f77b3243c3ea7b1193970abadc48446a2f47116cc9371f55745e7"
- eth1_data:
- deposit_root: "0x452498ecbea92a19db703d3e4544acfa45d9890b43883f5f88081533a826f236"
- deposit_count: "400"
- block_hash: "0x604f66f12e19e8be5538632835dc419e722d35e3e15b6bc7ba305348680a4ec9"
- block_height: 401
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- deposit_root: "0x452498ecbea92a19db703d3e4544acfa45d9890b43883f5f88081533a826f236"
- deposit_count: 400
- execution_block_hash: "0x604f66f12e19e8be5538632835dc419e722d35e3e15b6bc7ba305348680a4ec9"
- execution_block_height: 401
-- deposit_data:
- pubkey: "0xb43ccddb32f15baaa32d69abf4b298d38e835607fd74aac5b25b5b161e8c865744a06526594faf39521e51fe44d66658"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb35daff1750c7ab2ff3ec29d401f83dfcc035bd5e0de5e45bc7ef789558349839da1c3588a263359ba86b4812b6c28360c960dd5aa762c7ef6123dc3e2ce63064f9ef2ed74eb9efbdbda96d87cfc2b50f4947e66ecd0244c546b9450277e6861"
- deposit_data_root: "0x0f94bc880af7f796e05590236751522502362f586d3bcf4d42799a6931676193"
- eth1_data:
- deposit_root: "0x9c53aafb0bf05b211e3d12a2771506145ca19774733164e549865501fb0f26a9"
- deposit_count: "401"
- block_hash: "0x897487f0b6c2ee25dee391c9b855ac06fcbbcf4f8ced76cceda3081c27d461bc"
- block_height: 402
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0f94bc880af7f796e05590236751522502362f586d3bcf4d42799a6931676193"
- deposit_root: "0x9c53aafb0bf05b211e3d12a2771506145ca19774733164e549865501fb0f26a9"
- deposit_count: 401
- execution_block_hash: "0x897487f0b6c2ee25dee391c9b855ac06fcbbcf4f8ced76cceda3081c27d461bc"
- execution_block_height: 402
-- deposit_data:
- pubkey: "0x83249b11efc76fba2ab77df9b5ffc607e6e2265c7f761dbb3099f3b4ff74ad8b9570036cb04942898f8c33b8442adfcc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7e93b3bc24dddcd889bcb9d313f632eeeea863ac36f6bf45cdf2aa3817eea3d58f8e133f3d7c52318370ca3d51458e3195aaf7dfb8affbf789e294893b93e1420a5417e2bfd42ef06d3a0a93d35e6ae4a89aa4a3887c53fecc5a5784951a7b8"
- deposit_data_root: "0xe1f17fc61185cdbeb20440550c2bbee0b02afd1bbcdda44938f893fe92e6d2ed"
- eth1_data:
- deposit_root: "0x636af0f0424726b4060828f72a3186c6b7dfaaea3591c5e7691d3a62fe183a7f"
- deposit_count: "402"
- block_hash: "0x6cae019fcf9937f0efea9dc1ab3a9550aaf34af27f8e63b644f9329e61176a02"
- block_height: 403
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0xd120ef8988987a3de5b82d1b73dbf94fd20b9ab5bf7b3297255bc0ea59ffcd70"
- deposit_root: "0x636af0f0424726b4060828f72a3186c6b7dfaaea3591c5e7691d3a62fe183a7f"
- deposit_count: 402
- execution_block_hash: "0x6cae019fcf9937f0efea9dc1ab3a9550aaf34af27f8e63b644f9329e61176a02"
- execution_block_height: 403
-- deposit_data:
- pubkey: "0xb049dc45fd585ef8bc67831dc47690f95e466cf11127def6ef9fdfc43017518752aff3df93c3e5f68083f590f554f3dc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9411afc1b608ca75c7e4af02d1688588ca24b611b9b7250ee87dc7504f1c60543932bf50745b64c363537ce553234a62195d605f970744979913756525764b61e274665c5811d56b13928fb1bee16a35269bc2a466726ddbff0ebde348680e50"
- deposit_data_root: "0x11af26393dac3ce8fb05c12d6ece2cfceec9489fd2d915646bb4840993138571"
- eth1_data:
- deposit_root: "0x9c778cae240d62b556752b616662c7ac895a162e9a7730ff0d52b82bf469883c"
- deposit_count: "403"
- block_hash: "0x40daf225c72e6c2923e9ad5544c472bed26439a283682bb93688fe3d88d2e76d"
- block_height: 404
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0xd120ef8988987a3de5b82d1b73dbf94fd20b9ab5bf7b3297255bc0ea59ffcd70"
- - "0x11af26393dac3ce8fb05c12d6ece2cfceec9489fd2d915646bb4840993138571"
- deposit_root: "0x9c778cae240d62b556752b616662c7ac895a162e9a7730ff0d52b82bf469883c"
- deposit_count: 403
- execution_block_hash: "0x40daf225c72e6c2923e9ad5544c472bed26439a283682bb93688fe3d88d2e76d"
- execution_block_height: 404
-- deposit_data:
- pubkey: "0xb0f4dcd488f6725946e1a384d9ae9cd6a12824dafb426e15f4b848b6dabd46ec1177fccd0fa5c0c2260fc57aaadf1e7d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91ca8e45fc3d7c4003d0ec4602231b3f86e119931a1c8d605b86d36191a2d32193bd10741920bff28e2d2d2964f01b9c034ddaf18f30d326b6f91be845c9c75ef0201cd50ff50f39c29430b7492a1e4537926c786525091e1c2c238ad4698b49"
- deposit_data_root: "0x686a7b22bebf76249ffc853c5122014578f3cb65dd2c6b70909ffce37e88150d"
- eth1_data:
- deposit_root: "0x2a08f81dd020438f364a87bf7dab7624c404e0934662a5588c924c5fa10abab1"
- deposit_count: "404"
- block_hash: "0xd4e4fc76c0e27a2f700ade91f2510b65de7045289c1c22f964ea29e2a7dca632"
- block_height: 405
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x84a7921ef234cafc908a09e2bbbdd215ec6e0c4aa800834f18fd8592b86fb2cc"
- deposit_root: "0x2a08f81dd020438f364a87bf7dab7624c404e0934662a5588c924c5fa10abab1"
- deposit_count: 404
- execution_block_hash: "0xd4e4fc76c0e27a2f700ade91f2510b65de7045289c1c22f964ea29e2a7dca632"
- execution_block_height: 405
-- deposit_data:
- pubkey: "0xb400b2f5705dbd2905c5d9fe3b2f29cedb380954a60b4fab0e55009c47e1908a30bf286f7e01b7125985c9007015f37c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb8303c6fe8a1f35b218d48f838cd459dee1422b6f202c1b710c0179817f1085c8556cb71e6b0a97ad0484349fe854f6b0d4da3f69c0e3d5708843d4c0ad4d3f2bdc1cdb40db8a654a1f708b4318274ea613e75be4d0f6c9a26a1d52d950c1f5a"
- deposit_data_root: "0x54285447a3b3f65166091d937d7557f012b904d001e24cc43c8f0899522bab1a"
- eth1_data:
- deposit_root: "0x2964d0b869c2a6da631d3e589eca0125be3775f099f3cd1e6b7013ae66384abd"
- deposit_count: "405"
- block_hash: "0x227229f14dc54a592bdd03b2d84df40d64d0e6f51dcdfdf1c42ff87a1291c6a3"
- block_height: 406
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x84a7921ef234cafc908a09e2bbbdd215ec6e0c4aa800834f18fd8592b86fb2cc"
- - "0x54285447a3b3f65166091d937d7557f012b904d001e24cc43c8f0899522bab1a"
- deposit_root: "0x2964d0b869c2a6da631d3e589eca0125be3775f099f3cd1e6b7013ae66384abd"
- deposit_count: 405
- execution_block_hash: "0x227229f14dc54a592bdd03b2d84df40d64d0e6f51dcdfdf1c42ff87a1291c6a3"
- execution_block_height: 406
-- deposit_data:
- pubkey: "0x97580566e3ddcde5b3e0cedf688aede17a8b738a21f96a0c2efff77061e232ad877e6bc71649d0fbb3ec0dde584bb8e8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb680f12cff8dff209469f418f731a144cade0471dff2ee7b656baa3d0b2ada286bafcf1487ec3ec47b1fa83823fc237211352f5d3c28842d50124206019b16a9f7baf7c22405fbfcb49123aec9289fe8a2a6d894634a936297f0bd08d591074c"
- deposit_data_root: "0x5db3228f5c2c952907c045dbb394ae8e84db47a0e25ffa40de6b58e9c6ab257c"
- eth1_data:
- deposit_root: "0x056d0f3598f7c612c9d73dd3adcb0dc54a8861b4c3df6b4df8ff7511a3966207"
- deposit_count: "406"
- block_hash: "0x5b1c9467bdfcf4b7555e748b80e684419a23798fa52716ac92aaa14186dd85b2"
- block_height: 407
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x84a7921ef234cafc908a09e2bbbdd215ec6e0c4aa800834f18fd8592b86fb2cc"
- - "0x85117723172be560339b88739cf982d8b35cb46f757778b547dbc224ef314c78"
- deposit_root: "0x056d0f3598f7c612c9d73dd3adcb0dc54a8861b4c3df6b4df8ff7511a3966207"
- deposit_count: 406
- execution_block_hash: "0x5b1c9467bdfcf4b7555e748b80e684419a23798fa52716ac92aaa14186dd85b2"
- execution_block_height: 407
-- deposit_data:
- pubkey: "0x9504350e6a3ad1a5f711d9e5904bd25b1f6571bcaa66403f1da9fc8200ebd8073308dcf462371073bd8b076fd25df949"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97cf502d6ce9a1a4dadfa044a55404625dce825856a24d235e58e31726d6c656c6848a4f614289ffdf2ce52b065780a60f2ed591833b178369bf7b84e6d7f0a5bba85e79c5a37f7d7087b54f12f78dc94fedb49668d62cf052d3d36ba14cfc6a"
- deposit_data_root: "0x1a6a9e33d429de9d71c1f84e4476edfea7c21cabaaff5663bf0737e75d503644"
- eth1_data:
- deposit_root: "0x45ce45d9a35f5bacc28372385bd446592e1198cd983a9cabf423ae68844aca63"
- deposit_count: "407"
- block_hash: "0xe25780387a9c484c23c6252bd8518d02fca68bbef3de900bb192b8bda868017f"
- block_height: 408
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x84a7921ef234cafc908a09e2bbbdd215ec6e0c4aa800834f18fd8592b86fb2cc"
- - "0x85117723172be560339b88739cf982d8b35cb46f757778b547dbc224ef314c78"
- - "0x1a6a9e33d429de9d71c1f84e4476edfea7c21cabaaff5663bf0737e75d503644"
- deposit_root: "0x45ce45d9a35f5bacc28372385bd446592e1198cd983a9cabf423ae68844aca63"
- deposit_count: 407
- execution_block_hash: "0xe25780387a9c484c23c6252bd8518d02fca68bbef3de900bb192b8bda868017f"
- execution_block_height: 408
-- deposit_data:
- pubkey: "0x94184bf24da31a8ca6561c17aa36b6933f07d4966063972bfcc6c97d8daeefd05b7c22d41fa5133327cc0dd000139175"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2147f430cef90e44d212f911fb86e018b4757593fc5830f5df7c227d66c3f9498ea97f5d74fad123e7a1485589d17d90297d6203e5a815a8e154d548daa55b9f13901bc297b8fd4e6ccb909dbc8fd2f93a889d64186fc2f9a4be67496d97b61"
- deposit_data_root: "0x687e4fa71fd82af6ccca467fb6b5e48f142ad7fc09fd986e2d2c12bc08e2e318"
- eth1_data:
- deposit_root: "0x85996ca4642a553cc8fcf6d1c797c38df7fa374a2a8a420064114c4b7b576779"
- deposit_count: "408"
- block_hash: "0xa1d4a35fa123ddccc268e408c9c03c5351b323e42eeae7b8415b67725957f8dd"
- block_height: 409
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- deposit_root: "0x85996ca4642a553cc8fcf6d1c797c38df7fa374a2a8a420064114c4b7b576779"
- deposit_count: 408
- execution_block_hash: "0xa1d4a35fa123ddccc268e408c9c03c5351b323e42eeae7b8415b67725957f8dd"
- execution_block_height: 409
-- deposit_data:
- pubkey: "0xb88add150c36e8c338f7ff8efa8efb4e302a5a01afb8e331282eb075ffc3f2f5e5e783a4cef6a0d9c65dbedea48cc093"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xadc8bcc68efed61ce4039fba63c806c6e59282810427369f0967c765e052048304bcb76104660d30ca2667f406c445160240514f7b07c762a83e1f7a27e5cb7b4fc81b40b5a4f8d24fb3cb1640129132578819e404da56557e5f6988e8064708"
- deposit_data_root: "0x99422ecd07eaabd6d3d3380ff689d77656e191b82317f01a8ca95cbc98210d4c"
- eth1_data:
- deposit_root: "0x8d152a557390c7b500d1a4eda65c8491268e58d25a936cb8e032eb06be13de35"
- deposit_count: "409"
- block_hash: "0x864f7b84cd151b4359c1767fd03f15e94769a4a96b65a3e299b7984d6cd397e6"
- block_height: 410
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0x99422ecd07eaabd6d3d3380ff689d77656e191b82317f01a8ca95cbc98210d4c"
- deposit_root: "0x8d152a557390c7b500d1a4eda65c8491268e58d25a936cb8e032eb06be13de35"
- deposit_count: 409
- execution_block_hash: "0x864f7b84cd151b4359c1767fd03f15e94769a4a96b65a3e299b7984d6cd397e6"
- execution_block_height: 410
-- deposit_data:
- pubkey: "0xb25827b6746a0ed3bf133beb7e465ba08c39e1960c4555a81384502d6c244bdd7ca19f521c6d192436d71dfafa64b4a6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96aa871044bff32644f18d02e67e8dc0755621ed06eed2928626f653aa927e8976f39447954e3e0737533488633a319f16e573f70137eb877bc792b12df25b72847efa7c334309070109492bdd07b6f12641ef30895d71503755f6bd186a373d"
- deposit_data_root: "0xbe183759a8073454fc423aba202855bb3537be2a6772f75617206143e492583c"
- eth1_data:
- deposit_root: "0x3e6105f13f3575420640b86bf5967844ef363dbd91cd6d2f3d7b55bb2cafa1cb"
- deposit_count: "410"
- block_hash: "0xf59f3ccc775a6fd25443c8bd4d39aee5653b9399d8db7028a1244b2b36fa601a"
- block_height: 411
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0x8938612c24e370ad407b03900d58216a3677570a6393d86c1199e168ac50d0f4"
- deposit_root: "0x3e6105f13f3575420640b86bf5967844ef363dbd91cd6d2f3d7b55bb2cafa1cb"
- deposit_count: 410
- execution_block_hash: "0xf59f3ccc775a6fd25443c8bd4d39aee5653b9399d8db7028a1244b2b36fa601a"
- execution_block_height: 411
-- deposit_data:
- pubkey: "0xb5ed6e77bd6f1661a5ab3f2e13743385c7ee99dc240e9575b3e7639b4f73a017cf4edbd0932e02577acd2bec274be3fc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9304d4d21d94213e2e17afba7d41167249086d34837591a7ebaa998ad31dc2085f1f11cfc01b9a0651dc5bbc4785a9f6084549527e1d9f4a256d9d6b73a1cebcbd10c9e88984acc11ca85eb8d5ff5b53cecb6bc4a366bb5cc3a82db259accf9d"
- deposit_data_root: "0x56410aabb7658f5072e9d3caaafc6d06931ecd574f6af0b0c6780765b81b2efe"
- eth1_data:
- deposit_root: "0xf81fa25a4547d3ea55b14e7ac66c2e4d9f96c32c843d3ccf32efc7e625142204"
- deposit_count: "411"
- block_hash: "0x2ed4ba87f94e8bf64d8fa37d0b7cb7a67eeddfd408a8838ee62cdf8b63e36533"
- block_height: 412
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0x8938612c24e370ad407b03900d58216a3677570a6393d86c1199e168ac50d0f4"
- - "0x56410aabb7658f5072e9d3caaafc6d06931ecd574f6af0b0c6780765b81b2efe"
- deposit_root: "0xf81fa25a4547d3ea55b14e7ac66c2e4d9f96c32c843d3ccf32efc7e625142204"
- deposit_count: 411
- execution_block_hash: "0x2ed4ba87f94e8bf64d8fa37d0b7cb7a67eeddfd408a8838ee62cdf8b63e36533"
- execution_block_height: 412
-- deposit_data:
- pubkey: "0xa25579ff3efe83b344ac7ca26d45d5aac4fd4fdb1809f20e4e48026e154e95d7ea8c7abf6e91628f8448a6a798dd07f3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8915d4d355035a608f37b9c2402a9c3b95ef8c68209b0607cc8bcdc4f10a47a12b0708da53442b82348470e179f128bb02192b872b8ea16d388ed77ac173e4b9ae9456734fc33cc05b6bce98dbcb8f69bfae7583286ed548b4711916eb059055"
- deposit_data_root: "0xb55d26ad397fe717b187f5c40e5103bee6c3ba6d8a2b0d73a357f950fd172c34"
- eth1_data:
- deposit_root: "0x1d2b4ebde6a17b6badc11d3f4a4d67e5938f2b536fed42e015b6ae501b88bbe9"
- deposit_count: "412"
- block_hash: "0x616b1268dbde68f7f9ba43b43cbd7f721c94d1ae793f0101334af4ad8d8e82ec"
- block_height: 413
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0xa1c5ec665c8d856db67a8496e9dc6082278b339bf70b3a4f35f6d79670fa00e7"
- deposit_root: "0x1d2b4ebde6a17b6badc11d3f4a4d67e5938f2b536fed42e015b6ae501b88bbe9"
- deposit_count: 412
- execution_block_hash: "0x616b1268dbde68f7f9ba43b43cbd7f721c94d1ae793f0101334af4ad8d8e82ec"
- execution_block_height: 413
-- deposit_data:
- pubkey: "0x81dc3529a283023f70fec5eb65ef8e3b394b0239bfe40095574a881c5dbe536a6b119e6cc95668b62d6e5944386c07ca"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89053f18cbf904592529a1710bd771229ebf0709d2c637684eae158bdd5821469dcbe1263d3649a8e04b92d2d7e326ba1895598c591a69fd1048f58d2d34c1cc432dab87f8f0bed2afee9500f92ea000462b9ffb80f5ca409e0d05ab8b821aca"
- deposit_data_root: "0x315194fcfff6c0dc8855f81729f8993f67b38330dbec183119694e330fec78af"
- eth1_data:
- deposit_root: "0x3801e05532040093e13e5b25b9afb7ebc97618181c41afec4e929e7cf8458a24"
- deposit_count: "413"
- block_hash: "0xc49c428e319c98556fa261f9a6a3184d5149ea8cb773b47fef238c2f8d696641"
- block_height: 414
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0xa1c5ec665c8d856db67a8496e9dc6082278b339bf70b3a4f35f6d79670fa00e7"
- - "0x315194fcfff6c0dc8855f81729f8993f67b38330dbec183119694e330fec78af"
- deposit_root: "0x3801e05532040093e13e5b25b9afb7ebc97618181c41afec4e929e7cf8458a24"
- deposit_count: 413
- execution_block_hash: "0xc49c428e319c98556fa261f9a6a3184d5149ea8cb773b47fef238c2f8d696641"
- execution_block_height: 414
-- deposit_data:
- pubkey: "0x93da5217b698dcee39d36c25bd79f2a152e5053add9e4b17cf60cc5dadc0e2d1713d05f7b5917840b6748d25d68f4878"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaeebc4af4e5b90582f890827b760f39de6f9adf57afe53e74fa7dc7718e1a1ff4f70eb119c2f1042ee9d06264c07347b0d052699ba9145d7c3e38ffbc2d23d75f15c169b88e35810317e80281889f5a86248d05110ac7ce727996de71967cb29"
- deposit_data_root: "0x38ae0e785551cf674706d6ec349cb2a8061d5a6175b87857f9c9a9f51631cd71"
- eth1_data:
- deposit_root: "0x64149d892f598e8b77cb82d9ec6795bb77780c16ec7519ba12d9a3dce230179c"
- deposit_count: "414"
- block_hash: "0xa79d343f7dca460ec92a84fe1186ecbee2f9bef1270a4cf1999cf944a86f85ae"
- block_height: 415
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0xa1c5ec665c8d856db67a8496e9dc6082278b339bf70b3a4f35f6d79670fa00e7"
- - "0x48e639af938e1404ea96c354be4721b397a5acce7ffa49d37f8573ee8158a522"
- deposit_root: "0x64149d892f598e8b77cb82d9ec6795bb77780c16ec7519ba12d9a3dce230179c"
- deposit_count: 414
- execution_block_hash: "0xa79d343f7dca460ec92a84fe1186ecbee2f9bef1270a4cf1999cf944a86f85ae"
- execution_block_height: 415
-- deposit_data:
- pubkey: "0xb54437d1547e9a87476f03c094c86465f36376c09ef3c8fba0c8906fdeb0421d523a20ab6ce6ee18da9fbab39ede3bee"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9334c266b645d6cc2dc62f8dd0e6ec5224dacee0db27c912db0b41422bcbc20f85589fb41bfd51d22ee7030c75b52c6c0a54185c8385f95a36e97d241f32f0b903caaaea7e2cf27ec93870c1264f2ed07d73e84fac7402f03ebf77b9b5464321"
- deposit_data_root: "0xaf029eb95db881e01d26610b29fb72f3e787f515905568178e89caadffceafe5"
- eth1_data:
- deposit_root: "0x3f34a92f21f233bbf81b0c43288483f2e79ce0d95351eecc830a97b3dcec3eac"
- deposit_count: "415"
- block_hash: "0x455ef1eda7e29f3ed4bbb1c6d34330abd172c4626032644f0242b4d4defa1835"
- block_height: 416
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xec52edc11cb65e2c16d2dfd0ab3223c608e768e70c9e808e0a0196c82ad1736f"
- - "0x0901c3b3e1bacfae214532d21ac897c470123fae6d333b9af964c91ea57d286b"
- - "0xa1c5ec665c8d856db67a8496e9dc6082278b339bf70b3a4f35f6d79670fa00e7"
- - "0x48e639af938e1404ea96c354be4721b397a5acce7ffa49d37f8573ee8158a522"
- - "0xaf029eb95db881e01d26610b29fb72f3e787f515905568178e89caadffceafe5"
- deposit_root: "0x3f34a92f21f233bbf81b0c43288483f2e79ce0d95351eecc830a97b3dcec3eac"
- deposit_count: 415
- execution_block_hash: "0x455ef1eda7e29f3ed4bbb1c6d34330abd172c4626032644f0242b4d4defa1835"
- execution_block_height: 416
-- deposit_data:
- pubkey: "0xaa5367fff8db3ba5017bc601e9f9ceb867d54c3b17ade967b0bc905f644f6aadc8aa53d3e9ed0e278bf3fc2b0b56a7b2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b8a5f542223fdd7170978a36e904c31ec430dd68cd608a3aaac5b6514f1e817e1bb2374aa7359e85d0c280f17c99daa0049c57e853088b8ae3a23d77911c12d6094558aec8dff5a9dc917d7799e6a86d06bb54b394473fd4fdcd273868581f3"
- deposit_data_root: "0xd202196054c6e1cfa6f16d82399ef65d80f0765564b15c5111da4720bec9b495"
- eth1_data:
- deposit_root: "0x2bbfa716fadba6b4b1d4d2b4cbd5b031bad662ad0a18d60f8fae3a9ff2238c8f"
- deposit_count: "416"
- block_hash: "0x376a52185e4457c7d3536a168e21870ecbb58babc27d4a74189316e089e4a69c"
- block_height: 417
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- deposit_root: "0x2bbfa716fadba6b4b1d4d2b4cbd5b031bad662ad0a18d60f8fae3a9ff2238c8f"
- deposit_count: 416
- execution_block_hash: "0x376a52185e4457c7d3536a168e21870ecbb58babc27d4a74189316e089e4a69c"
- execution_block_height: 417
-- deposit_data:
- pubkey: "0x874305f7d11e69b74164cad10ab88ea7df22208c954fcb6872f34a5f9c8292341f85a6250716270563a19b5a112761d4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae8bde36d9ebdb5a259f005703d09b72d1828bb4b4dffbab5e145f1bc0cc857b24ba1365ead8ce0953aa67e3afa4c9a40fc79fc0da93c7a5b350e0c528f91fe7a1b124c27d0d622711be2a85abe3078010c584576b919e438721dcfe7a5f6d1c"
- deposit_data_root: "0x0e431cf7531088ea8e7aa4b2ad1e3a2971548ab2fc6967219a91861599293180"
- eth1_data:
- deposit_root: "0x0cc28d5ecfca85f1d141d409373c12e5ef93e7fab9d3d667737b8e3e8b9d567d"
- deposit_count: "417"
- block_hash: "0xcc9737753a8b74792a5df80adaa5eeeb97c6d8656eaee16fcfb04a63bddd791a"
- block_height: 418
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x0e431cf7531088ea8e7aa4b2ad1e3a2971548ab2fc6967219a91861599293180"
- deposit_root: "0x0cc28d5ecfca85f1d141d409373c12e5ef93e7fab9d3d667737b8e3e8b9d567d"
- deposit_count: 417
- execution_block_hash: "0xcc9737753a8b74792a5df80adaa5eeeb97c6d8656eaee16fcfb04a63bddd791a"
- execution_block_height: 418
-- deposit_data:
- pubkey: "0x96917c5ff8bd2debf697fbc64455d19cf1efc4e1327b3dde2eef7db7cab762effb43025c4162db0008a0b43b4d060748"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa16d8a141171087108c9f042e0915736a0eb801ccaf8b889a124bd6d53eaffef6518a982b0214e9b6c9a95860d5a2da50f5b3eef099489a927545bbbba3d9e0126f7720c367e93bbb64353d8b7b86363792c35e1d812fedc3495921910051be7"
- deposit_data_root: "0x3dab6d15efd096307e6d2f0f3465f10a35147b60564a52e9a69c2a9d20c16a2d"
- eth1_data:
- deposit_root: "0xcb8c6981b53a98be40422412d265fd54abc7329f49ba6028981465210544c9c0"
- deposit_count: "418"
- block_hash: "0x3fb793716ced3b8a456415e801d6e847ee18b269ae9600bb2b42d698d23c6d17"
- block_height: 419
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x696db144fa18876c4f737f199bf14a3d8922bd7a5c7469f783cd255b766ac02b"
- deposit_root: "0xcb8c6981b53a98be40422412d265fd54abc7329f49ba6028981465210544c9c0"
- deposit_count: 418
- execution_block_hash: "0x3fb793716ced3b8a456415e801d6e847ee18b269ae9600bb2b42d698d23c6d17"
- execution_block_height: 419
-- deposit_data:
- pubkey: "0xae77044f5f689ef3c59fbb1afc7fa2e33c5406121f9c2eb1dd089cb320b9d82ab51d6fadb545327dfcc2688c201e9e07"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2229d26b8942b36b25e0231246148d635c4abf51fbab950efea2e4f0e4a9b7f6f9ee366636bc42801930330fd7b197a11cac3cec7abfccfa29323a2810f2d209ba953a45bf11058bf438d66cec626c4c6be647cc6c0c88fe372e333863d5766"
- deposit_data_root: "0xb1532d97dbb8c85040e1ebc08649670b8980fd97cae2e23ab7f1b5af06c1f597"
- eth1_data:
- deposit_root: "0x76d0915685d7293f2ad3c227cfd6208d198fc11d6eb154dca9ebf9f08b57a863"
- deposit_count: "419"
- block_hash: "0x08a0fbfdd1c3183824d6f51a123e89b1a8dd1c208dea3a167bb8c47ff7697390"
- block_height: 420
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x696db144fa18876c4f737f199bf14a3d8922bd7a5c7469f783cd255b766ac02b"
- - "0xb1532d97dbb8c85040e1ebc08649670b8980fd97cae2e23ab7f1b5af06c1f597"
- deposit_root: "0x76d0915685d7293f2ad3c227cfd6208d198fc11d6eb154dca9ebf9f08b57a863"
- deposit_count: 419
- execution_block_hash: "0x08a0fbfdd1c3183824d6f51a123e89b1a8dd1c208dea3a167bb8c47ff7697390"
- execution_block_height: 420
-- deposit_data:
- pubkey: "0xa174a13601df492b77a263ff54d9e30a0d9b248a1bfc559a4bbeb251fead9b72790f08bed89dbf224c1cb5548c44abab"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a8d011198c4e426421f2563dbf5552ba950849f6b404a77de5f397f470ad349fc35c62df521f34d4ce8e5135f514df11654c7868da1b45d6d10193597cb0e1c33b8bff2f005c2eba783f1e7f5526cc85be30fda5d481ecc526b5a0a5733815d"
- deposit_data_root: "0xb5100ee2bc58e4bcbeb35010d28c99f25f30db2dee32e8d8be5abfff81c6b980"
- eth1_data:
- deposit_root: "0x4fbb0a4745d73910a0e83ed47c036e561d5a974ba373106f4be04ee184f68009"
- deposit_count: "420"
- block_hash: "0x8644b9495ba9e4ea664a3d613b9aceb7e8a7efb507635cf2eea237ccfb3eeb5c"
- block_height: 421
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xfb785265dae57039dc1b110d2edb8556f05c9f2013e0cd5b57982be1642c2375"
- deposit_root: "0x4fbb0a4745d73910a0e83ed47c036e561d5a974ba373106f4be04ee184f68009"
- deposit_count: 420
- execution_block_hash: "0x8644b9495ba9e4ea664a3d613b9aceb7e8a7efb507635cf2eea237ccfb3eeb5c"
- execution_block_height: 421
-- deposit_data:
- pubkey: "0x88a09d6756a015068efa04c8fca73dd96e2314e4f6e9d1aefdf19ef139eccb2000c3f382a18a3ade202641ed2c4b4267"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8bae90cb3fad0db9242b14e40a799f7ad163ca2a720864f4abdb6e28a352d19655d557420a4f4965108d247c82d3cf050224c04aecf9a351e57cfc008e27b60c991b02446d19ef1f3bb6f6bc932010d9bf6c54b4b09afd8131fd2d95fac89c11"
- deposit_data_root: "0x87c39cef2326f57395a3143b07c46e7077d23cab48b40a25631ba38381e3f15a"
- eth1_data:
- deposit_root: "0x1bf71fb13806bd931b817a8be4dc90de192c8f2baafc12d99eb8ed922bcf53a3"
- deposit_count: "421"
- block_hash: "0xad379a83ea80b1aae55e118cdadfb133bbcedb14842e6a1a1fe4cdae049d0739"
- block_height: 422
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xfb785265dae57039dc1b110d2edb8556f05c9f2013e0cd5b57982be1642c2375"
- - "0x87c39cef2326f57395a3143b07c46e7077d23cab48b40a25631ba38381e3f15a"
- deposit_root: "0x1bf71fb13806bd931b817a8be4dc90de192c8f2baafc12d99eb8ed922bcf53a3"
- deposit_count: 421
- execution_block_hash: "0xad379a83ea80b1aae55e118cdadfb133bbcedb14842e6a1a1fe4cdae049d0739"
- execution_block_height: 422
-- deposit_data:
- pubkey: "0xb41b17006e2a6a6bce8055ee459557cf835fccaa851885903846dc190adc223f6cad199446ca225b6a65d40382344227"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8c1ba3a40657d6fc08753d00115125acec2821bfcdb6e272758086cf5eb38f6653924da5b296a24ec4099958edb6c42d1539bafe103f62c926d09f03424abb0cf189985dfbf042fee90cdc4efb1204eb251825a9b5771862686271c0744ea62f"
- deposit_data_root: "0xdcfe0566760412e34ef921467df75a7ab63ba33709d01ec51509c229ea7f1f8b"
- eth1_data:
- deposit_root: "0x7ea9a20183569c27fa282cf8f41035a826ad1a4055bc201b03bfffd70a4ebf7d"
- deposit_count: "422"
- block_hash: "0x623deab0585c9ba3256328022621d3ea83974a0e95bd98cb4974fab7ff84c458"
- block_height: 423
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xfb785265dae57039dc1b110d2edb8556f05c9f2013e0cd5b57982be1642c2375"
- - "0xaab1605a8179a12b1e4e07684af74b5398445a216df5219be25801f44d75d56e"
- deposit_root: "0x7ea9a20183569c27fa282cf8f41035a826ad1a4055bc201b03bfffd70a4ebf7d"
- deposit_count: 422
- execution_block_hash: "0x623deab0585c9ba3256328022621d3ea83974a0e95bd98cb4974fab7ff84c458"
- execution_block_height: 423
-- deposit_data:
- pubkey: "0xaf9a969a70272ac2871fd689f13c0b478e27bdc5127f02c41efabd5814a902dc1e3ed8b3ca1786aafb8f112aa3c87db7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4b4f5e4b3bab060290c43259af77f83aab46b0d5b47cf7ec63e252bc1a1cbf4473bc03b6e0d70cd822d80b93a5d686109087af68ec598e991234c5692ca91844404d7be411ed10fe57100f9d29a89fbca2b3869ab58177079fb916d7a488573"
- deposit_data_root: "0xed7664e9d1230b810ae66e70f7216a6cfc8dd8dfffb6781b25a724317713c991"
- eth1_data:
- deposit_root: "0xd4d4345b1ff711661fd8c50cb40512e1535b1e50b1abc36db5ca5ddc1d998963"
- deposit_count: "423"
- block_hash: "0x76d7667e463891a1f70c269d1a0113126715969b01f74733050cf0fed12f1f41"
- block_height: 424
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xfb785265dae57039dc1b110d2edb8556f05c9f2013e0cd5b57982be1642c2375"
- - "0xaab1605a8179a12b1e4e07684af74b5398445a216df5219be25801f44d75d56e"
- - "0xed7664e9d1230b810ae66e70f7216a6cfc8dd8dfffb6781b25a724317713c991"
- deposit_root: "0xd4d4345b1ff711661fd8c50cb40512e1535b1e50b1abc36db5ca5ddc1d998963"
- deposit_count: 423
- execution_block_hash: "0x76d7667e463891a1f70c269d1a0113126715969b01f74733050cf0fed12f1f41"
- execution_block_height: 424
-- deposit_data:
- pubkey: "0x8faef0de1c486a7638c2a50af8f34e42b7f11bc1168c03678408702f8d11637f1faf893955a39897d797c851d1e6267e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa03d1ab7e650e5b593fc076f109653b6ab3bcbd4ab214a638c91c182073d90e44dadd8243ec6b6055a08d7876d67231d11be579189b12e04ae0f6aa2071fbfa25680102c2cd9612955bd5ccd11e6924acc1aca90f17939eb50e364484707d58a"
- deposit_data_root: "0x618c9f801c71c3abb9c4a6b58ecd7bb0ee58537066ab15c04b86466d53acc316"
- eth1_data:
- deposit_root: "0x0ff9c5f8f3fce635e0c513c911e919396b682a34471d7a6d95f709fdd15c8713"
- deposit_count: "424"
- block_hash: "0x987c1a8ce6e27f94a0bac01816f3f4f54c057350d36bee07c00d83a62555e92b"
- block_height: 425
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- deposit_root: "0x0ff9c5f8f3fce635e0c513c911e919396b682a34471d7a6d95f709fdd15c8713"
- deposit_count: 424
- execution_block_hash: "0x987c1a8ce6e27f94a0bac01816f3f4f54c057350d36bee07c00d83a62555e92b"
- execution_block_height: 425
-- deposit_data:
- pubkey: "0x95bff09876e40fee59003b08bab452d9bd2dfae2c6411e153c4fc531f4aa26af8966049cf303865472d56643e3a3ad70"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa74bde4e1b2c55840198a66fd62671eee5e81c69c0d8418eb07c16c2003ba3eef1b8a7454b4fe1df5108e22bd8710288053fc45216787688320c3bebda2fb6e0402035ec9aa54f3f23e27c541e602f7fbbd4a259f5e359592486d027da49df31"
- deposit_data_root: "0x370e5d74a292574246d28b1c7e721565b32b960f041768ff4727d395b42de7d7"
- eth1_data:
- deposit_root: "0x1e3367c89e570fe259bed5fe2dcaaf6cdf1130c88b0cbdbe3880cb020a578772"
- deposit_count: "425"
- block_hash: "0xaad57c3a976f49af3a86b03765169a35d6d785bb020ff2cf5ce6e6725d4e5669"
- block_height: 426
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0x370e5d74a292574246d28b1c7e721565b32b960f041768ff4727d395b42de7d7"
- deposit_root: "0x1e3367c89e570fe259bed5fe2dcaaf6cdf1130c88b0cbdbe3880cb020a578772"
- deposit_count: 425
- execution_block_hash: "0xaad57c3a976f49af3a86b03765169a35d6d785bb020ff2cf5ce6e6725d4e5669"
- execution_block_height: 426
-- deposit_data:
- pubkey: "0xa186ad3532db69f509d3f38223e388c9300031630ae02c5e13e6b55db6094554647fe52dbad51f931678c43d97f6b4c6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9464130c7ad45c27345e3383ba1e3a94ef7e5691fd9abd97b0cbd7c253a744ed2e953c561aa7196d2326a75c7a2410c4115b0968abf336ca7fa9414ab9580aa12b42e5bf991863df7ac526b8b00624704f025e6f8cdbdfb21411492fc0f30b38"
- deposit_data_root: "0x7d7cc85629154e45c92dcc1032aea2cb10f384ef24c4d8903cf3f6f7f4140a11"
- eth1_data:
- deposit_root: "0x2b3611ca950982c5bef154794766299407c48416ca3e3326072e108f83081f01"
- deposit_count: "426"
- block_hash: "0x34b26f56bc1b5b8b92acee8b5514178a4e1262479ba3c67294330a2d9dab14c8"
- block_height: 427
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0x7f0c9697e17536d1ed08f791074bb7a4acf1a34de4a9d0e99d8e5057c1cd13f3"
- deposit_root: "0x2b3611ca950982c5bef154794766299407c48416ca3e3326072e108f83081f01"
- deposit_count: 426
- execution_block_hash: "0x34b26f56bc1b5b8b92acee8b5514178a4e1262479ba3c67294330a2d9dab14c8"
- execution_block_height: 427
-- deposit_data:
- pubkey: "0x976ecc14c14c93f8d0bcd6ee0a6f829de29fc13e167204e83d9c13d69065994af9c38424443114913e3142ca96138094"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x891aaeebcf8b8e5fbf12ae568c2782ac6ef3d42856d9476d12e7638bebd5f669bbaae802a46d7b9a41ea456547434ed806b583f696903bcc2a032961e7f123b4c0dc71356edb0db37de478452407fb48984e3d174fc821f707de94a67ef81100"
- deposit_data_root: "0x3e4beb332aee13ce0e48353814b5368e9571a2467f070677265eb9b41c1514d3"
- eth1_data:
- deposit_root: "0x3b62cf4ee50ca126c3da8052bae1db595a921d5aa400aa5a4e7b14750e8aaa5b"
- deposit_count: "427"
- block_hash: "0xfee92ed291741bf5c0e55f66775aa3b61a501b735d0b4b1c633dc48a1da857d5"
- block_height: 428
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0x7f0c9697e17536d1ed08f791074bb7a4acf1a34de4a9d0e99d8e5057c1cd13f3"
- - "0x3e4beb332aee13ce0e48353814b5368e9571a2467f070677265eb9b41c1514d3"
- deposit_root: "0x3b62cf4ee50ca126c3da8052bae1db595a921d5aa400aa5a4e7b14750e8aaa5b"
- deposit_count: 427
- execution_block_hash: "0xfee92ed291741bf5c0e55f66775aa3b61a501b735d0b4b1c633dc48a1da857d5"
- execution_block_height: 428
-- deposit_data:
- pubkey: "0x847ec3a8b963b0a40506ad2e2a2f9119456d36150eeb64856f12c85a85e12d59b295d953d845246be5aeccfb70c1dc04"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb9cb0dfb5fcb39c230277f2574438a7c19d54a4ec2e3e2ffe7129f492ddca723f92f30e73dcd08649dbd534ca2cf2adf1002df9dadd275afc05f4043b5ff7dbe6e85db48ccc1b2939652c7c2dd67553d40935ec4c8f6af52125096afaea8bdaf"
- deposit_data_root: "0x7246ac04b767468d6e6962003af7f3c181600a6061e568046b7d4674a8cb6ba9"
- eth1_data:
- deposit_root: "0xd644b836a3cddf49cc1de8df9b2147a89e2cfcfe1eb18ea7d5af3415d20c5adc"
- deposit_count: "428"
- block_hash: "0x50f3f0653ab23862d6539b59676e3f7b9d7af24750232050ac04473e7d14c2ca"
- block_height: 429
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0xabd7629e265df3c45f91829f510911e1a6dc607cf1967e4cf7a6a1978741a35e"
- deposit_root: "0xd644b836a3cddf49cc1de8df9b2147a89e2cfcfe1eb18ea7d5af3415d20c5adc"
- deposit_count: 428
- execution_block_hash: "0x50f3f0653ab23862d6539b59676e3f7b9d7af24750232050ac04473e7d14c2ca"
- execution_block_height: 429
-- deposit_data:
- pubkey: "0xa6be6fc30a561b92e84333e413ce5be1d83de64ff5cef73611840fde672bf26763901912b37dfd8f1af85c3af87c8718"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x97b2556b101e1c5b723317713a0bc7ec78848d693b16475f1d0ef7679a75189510913cd7e211a9347242dfaae7ebd71e05010b840b2920cc1a36b4402ddbbab8d299b67cf49a171c8a39b30c75880a455f2055717a5021e390f1073d398825f4"
- deposit_data_root: "0x28bacf6966c371a93169d29ba14a8a7f29b578c65832e521502eec860369c813"
- eth1_data:
- deposit_root: "0xbfc44c7d1d7f6b4df91c5cf86fa7b578915638c69752caa00aac61cc88f2531d"
- deposit_count: "429"
- block_hash: "0xd6afed7b6d18bb3524ad6fb17e2c46acdbcfbb3197f82e2b287d17e945a2b8cd"
- block_height: 430
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0xabd7629e265df3c45f91829f510911e1a6dc607cf1967e4cf7a6a1978741a35e"
- - "0x28bacf6966c371a93169d29ba14a8a7f29b578c65832e521502eec860369c813"
- deposit_root: "0xbfc44c7d1d7f6b4df91c5cf86fa7b578915638c69752caa00aac61cc88f2531d"
- deposit_count: 429
- execution_block_hash: "0xd6afed7b6d18bb3524ad6fb17e2c46acdbcfbb3197f82e2b287d17e945a2b8cd"
- execution_block_height: 430
-- deposit_data:
- pubkey: "0xb1ea18e5c0a7424d06a9e77c65f2ff5047b5c4530e34e700c0d1bf15579e2afad228a8213c68eff8c14353d2e1f10053"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa965b7ec3ba5eb7d723ae622732f9398f875bffb7941b121c14daace185523a42e662151832132b8b296903c4432f77b02e06400a84268834eae712813f6bd4af66e571fd397c2dca316dba4c5ef7091ada36ddd5726d1db8e1e1f8ef6c40f6e"
- deposit_data_root: "0x81e40c00c14deb34eb65e0a158104b60554fd0624bfa86b560cddcd29eb66750"
- eth1_data:
- deposit_root: "0x46bb5f072f410bcb56d1f87830a0db231802265dec6ac59acd451360db8f3eab"
- deposit_count: "430"
- block_hash: "0xefef471cb7829f27db63a66917e6141f86a58f90c076f54a2ea35302ac6bb5d3"
- block_height: 431
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0xabd7629e265df3c45f91829f510911e1a6dc607cf1967e4cf7a6a1978741a35e"
- - "0x3bbb471bc80341245a119253a0bd27206485c8d671ce2ab1904d70b635c83297"
- deposit_root: "0x46bb5f072f410bcb56d1f87830a0db231802265dec6ac59acd451360db8f3eab"
- deposit_count: 430
- execution_block_hash: "0xefef471cb7829f27db63a66917e6141f86a58f90c076f54a2ea35302ac6bb5d3"
- execution_block_height: 431
-- deposit_data:
- pubkey: "0x8fff13510ac685f51ae914b7177bdf296ecd757385442ea0dbfc8841685b79b7d52c780a40e07723ea34d6179c6f3ee8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb501c7b840d94f74b23e82caa150fd57a830cc20a665a84267e069fb8a93ccc56e7faae237f875e910a533a8eaa20cce06783be38427523d18ceb88bb4fef649c256ea05bd54cde8e05bf82826857e023afdfad82da136a1586ff0cd23435430"
- deposit_data_root: "0xabffe715ca708ebf5bebea360ea9c27f48e040dccc482bce560d84cf0c0f364f"
- eth1_data:
- deposit_root: "0x19e7f6f59f1a6bfc99344743800d79127bfa93e93118783888f7fd6bc3d23087"
- deposit_count: "431"
- block_hash: "0xe61cdc39257cdd0b1d973ef37bde4c7ad35fd8b5bd245be06da6a869f3be5364"
- block_height: 432
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0x60f09c9d72bd6a4e2cbb2f9f54623e280baddba85f8c51e5a07912c0782c2997"
- - "0xabd7629e265df3c45f91829f510911e1a6dc607cf1967e4cf7a6a1978741a35e"
- - "0x3bbb471bc80341245a119253a0bd27206485c8d671ce2ab1904d70b635c83297"
- - "0xabffe715ca708ebf5bebea360ea9c27f48e040dccc482bce560d84cf0c0f364f"
- deposit_root: "0x19e7f6f59f1a6bfc99344743800d79127bfa93e93118783888f7fd6bc3d23087"
- deposit_count: 431
- execution_block_hash: "0xe61cdc39257cdd0b1d973ef37bde4c7ad35fd8b5bd245be06da6a869f3be5364"
- execution_block_height: 432
-- deposit_data:
- pubkey: "0xad2d0e0c00b5a16d50a4ae56a3c0cf2e1b2263e2dd53ddad54679cdbf338300e1003af5ecb73ac3dacb8636661e142d5"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x841c98171049ea19762d010391bf195c097c130667801133259262d06ab7464e26cf14bf0dac3c8d08890db416a3301519474ab35920fd9ea961ebe80ae7a076f609fcf8cadf99c3bd46aac91456c6f543783cd042525bad6fe94730755330da"
- deposit_data_root: "0xa2a0f194432b58ec992b183815bfd4f21a1acdde93677175ec830dc8ada25092"
- eth1_data:
- deposit_root: "0x83784abcabf728772306f379a348e2329b6b03428e8120b6deb3ba1aefba2407"
- deposit_count: "432"
- block_hash: "0x98b16968453d04262b7c05ee1a2b09bcbcf8e29473c6d1a74bcaa3d03af6eccb"
- block_height: 433
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- deposit_root: "0x83784abcabf728772306f379a348e2329b6b03428e8120b6deb3ba1aefba2407"
- deposit_count: 432
- execution_block_hash: "0x98b16968453d04262b7c05ee1a2b09bcbcf8e29473c6d1a74bcaa3d03af6eccb"
- execution_block_height: 433
-- deposit_data:
- pubkey: "0xb854086bc1f668ad8ccc4ed3a7a52eab65210717c3f8b9e6ebc27c1cf27ccba0a4056311c69cfefe875fa45e2cd26e69"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa94b7daed00dd9fdacdb5cdc0635b588e5c3ab124438d7a1a59b068708e2fc3de327e35ce66800db13f100ca332db93219ff60525e13d868c66b5920d76c38c4264b9e68ada4586642ca4f02ec33438989c7f1d00cb9b02dd49dfc47d401d8f8"
- deposit_data_root: "0xda7276d3cd6c2ea2db69550570f8721ecb14d9e122e35c2d6090c600ad286bd9"
- eth1_data:
- deposit_root: "0x25028b90b69a3ff62a7a3cb3e67cf58130aa8868027f3b41613d71e8156162c8"
- deposit_count: "433"
- block_hash: "0xa783b7745e047a84c6270ab3910a09b000044ee37bca6caa2446153767236733"
- block_height: 434
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xda7276d3cd6c2ea2db69550570f8721ecb14d9e122e35c2d6090c600ad286bd9"
- deposit_root: "0x25028b90b69a3ff62a7a3cb3e67cf58130aa8868027f3b41613d71e8156162c8"
- deposit_count: 433
- execution_block_hash: "0xa783b7745e047a84c6270ab3910a09b000044ee37bca6caa2446153767236733"
- execution_block_height: 434
-- deposit_data:
- pubkey: "0x95000d5a88212033fcc30690e930c2128685b97f26a9e2c52b75e1fb562a1db1b9af071207823ef1927db3ca65ee00ef"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8444dfc139521e5236c5f5637cfa17c87b6fd06e5ca8d4e33e522f02cf9fee562903dcd42f173696c981e1113be5bee5102f84730a31c9e03b45b753178c65d87335bf82cd600384fc4d03151ca94880b0df31bad1ab4f09d760c604ca16487a"
- deposit_data_root: "0x184c58ea01f5c0c47d5dec98d30cfd9edeb11060b1c931cb3d117fd5cd6d7c4a"
- eth1_data:
- deposit_root: "0xbd639adce24d58cfbc0f226d6a045f400506c30d3388b4e520816c2ad1a5776d"
- deposit_count: "434"
- block_hash: "0xa36bde80ad1b5c6fa8848e656ef5c9c95411042e1fff4ffc23b4bc2bcb7e6bee"
- block_height: 435
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x923555fa4c1bad92de2ae74472f84089b9f15bfcf562d84eb249313dc6bb6ae2"
- deposit_root: "0xbd639adce24d58cfbc0f226d6a045f400506c30d3388b4e520816c2ad1a5776d"
- deposit_count: 434
- execution_block_hash: "0xa36bde80ad1b5c6fa8848e656ef5c9c95411042e1fff4ffc23b4bc2bcb7e6bee"
- execution_block_height: 435
-- deposit_data:
- pubkey: "0x929ab4e52386b139d32da163a4e1be5760f1d97bcfdaaa146f8b0348c94896b33fdbc3083ff3a41063e1b969a1f84080"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x81b4e7bf1ea952ddeba8fdf3e4b81162e5f7481fa9f59a95604fb0b8f8e4edd17e114d264ce0a236ce2459880a68c11317ac8aa2faeca6f80eb2e5cb53f106dd992e687c7b86536de330630e0c7de7ae16ef04646f05e98340d689157b704f0c"
- deposit_data_root: "0x27578550b83a805d25278e7004eb819236d723c8e1be90d61b65d3fc50314abc"
- eth1_data:
- deposit_root: "0x27d9b9761517e56e0c390781d9e7e967a7376a27a09380615594f756608ab48d"
- deposit_count: "435"
- block_hash: "0x51f5137c853e6e77ec221f4c6185e11aa1f03537aa9c94d91d4a58ec8287466d"
- block_height: 436
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x923555fa4c1bad92de2ae74472f84089b9f15bfcf562d84eb249313dc6bb6ae2"
- - "0x27578550b83a805d25278e7004eb819236d723c8e1be90d61b65d3fc50314abc"
- deposit_root: "0x27d9b9761517e56e0c390781d9e7e967a7376a27a09380615594f756608ab48d"
- deposit_count: 435
- execution_block_hash: "0x51f5137c853e6e77ec221f4c6185e11aa1f03537aa9c94d91d4a58ec8287466d"
- execution_block_height: 436
-- deposit_data:
- pubkey: "0xb126e91bd72a3289a04fa01e108f3ab4b77f2d20a93edc1c70f8ceda1df286461e92f73b7d2f85874abb1454ae1ef535"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa7f2a03af6e7075f289910a5b4348a6b2ff4d2f02633a44faeaccb965e6c2eb77647bc1489e6a8e39746fe29cabfaa92065161485194301a25617f81b96b7fc420eba955e13b04df59214faee482a439c3a2dd7cf5e3c9ba31a0309150b7d545"
- deposit_data_root: "0x5ed3598bdbce2f0bc4a26dd562b02fdc5c80ee35c013ee7c28610ae954b6b5e4"
- eth1_data:
- deposit_root: "0x6dff34424e745612aca561b1be1d10859787245ad98e2447b7bc9fa7bde0f008"
- deposit_count: "436"
- block_hash: "0x4820d0b8cf715941790bcc4e7ee618bbbace730c2bdba686471fac3746020dc1"
- block_height: 437
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x7aa625d524b4796a9c8870fee5a28d37b822d5a6c4a9959b084e764ffa123a94"
- deposit_root: "0x6dff34424e745612aca561b1be1d10859787245ad98e2447b7bc9fa7bde0f008"
- deposit_count: 436
- execution_block_hash: "0x4820d0b8cf715941790bcc4e7ee618bbbace730c2bdba686471fac3746020dc1"
- execution_block_height: 437
-- deposit_data:
- pubkey: "0x8fe3f04f04422bb2c76f5cfddf80a7a2b01bef7170af5f52c94e64ba1f8f523ff18d09af9235e37d10b3ac8ba3cc6ac4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x94c9697875b08a8f6dd31af84ba20b702f8ac2a3488b6ea694bc1a3afd582bc5d52dff92b0c9dfa4ab6ab7080ed434b6047e3743f1007c560cdb7482eb09147d49c79f3118dc1fac66e918d25e86226042ede65d1ed7a262b8c165b78df81e3e"
- deposit_data_root: "0xb40085a98ecff79943839d4d2cdd7ab9bbb72f90e94daf08c50efd26eba09c72"
- eth1_data:
- deposit_root: "0xf52ca6c22904e0ebef5336e0f010308fd124d5caed6a6043da92e1cbdd7afc56"
- deposit_count: "437"
- block_hash: "0x7692a6ca9efd1b0796eb01fcdb2b08fbc1739837e6f24eeefadf8cdad2a8062f"
- block_height: 438
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x7aa625d524b4796a9c8870fee5a28d37b822d5a6c4a9959b084e764ffa123a94"
- - "0xb40085a98ecff79943839d4d2cdd7ab9bbb72f90e94daf08c50efd26eba09c72"
- deposit_root: "0xf52ca6c22904e0ebef5336e0f010308fd124d5caed6a6043da92e1cbdd7afc56"
- deposit_count: 437
- execution_block_hash: "0x7692a6ca9efd1b0796eb01fcdb2b08fbc1739837e6f24eeefadf8cdad2a8062f"
- execution_block_height: 438
-- deposit_data:
- pubkey: "0xaaf6cc6cfc559ca26b82790935d4919ccc630438032b76874a40c25d77e4b87db2401cef8ad1871011569061ec7badcc"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa47e64f4d650537e9cb7d858267ee6862b97504ed46d11def724be28d05bd9c08e34420d5f06a1342536a47f120e8a540eb453b08c94fdb4c2deb3400f9cf87ce90a7cc1b14c8dea450111fb91f54fe4460e238588a6b4ab8778d48b99438a84"
- deposit_data_root: "0x99e08ee836bfaf2e9ccdcbfb308c88826e060edae11e3248a155049d4eaa772d"
- eth1_data:
- deposit_root: "0xb54a726ffc39347df5841efcdcdd4936894b92463db82208a447cf0071dcc95f"
- deposit_count: "438"
- block_hash: "0x3f48bbc9894a9a76b6faf91af106f773ade4285ed0b2e82591ff87514e41720b"
- block_height: 439
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x7aa625d524b4796a9c8870fee5a28d37b822d5a6c4a9959b084e764ffa123a94"
- - "0xb3aeed2eb2f5e99db75fa362a4e6c7dccfcff20b110983ffd36ad0aaa1783e50"
- deposit_root: "0xb54a726ffc39347df5841efcdcdd4936894b92463db82208a447cf0071dcc95f"
- deposit_count: 438
- execution_block_hash: "0x3f48bbc9894a9a76b6faf91af106f773ade4285ed0b2e82591ff87514e41720b"
- execution_block_height: 439
-- deposit_data:
- pubkey: "0x8533f1c4e38a4f72c3593ab28ccb163bfb429242a8c23e731478e57950f563b62101b06882f25c8133ea357fad66522c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x861858db0f3721f816791c002f9d8f09254d0ba5015fc2fc609783cff8a36efc267392c0525e4e0fb4bfa96d58626732091853af4c16b9fa309e5295331a32f84b2c3be61d2c2dfc34bd9e59117c54a8c46ee50f9291ba2793450fc960e14530"
- deposit_data_root: "0xbbb5ada0d7f4efa62bf0ba927747f1af9d4cfcbd76eb084f24ace3c8b0167fe5"
- eth1_data:
- deposit_root: "0xf75c37a1a191b865e14c6dac867208ae436a48d454410ad13cc9410bd8e3bdc9"
- deposit_count: "439"
- block_hash: "0x00c49ac28a1512771b4a976e03f723442c209b14068daba22e931c5b7e357594"
- block_height: 440
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0x7aa625d524b4796a9c8870fee5a28d37b822d5a6c4a9959b084e764ffa123a94"
- - "0xb3aeed2eb2f5e99db75fa362a4e6c7dccfcff20b110983ffd36ad0aaa1783e50"
- - "0xbbb5ada0d7f4efa62bf0ba927747f1af9d4cfcbd76eb084f24ace3c8b0167fe5"
- deposit_root: "0xf75c37a1a191b865e14c6dac867208ae436a48d454410ad13cc9410bd8e3bdc9"
- deposit_count: 439
- execution_block_hash: "0x00c49ac28a1512771b4a976e03f723442c209b14068daba22e931c5b7e357594"
- execution_block_height: 440
-- deposit_data:
- pubkey: "0xa20e3bcb6b38b66c2de7a7b3d1731cf430ebb94e38897d9ab9a9463bfe813ecf65f39297d2a3daa803f66bff80d6b653"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x880a58b82783d37fac7f207c9ad45e6c7fe7f98cf843bd52733e328a87ab81a4b585f598907d594b2abfc03913e0983b00cba405f0478ec3ff59954244f36467b5002354dc3f56001cf0c06fe12535dfd3813a03e561f27d0fe475153a7cc46e"
- deposit_data_root: "0x05bb8954b6ae43cbaf05ef800efe85d1755df3df92888c1390ac7524d332f2f1"
- eth1_data:
- deposit_root: "0xee960dbb2cb5694f6bd15e8fbe5d67369629cfcb89920dd6e05dd8c95ed484df"
- deposit_count: "440"
- block_hash: "0xd597af80422338ab6dff2432fe3d82e43c817e4512bb29e120492a6dfe622bd2"
- block_height: 441
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- deposit_root: "0xee960dbb2cb5694f6bd15e8fbe5d67369629cfcb89920dd6e05dd8c95ed484df"
- deposit_count: 440
- execution_block_hash: "0xd597af80422338ab6dff2432fe3d82e43c817e4512bb29e120492a6dfe622bd2"
- execution_block_height: 441
-- deposit_data:
- pubkey: "0x8cd7d05a46ad2e98ea82c438f12dc9fad70fa0b8cff2a731847efedc0efadef9a3f4d9e12cf8e9469d157d106f12626d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa580ca98af67b935e7b896aa223bb2ae6fc23313da1d47595e244f5f9f6aac65b7b396a196be2722d6cf036f8c293de81736674e13303d5a6c8d8893ae1fc5b572edd9a84bb0feefe7ec293f6d9050f9687bf930ef42dffabb554094c24962b1"
- deposit_data_root: "0x4c2f5d2c7521c2fa4bc78d77d66c44bc032f688fdeae2a216221fb20f49645ab"
- eth1_data:
- deposit_root: "0x03e6ba3922640836649ecbb7649e8b5361eed51edc0e24919c4a2f258350be34"
- deposit_count: "441"
- block_hash: "0xf4a32ac25eb43a2dee79b2620ab6d79fcecfe26f5b4d1743a6c6e47057f8f478"
- block_height: 442
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0x4c2f5d2c7521c2fa4bc78d77d66c44bc032f688fdeae2a216221fb20f49645ab"
- deposit_root: "0x03e6ba3922640836649ecbb7649e8b5361eed51edc0e24919c4a2f258350be34"
- deposit_count: 441
- execution_block_hash: "0xf4a32ac25eb43a2dee79b2620ab6d79fcecfe26f5b4d1743a6c6e47057f8f478"
- execution_block_height: 442
-- deposit_data:
- pubkey: "0xab5fec7f75687d50f35f4336b7ac78108834f98d9979f0327cd11b1557b6ad9dc119889003384b3940b10f0af7b8314e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb71c223a9819d28964a114bf849fb9f765087d4d32019a5fccc1062ea217a68ae8475708179e926d60f60df70a39973d09e6e387807f287dbf2d02db7a45be47f428330d2d2900a531b716ea53f90e9109c3aa061c1291b484eacb3f574372bb"
- deposit_data_root: "0x1d605f33e04dd29303dafd86bd3dd88e3fa4fe9f8a690c596af384d1515e4d23"
- eth1_data:
- deposit_root: "0x3f9a271478e34f229dbde7880720bb764f94cc3008ad30fc40b822fa46551e7c"
- deposit_count: "442"
- block_hash: "0x1306dfc166e3c7fdfe93ce194349c64b49f57eb0ab103fc426be4cc1ef7256f1"
- block_height: 443
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xacc05a3daa1af57565781fd828122e22e64a429030d2e8b20702611e6f49bd47"
- deposit_root: "0x3f9a271478e34f229dbde7880720bb764f94cc3008ad30fc40b822fa46551e7c"
- deposit_count: 442
- execution_block_hash: "0x1306dfc166e3c7fdfe93ce194349c64b49f57eb0ab103fc426be4cc1ef7256f1"
- execution_block_height: 443
-- deposit_data:
- pubkey: "0xaa93eab6f16b0bee0a2eaf3d548d354a716e1bfa4047ffae14af55bb49bb994310265e10c7ab47ffa33d1c3eceadbb4b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa4d489afd3c027948032978b0384fed21b6013e19108ebd8f2937e3b32854c91ea80dcf183670be34574a05634eb06b4109970b34b0e998f9d09615a7b8ec277c2d62b43daacc9d346733060dd7f08208164c57cc54dee78de08c4d42774e51b"
- deposit_data_root: "0xc91ecd7959d5713b9f528f6fdfdf456416f0c19514640347fd465d24352e35d5"
- eth1_data:
- deposit_root: "0x7bc70f5b38014ee13c40977439be4afa105e103bf24aff9c687c1d52def0d90c"
- deposit_count: "443"
- block_hash: "0xb6fcd3780b78de4f093046724aba76445fff193f0aab33ee3e08099403f5d076"
- block_height: 444
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xacc05a3daa1af57565781fd828122e22e64a429030d2e8b20702611e6f49bd47"
- - "0xc91ecd7959d5713b9f528f6fdfdf456416f0c19514640347fd465d24352e35d5"
- deposit_root: "0x7bc70f5b38014ee13c40977439be4afa105e103bf24aff9c687c1d52def0d90c"
- deposit_count: 443
- execution_block_hash: "0xb6fcd3780b78de4f093046724aba76445fff193f0aab33ee3e08099403f5d076"
- execution_block_height: 444
-- deposit_data:
- pubkey: "0xae363ffe8d6c6858d3c32967150ef670a2262ab9f46b3f2e3e4ae8910092bad1e7208ff9ba3f28b151dfab12f3474a19"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x803d1670174da10aa0eae9a24ef57151ce4fe2eb9f8c3144761f90fe483fd38d06aea4b7e6879afd43c5e1e3dfa223230edb7385dcd41d0d4eff69f94690ceab02bf9d5c35ecda1e30cc929403f64b0a08e9de644cbba5efcc5814ffbfc51322"
- deposit_data_root: "0x1ec544baffa893fc7cc179cccb186cae5d98da2920f837e49b6cd683abcb8fb6"
- eth1_data:
- deposit_root: "0xb81e9256ace4aee3308b567f7fb37713dff69385afb6b57a436070f318c2bd7b"
- deposit_count: "444"
- block_hash: "0x3c24b3a1983001debec5a13e73083d0bb99ab232cc3b26985f78dae529564581"
- block_height: 445
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xa1b8c431a46186490644ac091a8a657e248fdf1dbabd59a9e6c69007dce25c3b"
- deposit_root: "0xb81e9256ace4aee3308b567f7fb37713dff69385afb6b57a436070f318c2bd7b"
- deposit_count: 444
- execution_block_hash: "0x3c24b3a1983001debec5a13e73083d0bb99ab232cc3b26985f78dae529564581"
- execution_block_height: 445
-- deposit_data:
- pubkey: "0x83ae23912c04f49176c912a5d728224c3bbfac588e2203e37c6ca7520b01c6225b2830b0d37c8eb641d9abb44a648e28"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b5366124d214e3f88667a97297b75e2feaf3f54e09047b6e1d805499c961c76685f4dd16c8d169cff4fc17c401747ac0b6685693e80ab3324e4c77fcde51afb210799489d32a8251d6c25623abd5eb4930ab097b4d6d6daa38ad752cff3b435"
- deposit_data_root: "0xe76b1cfd301efe07f3af9878e54067b811f1872abd8cb7a02442fdf7cadd6d54"
- eth1_data:
- deposit_root: "0x99b58fdf354bd79892edced1978af6264777847c433d692efbfedff57526c7bd"
- deposit_count: "445"
- block_hash: "0x7480cf6cd450d4e3d9a461c222e8e0fd3a4416ac6c66a18d95bd870ed0294806"
- block_height: 446
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xa1b8c431a46186490644ac091a8a657e248fdf1dbabd59a9e6c69007dce25c3b"
- - "0xe76b1cfd301efe07f3af9878e54067b811f1872abd8cb7a02442fdf7cadd6d54"
- deposit_root: "0x99b58fdf354bd79892edced1978af6264777847c433d692efbfedff57526c7bd"
- deposit_count: 445
- execution_block_hash: "0x7480cf6cd450d4e3d9a461c222e8e0fd3a4416ac6c66a18d95bd870ed0294806"
- execution_block_height: 446
-- deposit_data:
- pubkey: "0x86d99bd43392d34879ff4409aaa44f1a42b34471a59136ff2fc2c5d0f3bee905108958f4a0de383597476b6f8fa380eb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8560371d260fcc434e0da634b18e1216ca8d63ea40486020c9568fbd959ed350f8b8b3fc1f6f88a48b7517d927c08c04190dc945da272ece929599becb29c8ed939ccb31cc4f316bf2c7341e2373f44ff8515858606fab8165e4ac6356f037bc"
- deposit_data_root: "0x28f2965716ad7616ab299ba34a56b5da43142e03867076aa477efc5774f7aa12"
- eth1_data:
- deposit_root: "0x440365613909570f9c374a476876624deed2636114a1dece1e7051d565d687f9"
- deposit_count: "446"
- block_hash: "0x452bf66254b503662848f580173b6b13a10efdf20d2016683b67c4d0beafbad4"
- block_height: 447
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xa1b8c431a46186490644ac091a8a657e248fdf1dbabd59a9e6c69007dce25c3b"
- - "0x22ee861ca07aca649f7d8b981e6c3bf4615ac3944a6acefbfbc843fe66b2d14f"
- deposit_root: "0x440365613909570f9c374a476876624deed2636114a1dece1e7051d565d687f9"
- deposit_count: 446
- execution_block_hash: "0x452bf66254b503662848f580173b6b13a10efdf20d2016683b67c4d0beafbad4"
- execution_block_height: 447
-- deposit_data:
- pubkey: "0xae47eed8ebfbd33bf1e92f52fc40d16f4b2b5e0cf4f54f2463af76f83cf0fef26475dff6c5b9d78f81925ca7d51190ed"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x80f785a5c57201068c993fde0c2efb2004cfe05a03a65bae1562b9663fd62aa6a27fc529c69966838b3d2e41014eacdc1211d67c7ecfafb32d92e34a1bfdbd4df20f3051b7398715b95f34046e1e157186f2502725000322f66b6684ac7a5679"
- deposit_data_root: "0x4c4ee3b1458b7a43155652b0c8e734776ed957d7f0baadb41e9c69615240a8fb"
- eth1_data:
- deposit_root: "0x024dc727a35948ddc2d5c8def41df75d4ab5f9c638d8420fc130ce350d4ebf5c"
- deposit_count: "447"
- block_hash: "0x5d0fc230f957aec298b3a4f35bd4dbbdd2a71de4696668501310240d0c3c36ff"
- block_height: 448
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0x2586924062b8d4cce4bda9de914e2a85d8352e0ea9d1512a816b099cbcb65c05"
- - "0xbe065ffe4f04afdfe075ddd6d51b69a8b470abe91f51e18845e3dd959b272134"
- - "0xb009f607491090689f616596852977e7f2617f96388353655e0b01bb9e3c5477"
- - "0xa1b8c431a46186490644ac091a8a657e248fdf1dbabd59a9e6c69007dce25c3b"
- - "0x22ee861ca07aca649f7d8b981e6c3bf4615ac3944a6acefbfbc843fe66b2d14f"
- - "0x4c4ee3b1458b7a43155652b0c8e734776ed957d7f0baadb41e9c69615240a8fb"
- deposit_root: "0x024dc727a35948ddc2d5c8def41df75d4ab5f9c638d8420fc130ce350d4ebf5c"
- deposit_count: 447
- execution_block_hash: "0x5d0fc230f957aec298b3a4f35bd4dbbdd2a71de4696668501310240d0c3c36ff"
- execution_block_height: 448
-- deposit_data:
- pubkey: "0x9286bfc698dd8f807748245c4d13de02910fcd8bc9b375a308d8a2bc7c73a05c8254b73931e448fbb2cf2d24f8b42f56"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa4d210f5d05cc9475174d918b7f495c5a91291e08eb6e747a513265d3d7b52444df7213e1d476b8513f6ddcc90bf97c0e5ce888570f5537cc450b14ae716bc5bde3a8a251b9feb35129b63f52df8926494b921c0c2317548c680109503acff0"
- deposit_data_root: "0xffe2744a1f6606c4f333a1163e422c905af1da3faa8355a7c1d14b4d96cf3a12"
- eth1_data:
- deposit_root: "0x783f4af9f9ff701317e0a1fe3c9772aba6748d2c3278d5ab1bd30feb212dbccf"
- deposit_count: "448"
- block_hash: "0x3ca4825aa555d4e316dcf61ea7d127988b176af164b1705bab9831427b3a48c8"
- block_height: 449
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- deposit_root: "0x783f4af9f9ff701317e0a1fe3c9772aba6748d2c3278d5ab1bd30feb212dbccf"
- deposit_count: 448
- execution_block_hash: "0x3ca4825aa555d4e316dcf61ea7d127988b176af164b1705bab9831427b3a48c8"
- execution_block_height: 449
-- deposit_data:
- pubkey: "0x98857d698710dbc26a57f167d463de3fc8e15fa4221d8ef6d8853c7843b04d2119a865215075f52674340300e1ff58a7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xad731a0a79a0d708d244ee8766bca38692a89fb89abca67ed6ed6bb672daf44ab77fa66ad298f0a158e72d3f7b3a55c719700c6173b8447d7cb46b07336fbae244fa124e3f98b825b7dc10c9429fc85dc4a5aa671006021aa0a72e5552b95ef3"
- deposit_data_root: "0x6af628d2a153eb81599f51910fd685f52bd32fb10ac3556bb0c608b35afc0c5e"
- eth1_data:
- deposit_root: "0x03cfe15696d6d04ec988563cf653ae99e72a85641c1de5499e287c0dbfc3fe86"
- deposit_count: "449"
- block_hash: "0x090750899e4923ca431e67389a655fe6080af94162863e81712b21111ffd5587"
- block_height: 450
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x6af628d2a153eb81599f51910fd685f52bd32fb10ac3556bb0c608b35afc0c5e"
- deposit_root: "0x03cfe15696d6d04ec988563cf653ae99e72a85641c1de5499e287c0dbfc3fe86"
- deposit_count: 449
- execution_block_hash: "0x090750899e4923ca431e67389a655fe6080af94162863e81712b21111ffd5587"
- execution_block_height: 450
-- deposit_data:
- pubkey: "0xabb8d751f2f97cd345688187accda8e00395503e500bd727b82b0be88484587776c225d64ca72703c186d6d0cb248e76"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83ea0cdfe5f2641f06f69411ac348b2429f34544f17fba693e58a7c395b86afe7cb52ec681ee2b92865b38a2ef600f2708eb9746987cd9a4bd831a2d74953e17077c8eff72002d1e6dcfc63693c42e6c48801ed6960480cb8e88b36bdd67df5a"
- deposit_data_root: "0x966d2b44d3db4cd7fe7b890d54612f94f5e66aff6bb82f352e17ad42a35c7f60"
- eth1_data:
- deposit_root: "0x31cb5ea97e5cdb9ca3d10a4098e70b8fd784e6796603c63634eec24610665a1a"
- deposit_count: "450"
- block_hash: "0x1b42b2023d6aab58dcf21a8f96a4fd53a9980a99a92278d95bad77b79b3eb143"
- block_height: 451
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x2ee848cde5b8b481d247e89b448dbd7e7fb077ce49a7a8777cb3d52d858452ef"
- deposit_root: "0x31cb5ea97e5cdb9ca3d10a4098e70b8fd784e6796603c63634eec24610665a1a"
- deposit_count: 450
- execution_block_hash: "0x1b42b2023d6aab58dcf21a8f96a4fd53a9980a99a92278d95bad77b79b3eb143"
- execution_block_height: 451
-- deposit_data:
- pubkey: "0xb88f1156883e6edf6df2f4f94079d373992e2d236ddf7003cd8cf84d73e371d16d4397fc20163eb4d8b5ff134beb4b51"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8fcd914835883541cef44b08c1b3fc7c91b28f6fb491b9beff48554ac227dcb6ed535bb1a6cf8cd9be97f495420f358116c39749895d17784a6828bbfacc22c6bf3c42d17f8e4a8900ea17be43e6c5b27f4a83793ff68b26a9d9fcebc6a376e8"
- deposit_data_root: "0x88c1120bb5fa6ab67bf2b80803a27302619bdee14a10cf97df1e56ded1ed54d3"
- eth1_data:
- deposit_root: "0xe8b7f46dc7475278120b4752ae46cf7b4dc209ad1948739a5559bb8ad2c43846"
- deposit_count: "451"
- block_hash: "0x58a48bedd093c961425032a2b01bcc2789f04af84e1474c57d1739a0288553ce"
- block_height: 452
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x2ee848cde5b8b481d247e89b448dbd7e7fb077ce49a7a8777cb3d52d858452ef"
- - "0x88c1120bb5fa6ab67bf2b80803a27302619bdee14a10cf97df1e56ded1ed54d3"
- deposit_root: "0xe8b7f46dc7475278120b4752ae46cf7b4dc209ad1948739a5559bb8ad2c43846"
- deposit_count: 451
- execution_block_hash: "0x58a48bedd093c961425032a2b01bcc2789f04af84e1474c57d1739a0288553ce"
- execution_block_height: 452
-- deposit_data:
- pubkey: "0xb37a06d51bf2a06b938b2a1d84fc0e9a0d45e753401035d0c7557b01d200c302169a06c5276ed77b7b832a885376522e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb8152b87ca263de22dd75f0ef8197369bd750813ce33e8d49a67ee27ef560f384fe388f05a14aa0ac1a15cc43b7dcabe02bbd2035531e677009d17a552338e34e1bfdeedffecdc32982ed80ff2d863f39ee6b1e04136ea43a129edc137f60114"
- deposit_data_root: "0x719a442d020d219e23f2c202c972311f1eab73fd8bfe61a3518405c83c4df232"
- eth1_data:
- deposit_root: "0xb522e60c52c239b043e08c2f0cda07c615337f6067f9f76e794b1f71145727f4"
- deposit_count: "452"
- block_hash: "0xc276347716f8b77e58ce6840bae2e5fa0167bcc32590b414298060c7c70bc921"
- block_height: 453
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x6cd34b4abd5cf459af14ab7b1b53f14c3f3c752241056a9b64349432d18e4f4e"
- deposit_root: "0xb522e60c52c239b043e08c2f0cda07c615337f6067f9f76e794b1f71145727f4"
- deposit_count: 452
- execution_block_hash: "0xc276347716f8b77e58ce6840bae2e5fa0167bcc32590b414298060c7c70bc921"
- execution_block_height: 453
-- deposit_data:
- pubkey: "0xb960a785f7ea8fc1d9886ff43e3b736cf7fab383087b6f1d85727473d909a91215ec515fe72783d703e8d214cc72dbde"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa429b2d68b1a5e8493e942954a03d4cf7234280c5c48ece941bfaeb877351da8c9fc915141afb1e9f8ebca3eb4c1a7f006f4ba60b43df7951a87f9dcb7286b8bdcb8e34e3b1e73b53645425e35d68a7b95688b3557bcb30f7c45de075d3620d"
- deposit_data_root: "0x80b0dadc1f658351f89567fc40f0775d9a496f4e72380fc1187690de3223a11b"
- eth1_data:
- deposit_root: "0xc9f3220a5eef0065415e6ff59ca524424b32ad98e61d6a5fa58e3addf0c1d3b1"
- deposit_count: "453"
- block_hash: "0x99799c65563071761573abee510fc22423fd463f2f1ffc6c1185038e82171f51"
- block_height: 454
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x6cd34b4abd5cf459af14ab7b1b53f14c3f3c752241056a9b64349432d18e4f4e"
- - "0x80b0dadc1f658351f89567fc40f0775d9a496f4e72380fc1187690de3223a11b"
- deposit_root: "0xc9f3220a5eef0065415e6ff59ca524424b32ad98e61d6a5fa58e3addf0c1d3b1"
- deposit_count: 453
- execution_block_hash: "0x99799c65563071761573abee510fc22423fd463f2f1ffc6c1185038e82171f51"
- execution_block_height: 454
-- deposit_data:
- pubkey: "0xac748de8d5418285e99661d22ef888ee9b19fee4e3bb2db1fbd4404ac32fabf9ba2d41450c2f2ba42bd97cdf28a349b8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x89cb911ffbffec15dfaec2c21298681348e4c02cf3e6dde9c7fc73093b94115cf433a485dea3561efcf7feb2cf9c2ede105004f477bad9be075e408dd73ef9c3be78862c8b6b3bf4122b28f887ae0a0120bc7a754e1f46dcc6b4b9606ddbc23b"
- deposit_data_root: "0xcd7377eac780c66d2dd90fbcda1563fbcc7f4cb53c0d2e2f4c22f88005755562"
- eth1_data:
- deposit_root: "0x20d947edb9a78bcf6b5a8ab78f2fc9d1b08a451d553977ae010d2cdc39566e59"
- deposit_count: "454"
- block_hash: "0x60bc4577621cbd0cbeb9238733a408f77bc2a1958775e864f8dbaf88e09be44c"
- block_height: 455
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x6cd34b4abd5cf459af14ab7b1b53f14c3f3c752241056a9b64349432d18e4f4e"
- - "0xfa8b871b3d268957a0da1ff487492cb4e8ac619d397f80e1a36987ca54ef56f9"
- deposit_root: "0x20d947edb9a78bcf6b5a8ab78f2fc9d1b08a451d553977ae010d2cdc39566e59"
- deposit_count: 454
- execution_block_hash: "0x60bc4577621cbd0cbeb9238733a408f77bc2a1958775e864f8dbaf88e09be44c"
- execution_block_height: 455
-- deposit_data:
- pubkey: "0xa89895024ffe3c247d5515a8f2cf3e5275dec9c1c3143d7a4dbabe1aa16761ca69225bd2921a4afee83e01cb4c83c25f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84d1d54c7b7afe591fd9be6342e92f4a1e0a0983a73cbf620c9653f602df0b9f1fd205e2b5e21edb3529cfb4fb200681012beaf6de044ee3198b256134c1a2b655df3fdeba942999f6f4e1642fa34b6185c5016d353e19441fcf55cebf6fd085"
- deposit_data_root: "0xd5166ba088a056939b9bd3f7fc516190e2dd84b2f2872c225236a97908cf5d60"
- eth1_data:
- deposit_root: "0xb9093524f50637874422a739e135b55224a74123bf8d04b993a02921a5401dae"
- deposit_count: "455"
- block_hash: "0x6a4fb53350211cabe2bc406b3da41c4fc959922aa4953a42326fa0c58b5db8b8"
- block_height: 456
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x6cd34b4abd5cf459af14ab7b1b53f14c3f3c752241056a9b64349432d18e4f4e"
- - "0xfa8b871b3d268957a0da1ff487492cb4e8ac619d397f80e1a36987ca54ef56f9"
- - "0xd5166ba088a056939b9bd3f7fc516190e2dd84b2f2872c225236a97908cf5d60"
- deposit_root: "0xb9093524f50637874422a739e135b55224a74123bf8d04b993a02921a5401dae"
- deposit_count: 455
- execution_block_hash: "0x6a4fb53350211cabe2bc406b3da41c4fc959922aa4953a42326fa0c58b5db8b8"
- execution_block_height: 456
-- deposit_data:
- pubkey: "0x8e0cd6b49327ba93279e394f62cb84375fc63bbac7c72eb4f90cd5d71e4cf34f1fe0d92b82ce51e60d9255a0fe99e021"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb16f03ea11ebd8f5f5c864bf87df767429229be5fad7b41bf26fa025bc4248af339ff07be292f5661d975344c4947d871368db8fd3ab8995c7ba358e4e73218b169fa32fbcc4839f9d1a1a9ef52b4169929d48d400783cc959ad4ca27a3432ad"
- deposit_data_root: "0x35d372da653d0c041ede27965e52876b47afacc14fc6ed6eaf37580bd5f85177"
- eth1_data:
- deposit_root: "0x88685588119ba1394dfd58c01b558e18fd9e1630431136f478f0099a37fad6f4"
- deposit_count: "456"
- block_hash: "0x16b9630f3d0113ff5a3688bd3ecff00d4958a1136f6e3e9c6155a35288c51cd6"
- block_height: 457
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- deposit_root: "0x88685588119ba1394dfd58c01b558e18fd9e1630431136f478f0099a37fad6f4"
- deposit_count: 456
- execution_block_hash: "0x16b9630f3d0113ff5a3688bd3ecff00d4958a1136f6e3e9c6155a35288c51cd6"
- execution_block_height: 457
-- deposit_data:
- pubkey: "0xab195eaafc5a60c4c91722f53e19fce9c04ba9655f433a18f0472606ec826fbf77828d16f859297a9272d2b4fe50403b"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9297d77b34934381a63a39e25ae8ffd26a67bb1baaf6ce2d39ae53dde9e0ba2eb9ea5f6cd61d9f82a73e3c8f00220b5c14ded82f49ccc953a82a6f352a693d57ec256877122b2caf56c8405269a44ca255de858a1af5504388c4a04b71bdde1d"
- deposit_data_root: "0x69c7a9d2550955ae43c7a6790737017c37d9d2c353af01686d4736259ab45a77"
- eth1_data:
- deposit_root: "0xcff79088a43be898c147090a135293d6ac0b9a05370a36aa6403897e449b6d74"
- deposit_count: "457"
- block_hash: "0x66e0fcb1ac380fb70e9a3bf4771276b0a1bd23bf7cf6eb37fb3b919c7da07e98"
- block_height: 458
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x69c7a9d2550955ae43c7a6790737017c37d9d2c353af01686d4736259ab45a77"
- deposit_root: "0xcff79088a43be898c147090a135293d6ac0b9a05370a36aa6403897e449b6d74"
- deposit_count: 457
- execution_block_hash: "0x66e0fcb1ac380fb70e9a3bf4771276b0a1bd23bf7cf6eb37fb3b919c7da07e98"
- execution_block_height: 458
-- deposit_data:
- pubkey: "0xaea50380eaca9b09e5baec21e5f522c964b0ac8d4aebb8e1a1a196a01fb5c2c87f524be56a57d2f80274d1a0d2ed7fa6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x954643a0a8494712b0e1c45e089b17e84bfe57e4d901841e2e2381b303b724caf34741564ba450c8ef8469999f22a9a811c4b14c4599e2c3caa45f306264b7149402c643e4c82fafa3c966cd0bef954a214c06311ccf6a812b1ef43ea279a2b2"
- deposit_data_root: "0xb131ceaf7a69f35f76b5c8e6ccd346ccb2f10cf14a173d12758dd4a9fed3c0d7"
- eth1_data:
- deposit_root: "0x1ef3716bf7e7a51f7fc622319f07a89a2ea1c2bd4a6149e5ea6e069e63a5dc66"
- deposit_count: "458"
- block_hash: "0xbca1858a0a0f800b2b1921341c915c917e67ba447b530834ddab39c1b4b5dd59"
- block_height: 459
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x2f22c52f2268d8873a91866c36b0c38a75a64c6598e974ce14cf6b0b783fcf8a"
- deposit_root: "0x1ef3716bf7e7a51f7fc622319f07a89a2ea1c2bd4a6149e5ea6e069e63a5dc66"
- deposit_count: 458
- execution_block_hash: "0xbca1858a0a0f800b2b1921341c915c917e67ba447b530834ddab39c1b4b5dd59"
- execution_block_height: 459
-- deposit_data:
- pubkey: "0xb68a35785d29094de3457406b8f974581ab72e2aea2c3ec1ffd21b0326297f09a838b669e3e1409e127a3bc3eaa8cb72"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xac9f75a49603af9cd321f521460eda36c3a1dd7eb88bff394e7692b8d4dc7e7c33868025c7cab4b365693a8743d514d5029c238b47357486bb3b4cf31f87c9ac07327ec39858fc89b580dee5ddcdf7d089acfb238cec502403de5bc2487ddb6f"
- deposit_data_root: "0xda57dcc5780f0fe914a0f88d1db9b36324b9e13a0fc44ad777ebec7a8ac154a4"
- eth1_data:
- deposit_root: "0x6262414f9280a354022ae8b80692ab01589f0f022775dbc08e7cbaabe1feb343"
- deposit_count: "459"
- block_hash: "0x88421a8eac3dd6665ad9040506148cbb90c37ff8278e3286d36eb41939177435"
- block_height: 460
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x2f22c52f2268d8873a91866c36b0c38a75a64c6598e974ce14cf6b0b783fcf8a"
- - "0xda57dcc5780f0fe914a0f88d1db9b36324b9e13a0fc44ad777ebec7a8ac154a4"
- deposit_root: "0x6262414f9280a354022ae8b80692ab01589f0f022775dbc08e7cbaabe1feb343"
- deposit_count: 459
- execution_block_hash: "0x88421a8eac3dd6665ad9040506148cbb90c37ff8278e3286d36eb41939177435"
- execution_block_height: 460
-- deposit_data:
- pubkey: "0xb90a59e63d66d20d5e9a3b45be51fa7963da5ee137a126740036f432c50eecaade78c4a5bc92fe1908a153b15ad92a25"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8397c642292c99d42f208b26b2dd82f1e8d214dbb6829b70cf5a55c710a37572fb77e02beafb4c2208e7c6a965529009021b0d55dbf63c6eda839187158f5cb2141f25464da3802e2f411ec7bf5671225b231d2a4a48ed90c72ec8bfbabe30d9"
- deposit_data_root: "0x51c105f98c9892d6d1cead0485fe9058e733fbff334a4442e409140899cf445f"
- eth1_data:
- deposit_root: "0x34fd2a662b2220a66fc9b966be349b6c80781bf702a8702957ebd775a35e2e6c"
- deposit_count: "460"
- block_hash: "0x07fd13866775681d13fc3a2f7fd2ec38c86341a724a12140ed79d6c95bf1ad8b"
- block_height: 461
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x689f0a0b6d57f49f4654c506592ef965bcdab3336c358f30213e2d5d3630415a"
- deposit_root: "0x34fd2a662b2220a66fc9b966be349b6c80781bf702a8702957ebd775a35e2e6c"
- deposit_count: 460
- execution_block_hash: "0x07fd13866775681d13fc3a2f7fd2ec38c86341a724a12140ed79d6c95bf1ad8b"
- execution_block_height: 461
-- deposit_data:
- pubkey: "0x9826a9986a35754dfdc31e69bb8b073eb7293aaa747b0990da43c2c04bc001c78257ab3a1a91d3c7f2bb9c8395ed9424"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa569d9ac3ef0d59e22d7776348817afbbe1c4213c2d827dd2c75cb4cc7992fafd838e5661b98a8f77712a82eb3a6e798106b7d3ff6b1376de96bebef0a915e648d08fee8478c5e39e8085693ad0af6ab4e5dfb0f22136e9d2f1a7d1b1a6d6482"
- deposit_data_root: "0xb50cfbee3651658b71f15612069c1ade31ca2a26449985ef20b99f3ffbd78353"
- eth1_data:
- deposit_root: "0x76934fb0b2c000d79600b534433d9ae771971013b7e6ff1b5459ff86f9fe09c7"
- deposit_count: "461"
- block_hash: "0x9ae6b3c353ce3cb09bfe114d6b4f3a02e3119baff9cd693a7215a3036299c7ea"
- block_height: 462
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x689f0a0b6d57f49f4654c506592ef965bcdab3336c358f30213e2d5d3630415a"
- - "0xb50cfbee3651658b71f15612069c1ade31ca2a26449985ef20b99f3ffbd78353"
- deposit_root: "0x76934fb0b2c000d79600b534433d9ae771971013b7e6ff1b5459ff86f9fe09c7"
- deposit_count: 461
- execution_block_hash: "0x9ae6b3c353ce3cb09bfe114d6b4f3a02e3119baff9cd693a7215a3036299c7ea"
- execution_block_height: 462
-- deposit_data:
- pubkey: "0x854de57710b835c0253eef8a20d2e6f0ef8d260eb4443bbd5c38de0acd38035f0c1ad5d09994744588a497f8eb3b747e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa818e6ca068133ba1cb41c57f6b6b16db4ff64bdbe67d8207206989d8efc0021fb002976c3cff587687741db6d1ab6a200730acfe51121f49792c11865efde86e8d7ae4750f047eb18d544fcbe0aa03b73a38210a914cc1eb82012cfc9e0bb22"
- deposit_data_root: "0x48c0a3d3ca1ae0f20cd20838fac325cdc0b92253a3431bb9033a2b4144afb08f"
- eth1_data:
- deposit_root: "0xe74c79921d452c89e27a9414c76a65286982c0951d4ee0eb486361fc8208e5e2"
- deposit_count: "462"
- block_hash: "0xa11e6044fdd05aa46ecf17d49edb46d91545f750db221a4edbab2663880d2cee"
- block_height: 463
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x689f0a0b6d57f49f4654c506592ef965bcdab3336c358f30213e2d5d3630415a"
- - "0xc47891c2dae75dac43cad9c632bfbed1549eab22922ad0829e49fb45e3bfaa98"
- deposit_root: "0xe74c79921d452c89e27a9414c76a65286982c0951d4ee0eb486361fc8208e5e2"
- deposit_count: 462
- execution_block_hash: "0xa11e6044fdd05aa46ecf17d49edb46d91545f750db221a4edbab2663880d2cee"
- execution_block_height: 463
-- deposit_data:
- pubkey: "0xadc1109ded58e828f3c992b3d367b8e8d9d5cbe102fb171b4f4dfa66a181ab040f13d15a38b10e50c8c87432904b6e1c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb8799635089cb0c7b9703daf090358b53459304538f784eea9802a284bed2adb69c3c2e3b244da77b7ec5b420fbe2a4e1220c59059d904847b4750f7c188c92cc826ecdf1c6650f789856dcb49c7fbf380c76702169dfecd0c7d076ffecdfa1b"
- deposit_data_root: "0x8e7112b4f311f4c3a3a295185ba65739fc5f0a7bc06e2a561fd9f5ec1e3c56dd"
- eth1_data:
- deposit_root: "0x8dfaa386c19f0aa3bb523cdf7edae9a99a54ba5af875225e8ef106d89a9a7583"
- deposit_count: "463"
- block_hash: "0x66f1fe4d2e95c883b0a7698c48ad71aaaed1206a9ae8cce0d46c99a2d1834076"
- block_height: 464
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x53c1bf574da722d22635feb98ceae3cfa185fec248396946d571681fb60e9005"
- - "0x689f0a0b6d57f49f4654c506592ef965bcdab3336c358f30213e2d5d3630415a"
- - "0xc47891c2dae75dac43cad9c632bfbed1549eab22922ad0829e49fb45e3bfaa98"
- - "0x8e7112b4f311f4c3a3a295185ba65739fc5f0a7bc06e2a561fd9f5ec1e3c56dd"
- deposit_root: "0x8dfaa386c19f0aa3bb523cdf7edae9a99a54ba5af875225e8ef106d89a9a7583"
- deposit_count: 463
- execution_block_hash: "0x66f1fe4d2e95c883b0a7698c48ad71aaaed1206a9ae8cce0d46c99a2d1834076"
- execution_block_height: 464
-- deposit_data:
- pubkey: "0x87068fec51465d586d65ff531b32fe20d2e02535c08883721654338878b1aee8479fab486a19de804da1f301443f69d0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8e8b77fbdab9f6a210e3d8dac73df968fec07362e42dbddfc5533b103715438897012d2d49b64ecb920ad8eee641cffe06706a2af60897c44a21bc6c6581e878235070c197d57f9f8882bccc88feeafb1d0203569be51063663f82027a3da08c"
- deposit_data_root: "0x14cab7fbbcb0c52a1c60cb65d05f7be70e33e4d4e6367ddc931482e6d839e76d"
- eth1_data:
- deposit_root: "0x42a835e727b7aaf06d891a55d8b7a067512cc87046e043dada051674d3d61438"
- deposit_count: "464"
- block_hash: "0xbdb7f8ea7927498e58540bc2b1d70b082c025dbe0d41fea325e7e65427d396dd"
- block_height: 465
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- deposit_root: "0x42a835e727b7aaf06d891a55d8b7a067512cc87046e043dada051674d3d61438"
- deposit_count: 464
- execution_block_hash: "0xbdb7f8ea7927498e58540bc2b1d70b082c025dbe0d41fea325e7e65427d396dd"
- execution_block_height: 465
-- deposit_data:
- pubkey: "0x95322a22f4abe8eb0a0f4cf8876c31abeb3684ed984f6b595b9f3b9527b60c5f730d03d4960f5094210a3f6383691348"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x921dc1028ad56faf90a0732ed439ca36f5f4fa643bcad13b95309a6afcab2ef45f535601289b18d3b68244a23b598e6a014d3b75ec07afa43a2718b9c1a670d8587d3fd8e6254204f6d2c3937ca09cd0c80de526b8bbe2150f4d3e05c218a747"
- deposit_data_root: "0xea4b7f1637589d380ebdd0b75914919c07ef2936943a96865acd55028cd7c065"
- eth1_data:
- deposit_root: "0xf289bbf81113da5f485fc53db8a774b6817e4648e8c1f5e7136c68ffe1688fb6"
- deposit_count: "465"
- block_hash: "0xf02d6940bc1291413166041a1c800d2d86203d07151c71ed39604d78e50800a1"
- block_height: 466
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0xea4b7f1637589d380ebdd0b75914919c07ef2936943a96865acd55028cd7c065"
- deposit_root: "0xf289bbf81113da5f485fc53db8a774b6817e4648e8c1f5e7136c68ffe1688fb6"
- deposit_count: 465
- execution_block_hash: "0xf02d6940bc1291413166041a1c800d2d86203d07151c71ed39604d78e50800a1"
- execution_block_height: 466
-- deposit_data:
- pubkey: "0xb43fcdad30bb652a82ce6033d6cdd6b004f58eb102d54f4de5a59c17c774c66637e7ed8078b19afe55ed34ac2b969fc7"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83444116edd61f30eb0ad94e86f36834a2b99db16ff37a19139349456b8afd64b7dd6c92e7fa8f6fe9bf13de87c39fa80d3dafdcf00f9285e2610a63da505c2f91bb01d55cb2f75f0aebdfa37ed10d8a8102165adf87d03b421e604231ed200d"
- deposit_data_root: "0xba13491453796254686b89b3a1d2589d271db8a73cf2420df2f1d7a232c69238"
- eth1_data:
- deposit_root: "0x566f2e0bf068a861f4bcbe154f442dd6ae9097bbf4270c7dbfb3221ae6957fde"
- deposit_count: "466"
- block_hash: "0x29affc9ff69377a80f0888246a6bc7c98e7b914e4d6ce935f33e017fbb119519"
- block_height: 467
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x4f223a1f874097defdc9227f99dd60128d5695ed143768671db7ea87ff207409"
- deposit_root: "0x566f2e0bf068a861f4bcbe154f442dd6ae9097bbf4270c7dbfb3221ae6957fde"
- deposit_count: 466
- execution_block_hash: "0x29affc9ff69377a80f0888246a6bc7c98e7b914e4d6ce935f33e017fbb119519"
- execution_block_height: 467
-- deposit_data:
- pubkey: "0x801125a4149f3b2ae29f7745ed91492ebd9de91da253f0a267f864302044310c1f9decede6b1b5a9e1719c36841aff5d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa4fd707ca74abc5be01c340ddad32ac490f164119e323928247e7ce5e846f31c7642270acd7cb26b220e1f957a2e1230e4073d742bfc38dc538ed5089e89d1765c8c459f2d0997357d548e797267db7066f91541415aa769fb3eaf964465861"
- deposit_data_root: "0x344061e3131a0fd07c4f8c46d4e68950c9e0226907b418e7485009a1efca42e3"
- eth1_data:
- deposit_root: "0xf92d82cd5cfaaba51447264da8eed8cd65da770562dcedd00ec05ff6da207892"
- deposit_count: "467"
- block_hash: "0xee7806737892c8ba330f1d4545aacbee5f0a4b25c44d596f5eecf419ca936039"
- block_height: 468
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x4f223a1f874097defdc9227f99dd60128d5695ed143768671db7ea87ff207409"
- - "0x344061e3131a0fd07c4f8c46d4e68950c9e0226907b418e7485009a1efca42e3"
- deposit_root: "0xf92d82cd5cfaaba51447264da8eed8cd65da770562dcedd00ec05ff6da207892"
- deposit_count: 467
- execution_block_hash: "0xee7806737892c8ba330f1d4545aacbee5f0a4b25c44d596f5eecf419ca936039"
- execution_block_height: 468
-- deposit_data:
- pubkey: "0xa7852f47c6391e4ea0854d59b4a69ac72be49f7f798c19146a787dcc25a48a183ac3902001d0225f242ced6cc09aa378"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa0a90f6758d780721ada83e733fbda997001304b093517bb175d9b50f903d366f16ca33f47d716197317f81326688aac0c99be675058e687c2391016f28451c82484faa49311ca5b5af7b73e68003ec0b6f10a03a5fb0d735e32a6319bcaee81"
- deposit_data_root: "0x9da6faf501a235e8957b782d919b8b63d469f9cf252b5786fd8ee778e291a127"
- eth1_data:
- deposit_root: "0xd7166c06e1e85afaa7ae992a6aba05a63e6017f6be9acc4bd43344807cbda528"
- deposit_count: "468"
- block_hash: "0x29e18f49fc40f155ff1bd424b6af69c1bb1146f5e5060fc5c9c6badabb52ec28"
- block_height: 469
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0xb6a8aae06157a95d5852c69b8815034853daddd3aea1c41b6082f625f64a6688"
- deposit_root: "0xd7166c06e1e85afaa7ae992a6aba05a63e6017f6be9acc4bd43344807cbda528"
- deposit_count: 468
- execution_block_hash: "0x29e18f49fc40f155ff1bd424b6af69c1bb1146f5e5060fc5c9c6badabb52ec28"
- execution_block_height: 469
-- deposit_data:
- pubkey: "0xb0c1eb313f3894f5f19ddd7cb3472f015ccf51c24bf4316fae3e8502d3b65132a8d2ac58f7d17eec0a644ef31afda14d"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaf2982541a4ee7cd7a39ce1f4dd094b64bbdf93763ae134a09c4abdb5dad4830b772b610dd54d8e7fb782de6f6e524fa0bd3dae3737afebb2a10478ba965d1619276a04a3782d3976957c60fa92cf552876ff66db974c8c4fd820a738b980040"
- deposit_data_root: "0x6bd3f89d5210692fea089c2d827b529bd2c9127d4dd27b152bd78da7bd466f29"
- eth1_data:
- deposit_root: "0x17128858a7687c2474b0cb4f79f498a32c46a922afd92d97723efcbc332b93e2"
- deposit_count: "469"
- block_hash: "0xc50e70d8f92b0410c880a034aca2ebff5f6b2bd917673b1b7cb095be4b7c033c"
- block_height: 470
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0xb6a8aae06157a95d5852c69b8815034853daddd3aea1c41b6082f625f64a6688"
- - "0x6bd3f89d5210692fea089c2d827b529bd2c9127d4dd27b152bd78da7bd466f29"
- deposit_root: "0x17128858a7687c2474b0cb4f79f498a32c46a922afd92d97723efcbc332b93e2"
- deposit_count: 469
- execution_block_hash: "0xc50e70d8f92b0410c880a034aca2ebff5f6b2bd917673b1b7cb095be4b7c033c"
- execution_block_height: 470
-- deposit_data:
- pubkey: "0x8c6ccdc900d78ef20d5b22ad540e73864c858baf068349dafc397cd31c571708ec6ee6afef9e5711a587e3e97f1a50a0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d02c24dbaa0a13109feddc00dba3ecdbccf6f9f89ea859ce8293f131679c24786317f96ec390c847084f7e8ae5f56060b45fda9cbdfd4219e2806f0c2e340947fcb2860ab279860360e936b31e27fad05a4ffbbff514432e3f15f9ac7fbe5b7"
- deposit_data_root: "0x63bc1e79593a6bc90ad3e76e5cab85bbf3ebc0f95993633ee2070133bb805ee8"
- eth1_data:
- deposit_root: "0x0114581f1558b58a8fda8d0fd4d9c8d81e3a0a44e1ee0da77b688940dfcae870"
- deposit_count: "470"
- block_hash: "0xc72dde0d8a48244290c055cdcac8a82a10a5c83768430f4216a7f0db007f65bc"
- block_height: 471
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0xb6a8aae06157a95d5852c69b8815034853daddd3aea1c41b6082f625f64a6688"
- - "0x1b129cc8ae0d0bcf87188bb66ce17acc25350f28de10249e179c868a9f7a4a79"
- deposit_root: "0x0114581f1558b58a8fda8d0fd4d9c8d81e3a0a44e1ee0da77b688940dfcae870"
- deposit_count: 470
- execution_block_hash: "0xc72dde0d8a48244290c055cdcac8a82a10a5c83768430f4216a7f0db007f65bc"
- execution_block_height: 471
-- deposit_data:
- pubkey: "0xa8aa5faaa4bbda5b5e7d610746f27c09bdee3a3f057550bca600ebe1c83749525a135829669a0162c3339ea40dc5525a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x94fb954aed2ccc71dbeac75d03bab4f59bc09a2468b25a12ccda4d50efe9bf2ec3e4188ecbe50c1bee58ee2d90acb83b116085775618887034be7c1487e52e76d2aaa2fca8fc37ebbbf552d4a5996d086fc653b447337a89bcc0ff4e678b2e94"
- deposit_data_root: "0xc9ed8e05a9be23ad58521dfeda162c75bff62477ac3aea3f373e1c12c5fe5ce7"
- eth1_data:
- deposit_root: "0xc05d8b31462806679096a4b5e89c1f82e0c237f65cb53f9dbd7086517aef4321"
- deposit_count: "471"
- block_hash: "0x9923a0a46a2f622ff2ada864cb8ce46be4ad5ac7fd386ee8c1dc2df41279395a"
- block_height: 472
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0xb6a8aae06157a95d5852c69b8815034853daddd3aea1c41b6082f625f64a6688"
- - "0x1b129cc8ae0d0bcf87188bb66ce17acc25350f28de10249e179c868a9f7a4a79"
- - "0xc9ed8e05a9be23ad58521dfeda162c75bff62477ac3aea3f373e1c12c5fe5ce7"
- deposit_root: "0xc05d8b31462806679096a4b5e89c1f82e0c237f65cb53f9dbd7086517aef4321"
- deposit_count: 471
- execution_block_hash: "0x9923a0a46a2f622ff2ada864cb8ce46be4ad5ac7fd386ee8c1dc2df41279395a"
- execution_block_height: 472
-- deposit_data:
- pubkey: "0xa7c107c72118446d1dc3c5c1c42f95ca2471dddd61c1461dd8ce028a1dae7656c98c3eca5f6dbeae8f9594e3e652a4d3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8cec6a4e726448a24c2f9f4e1f82366bd723596c8d4a62be7a2c8a0e0a513518b9cd9cd00a13000a1d03a5bde2336c920752aa634d77143f890ab2718ecaaa5527fe7ef3b2489ff7548af90eefb857c03b9bf52dc9089989387c8be9141dea65"
- deposit_data_root: "0xd2602c538061473ff8ada72bccc5cb574ea9811b109867a442ec621a78184249"
- eth1_data:
- deposit_root: "0x71d80a6c13aaf2af9b142d5f75859f7f86cf33492301a62d42134810c1a43862"
- deposit_count: "472"
- block_hash: "0xd4b509039b3e7f5664ed77eed00addbc90392021394ae1c431c10f9236bf539c"
- block_height: 473
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- deposit_root: "0x71d80a6c13aaf2af9b142d5f75859f7f86cf33492301a62d42134810c1a43862"
- deposit_count: 472
- execution_block_hash: "0xd4b509039b3e7f5664ed77eed00addbc90392021394ae1c431c10f9236bf539c"
- execution_block_height: 473
-- deposit_data:
- pubkey: "0x899eaf183acd5beee0899a58c8ee5fff1dc76df143028d9871d231e8a3999d92098538d070fd1c9db5d9db60f23dfd4a"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x88a116fece26c6e4d209321a5c58a8e09e01fe165703b042cb577060a8bc3255a281bc960e65ce253e66d15560e38efc10fadf7f49224583d4d25b34258d46ffd6402356684954e33849e968ce77d484307dbcd7d02a6eaf75185c7512231add"
- deposit_data_root: "0x57f93038b3cac9f76cb61db2309f1a5853dee6b9f4b3e713c34c4cd2a18631dd"
- eth1_data:
- deposit_root: "0xdc3672b4162de2f668f5865ee0f8e00e755777968de8c44b3320c92592c8207a"
- deposit_count: "473"
- block_hash: "0x947b126441051344edc68b986f9b345352a4f0420b44dd06a6359204d5d0ac4f"
- block_height: 474
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0x57f93038b3cac9f76cb61db2309f1a5853dee6b9f4b3e713c34c4cd2a18631dd"
- deposit_root: "0xdc3672b4162de2f668f5865ee0f8e00e755777968de8c44b3320c92592c8207a"
- deposit_count: 473
- execution_block_hash: "0x947b126441051344edc68b986f9b345352a4f0420b44dd06a6359204d5d0ac4f"
- execution_block_height: 474
-- deposit_data:
- pubkey: "0x8771579633474fb50075b4c801124f63c4a786e7a618bc50c00122f4fe8c18d1edc123ce9be8436b9bc8159c5d2061ec"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb208ae48bba24e07a4d4dd1465cd92f135487a71353e79657250e66e18e31c08477d6b3f94cd8836b18ac1d6d154fbb50bfc5fb9e261c5117b30a96dbb3ae0dbcfd912b465b1b0c694d0030c97ed3b40437c0559fe95bd2cfad07706345e302c"
- deposit_data_root: "0x70e6082f9f4c9f7cb7c0d946caac7dd325787fe08c2a6fde05ddc7ee71bc1978"
- eth1_data:
- deposit_root: "0x1e2891528f3695be75c16e6f8e948737a6be58ec77667c41f70309fe2d0a0c24"
- deposit_count: "474"
- block_hash: "0x05b249730f2706e2825a6c3beb0582bc9430679dae5fa24c864a246efcb97eee"
- block_height: 475
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xff8e34dd64f1d9e20b42622f7dd59ce1f29ae93f52847609c7fbedd88e764275"
- deposit_root: "0x1e2891528f3695be75c16e6f8e948737a6be58ec77667c41f70309fe2d0a0c24"
- deposit_count: 474
- execution_block_hash: "0x05b249730f2706e2825a6c3beb0582bc9430679dae5fa24c864a246efcb97eee"
- execution_block_height: 475
-- deposit_data:
- pubkey: "0x8416902c51bdb3933ff4e87558121d3fbab9f116f9a5b0ae9cc30c4d145c39dc988f5c0b754da3daeec71fa68144f9b3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9402807f43da37ca29cede163b91633fde7614843314b423db475c86533e0006cf6b1e80a93dc04aedb919afdd9103b617e136915062a66211720207f6b1300da29a44c751251ed097a204b44780275514318e4cf73ad1971b10eebdb3a08aeb"
- deposit_data_root: "0x3ecd4d4c9a0d1810d3599f12fa62a3085f96dec792ed006f37bc2e2a20d5e90c"
- eth1_data:
- deposit_root: "0x04f3ebd098dd6485ad2ad107913118691ce85da75625af5e6fb730e536d298f9"
- deposit_count: "475"
- block_hash: "0xb63ee91d3c3edb9a298101f2c5c15a0dcc5fe27f0b564a620e944e7619845b1a"
- block_height: 476
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xff8e34dd64f1d9e20b42622f7dd59ce1f29ae93f52847609c7fbedd88e764275"
- - "0x3ecd4d4c9a0d1810d3599f12fa62a3085f96dec792ed006f37bc2e2a20d5e90c"
- deposit_root: "0x04f3ebd098dd6485ad2ad107913118691ce85da75625af5e6fb730e536d298f9"
- deposit_count: 475
- execution_block_hash: "0xb63ee91d3c3edb9a298101f2c5c15a0dcc5fe27f0b564a620e944e7619845b1a"
- execution_block_height: 476
-- deposit_data:
- pubkey: "0x83f8eb02f40f6369cb8836d521390b06ba91c72618056cd103ede2b6204069ff94c7364c2f24ca1db500ef627be3f1b2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8d236cee7ae8ac4a4b3bc5d71e8f1ef916dac52c731bd0992c3fab191cf2aba1e56bd69b708278715248e63d8f8b8724174c05b8ec955faf684b353c7c29c0e2bbc8b045c62c2554c3d5679e932e7ea6415999140f48860c3977c7149d5565b5"
- deposit_data_root: "0xc157aa44092165b3935d971c9835801dc66b24f54c8d4c387afcc14e2b469204"
- eth1_data:
- deposit_root: "0xe7fcb3f12d9fd24d0ebd089fad35d0a4edd4dca4fad112f72a5a42bf313e54fb"
- deposit_count: "476"
- block_hash: "0x546c6d2e65b628e3015ee8c2d0494a9a20cc098ce586d738f6de069136472497"
- block_height: 477
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xb99e45a812c5eaffd1f6ccb925e913d782b51cd8c371b11727ad48cc0de95d33"
- deposit_root: "0xe7fcb3f12d9fd24d0ebd089fad35d0a4edd4dca4fad112f72a5a42bf313e54fb"
- deposit_count: 476
- execution_block_hash: "0x546c6d2e65b628e3015ee8c2d0494a9a20cc098ce586d738f6de069136472497"
- execution_block_height: 477
-- deposit_data:
- pubkey: "0xb08c6eef8be13656c3963726dc3be95a5087e363fd5e72301322ea73a8840520d51f142cd9d94d0da3b7a6f22d111fd4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x974be67dd9641425535b8630a502c72298b86a579adb8f22d77474d3679ec0d3771190515ffea3cea288c5a401f275aa1951f6a3f226f9d0afd58a12520a51479a4ff168d782162ac242169580463e1e6968609fe0e911fdfe39192c816a3a03"
- deposit_data_root: "0xbafe7c7e5e984655b91e5c85b2a7064664c21483721e8d534bc04ce8c1849a1f"
- eth1_data:
- deposit_root: "0xf41c3d61184e6a446360ecb29eada4910b0694a5f26a281fcc7c07abb81f2f04"
- deposit_count: "477"
- block_hash: "0xbdb7e08ed1e7f61ee28337d7842866c1b545937e7c247d895e8ba87ac1b87cc2"
- block_height: 478
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xb99e45a812c5eaffd1f6ccb925e913d782b51cd8c371b11727ad48cc0de95d33"
- - "0xbafe7c7e5e984655b91e5c85b2a7064664c21483721e8d534bc04ce8c1849a1f"
- deposit_root: "0xf41c3d61184e6a446360ecb29eada4910b0694a5f26a281fcc7c07abb81f2f04"
- deposit_count: 477
- execution_block_hash: "0xbdb7e08ed1e7f61ee28337d7842866c1b545937e7c247d895e8ba87ac1b87cc2"
- execution_block_height: 478
-- deposit_data:
- pubkey: "0x8374c6a0d41b2da67f26a62120128838ab64f3928769a4280d0650ff18d6262b584e8f68a915bf8e4d1f6e18d72a6ecd"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2d63f5fd222d3c4db2c0f7bf4875d7a98cbd9511a43cc448df75d682984ed16035d3a9ea512c8da123d78400a29751910aeb767cf9361e2af7d50f4680796c3fc7a499028508c1de8093f6c4a9faa2d2e8737e39e90efc7b7f6304c79e471a9"
- deposit_data_root: "0x646da1db4ebfa44f98a74e708b6834ef0b3547d3ed62f4aa5ea28922b9ceb10f"
- eth1_data:
- deposit_root: "0xbbae20cfeb909f6a6c3efb0bdbf43a91e0111ac12305726d7c6ff78f0337edeb"
- deposit_count: "478"
- block_hash: "0xdad4caa2c941c49d2f6f9f8dba86a411d4cad65a2a89c6a12d017f08ba5bd381"
- block_height: 479
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xb99e45a812c5eaffd1f6ccb925e913d782b51cd8c371b11727ad48cc0de95d33"
- - "0xe4c5f8b27ed915c009a548dee4da3ba212b3c42979ac7fa6c80abfe02d1172dd"
- deposit_root: "0xbbae20cfeb909f6a6c3efb0bdbf43a91e0111ac12305726d7c6ff78f0337edeb"
- deposit_count: 478
- execution_block_hash: "0xdad4caa2c941c49d2f6f9f8dba86a411d4cad65a2a89c6a12d017f08ba5bd381"
- execution_block_height: 479
-- deposit_data:
- pubkey: "0xb98aeef39fb7eecc46e6cff2632a543757a8bd80bebe409b5d0eafe2922583040749cee9f130cf12eebf85c1dfc0adb4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x85fb8f084baed303cafc16887d1fd22b1ae16cf9a6978a9bdbea426975b183896a1ea8731b3ad9a61e0211519123cda50cbf3814f821938b9365ab4058228162aa1448881c64f410e15f09de147be4076ab418319748f97c09a57e18f3117370"
- deposit_data_root: "0xa196eee94becd475763319784c5f9a7ba0854e82893a0d9cf21d4952e08dddab"
- eth1_data:
- deposit_root: "0xb491c8ebe5be3cf6e59268e03ebc32a74e64efce2c805e1b328d3d2d8034af48"
- deposit_count: "479"
- block_hash: "0x56ca5f2c24ea7f40984bc5b6c97b289b23e33c6199d917b0dff9fa2e12607b60"
- block_height: 480
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x539c3abb99dc0d3652e3032b3abdd4f5d531d3783ac3c97c10e77108952d53fc"
- - "0x399784c504476260102e50dbb4284f4f83d3acc78686434e89711b29ffb00b2b"
- - "0xb99e45a812c5eaffd1f6ccb925e913d782b51cd8c371b11727ad48cc0de95d33"
- - "0xe4c5f8b27ed915c009a548dee4da3ba212b3c42979ac7fa6c80abfe02d1172dd"
- - "0xa196eee94becd475763319784c5f9a7ba0854e82893a0d9cf21d4952e08dddab"
- deposit_root: "0xb491c8ebe5be3cf6e59268e03ebc32a74e64efce2c805e1b328d3d2d8034af48"
- deposit_count: 479
- execution_block_hash: "0x56ca5f2c24ea7f40984bc5b6c97b289b23e33c6199d917b0dff9fa2e12607b60"
- execution_block_height: 480
-- deposit_data:
- pubkey: "0x8f9e00f60b9b830e72b7d0b45a3dab2cda1f678880db3b5dc5107e07850dc5146afe8b0999102d4a8bca5cbc27cd8a2c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x967c3931f641a1b00bf1d2f1f05b0d39470d3a18009ac4069f5b69f8c3d90129c10d5b0cf81fde69ae27470a47834d3a0946c9d6edbfbb3386910d3e881a34dd9b58ee1c51b34bf3c60920c52d449adcd850fe9a3e662e449cf50e02ef80eeb0"
- deposit_data_root: "0x1d584d8969a792467db268a84b71823f5421782407a24814519c5480593bdf72"
- eth1_data:
- deposit_root: "0x134da8281281e224a0ffb96b845d7792e22fcedd065ef136210928ec2804fc8b"
- deposit_count: "480"
- block_hash: "0x0c9865641090c264e1d7cbc1b65b0faf1005121540dc51869caba029aec61f22"
- block_height: 481
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- deposit_root: "0x134da8281281e224a0ffb96b845d7792e22fcedd065ef136210928ec2804fc8b"
- deposit_count: 480
- execution_block_hash: "0x0c9865641090c264e1d7cbc1b65b0faf1005121540dc51869caba029aec61f22"
- execution_block_height: 481
-- deposit_data:
- pubkey: "0xb42800735102f10b3e09c11e9113e0f4955bd19d0c5174f587d446de44230b10c3e8b439fbfc2e47f9e82ac2ade917b3"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa26895838394e4ead46ee443e6e76d42af792263bdf42113c206e99cde1d5ec5784f2a072691e1bfa9e29664741c3944009fdad153287feb4c172dde4ac6b63825c4211f2c09c0ca619f8c83b2c82a618aadfc27058df67685c437033cb23e1b"
- deposit_data_root: "0xc2a1be8de10512de15ce813468cadd14fec5f4dcff841434ef8ac94b0d4a1e8c"
- eth1_data:
- deposit_root: "0xd45d33b559eb5e75ad5e92d049659ab27a2c036a7aa315ec40fbcf807a8b78a2"
- deposit_count: "481"
- block_hash: "0x8c9122b92253122ed84adea540862612634d94e7c00df5df311278d785176f1f"
- block_height: 482
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xc2a1be8de10512de15ce813468cadd14fec5f4dcff841434ef8ac94b0d4a1e8c"
- deposit_root: "0xd45d33b559eb5e75ad5e92d049659ab27a2c036a7aa315ec40fbcf807a8b78a2"
- deposit_count: 481
- execution_block_hash: "0x8c9122b92253122ed84adea540862612634d94e7c00df5df311278d785176f1f"
- execution_block_height: 482
-- deposit_data:
- pubkey: "0x877968c73d43465feea583c7bde8270773fbcdcf9d1e3e4fe492a208e788bb56b329174b0d2539d96877e9d6f5bf1b41"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x83a31f50234740124160bb83287570c689c12df4415aa7d784fee273425568f566481089d6b910c6477cd982601d9b381333fa40c666da37750771f365a4998d6f2e1c5eb8412df44a7d4038b5528b3a624cc0af754e79e6e310e8669cef79f9"
- deposit_data_root: "0x5796c508baf67aa0316bd134dfd20381d7ccaa37735914bf83f122dd762e5ca2"
- eth1_data:
- deposit_root: "0x9d0ac2b2a873b08b17e722eb0893f30e4518ad523ee623d0567aa82dabc6dd32"
- deposit_count: "482"
- block_hash: "0xfde6c5dfbc17f3071be1020ace406b179a5e30640bc33c304b8e8264719aedd7"
- block_height: 483
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xdd4de29f488ddda22d81e4e7a3e890a1c2fa2f4602bf5612e8af70c852b459cc"
- deposit_root: "0x9d0ac2b2a873b08b17e722eb0893f30e4518ad523ee623d0567aa82dabc6dd32"
- deposit_count: 482
- execution_block_hash: "0xfde6c5dfbc17f3071be1020ace406b179a5e30640bc33c304b8e8264719aedd7"
- execution_block_height: 483
-- deposit_data:
- pubkey: "0x915fdf1928be84527b07ceccbc4a278f1e9e010d6f716d8c3a4666bf649411744355ef25b22276c2ab51b3af29c67119"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa3624f6211be2fcca00aeacae32fbc4101e787724ccd33d7293053b35ac8364784da5202037343024f4c94c86ce0a0ba171efaa129810f463e6f1337e59bea4aee8da537b313ccf72d207859d51bc2bec6c585e2598747b0b7e9f824ffb9f75b"
- deposit_data_root: "0x823ace95fa80327a404d8bc47116e2f39db4807f1547044d2f855459a6910f88"
- eth1_data:
- deposit_root: "0x34065c8a5baf250ed894b10d34c0b32b892d3457967219896e660caab4900265"
- deposit_count: "483"
- block_hash: "0x15dafdb4863cb94e4f40272996afd55a2772e370e89b8a75114fbd6706099b96"
- block_height: 484
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xdd4de29f488ddda22d81e4e7a3e890a1c2fa2f4602bf5612e8af70c852b459cc"
- - "0x823ace95fa80327a404d8bc47116e2f39db4807f1547044d2f855459a6910f88"
- deposit_root: "0x34065c8a5baf250ed894b10d34c0b32b892d3457967219896e660caab4900265"
- deposit_count: 483
- execution_block_hash: "0x15dafdb4863cb94e4f40272996afd55a2772e370e89b8a75114fbd6706099b96"
- execution_block_height: 484
-- deposit_data:
- pubkey: "0xa99b23673a9c02a8da9e44fda564aaacabc12fac43b600884e06ff21ca2ece8fb8ca28c593d3966ec6ff427f8f497c05"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa2e5bfd6972dc7e1224cd3a6cb8eb2120f88cb43912bbeac84e359e10ad2c707c6318c1a9edda7f10e0ec8a7c41af9e613fe59d07f50a3f5027e63c11b391ed425d1c6ab7ceea8681f310d34fe9b2c658c81472c30f89a6034d9f79ed5979b53"
- deposit_data_root: "0x726ba60cf4b669785203993565bb3b21592a22fdd92ed204db8774bd95854cf9"
- eth1_data:
- deposit_root: "0x5a94789da4c0fa8f904274e1a6be5fe01019d467234f560932302dc4480c9207"
- deposit_count: "484"
- block_hash: "0x5978eac6de2f57ef776f150ff7337be8d7323810da27f674804c0e2c34322109"
- block_height: 485
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xf8fc1b0c4abcf5d5c5214689c52a6c792ebb882fa93e6cdd79998c5bd752a4e1"
- deposit_root: "0x5a94789da4c0fa8f904274e1a6be5fe01019d467234f560932302dc4480c9207"
- deposit_count: 484
- execution_block_hash: "0x5978eac6de2f57ef776f150ff7337be8d7323810da27f674804c0e2c34322109"
- execution_block_height: 485
-- deposit_data:
- pubkey: "0x8759613fcfec38cf67297fc0b956382eb403f1b9126d1de3a26e0ee7142346d5457f09c7765d82d49f51726293b3cf7e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9924c8222eea8672b5aa21d38fca95cdaecadda51e373cd60100f1084e96140d333d2b01f60308bc8ca3ece43f1f915311b478bdefe9302188d636d3321ab684530f32cd8fa62b2ca575e0d3ac6b163a1934dc5e702af08253dd68c61f039e4a"
- deposit_data_root: "0x9613b659ffe2c9842167aa76d78262e1b72c7815b2751f4e9abc40bdc833a793"
- eth1_data:
- deposit_root: "0x301a60c707ce54ecd68bf6ab842130f5687966e5e3d6802c98a93105b8fffa6c"
- deposit_count: "485"
- block_hash: "0x33d4c030649788458fa0fc39cb615cac9e8614791d012c471b8f2c45314a398b"
- block_height: 486
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xf8fc1b0c4abcf5d5c5214689c52a6c792ebb882fa93e6cdd79998c5bd752a4e1"
- - "0x9613b659ffe2c9842167aa76d78262e1b72c7815b2751f4e9abc40bdc833a793"
- deposit_root: "0x301a60c707ce54ecd68bf6ab842130f5687966e5e3d6802c98a93105b8fffa6c"
- deposit_count: 485
- execution_block_hash: "0x33d4c030649788458fa0fc39cb615cac9e8614791d012c471b8f2c45314a398b"
- execution_block_height: 486
-- deposit_data:
- pubkey: "0xa0ab65230a0c9a2e2ec267918366deaa93d80068b14e691de2dff126c604e755b72d0865099078870d6a3d47a2f56d14"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x943d8cdce9bb776c6713cc436e6fe6dd9d3d6f015d79153945078cb204f725192e2bb9c95505b813782265e00532110b10c9c6d08012ead8d3d3ac825dee975cf68caa47a6a83697fec5f753de0480a2c81ec6799f3b9fcee7b561bdf1cd27e6"
- deposit_data_root: "0x02b77bbb8e3d988f7daa40bb4179390f620f74e3f370ca75e40087e188cfb290"
- eth1_data:
- deposit_root: "0xda801f823b9de4864cb8fbac530776a3faf03d59b3a2dbc736799f843ff769c4"
- deposit_count: "486"
- block_hash: "0xf40b8bd6aca0d2df5d30673cb93799ab391c73417d9fcd66c0f36061950258d7"
- block_height: 487
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xf8fc1b0c4abcf5d5c5214689c52a6c792ebb882fa93e6cdd79998c5bd752a4e1"
- - "0xc40108b2f8489c8b37335014f19abcb82e4493969e2c8ec160e771f38a2ac79b"
- deposit_root: "0xda801f823b9de4864cb8fbac530776a3faf03d59b3a2dbc736799f843ff769c4"
- deposit_count: 486
- execution_block_hash: "0xf40b8bd6aca0d2df5d30673cb93799ab391c73417d9fcd66c0f36061950258d7"
- execution_block_height: 487
-- deposit_data:
- pubkey: "0xa76186ca2743b7149ab7b5ab83c843d2d724ed85ef13a9e0e23a697ba048cea17acc68d9dda73d1f4ef97b9747e491ec"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xae8ce2cf4550895297567df5bbe471d3c58caec5fdfb1b526f4f686c0d908b32e3c88e0905344ce7d6c5ccf7d24ac2820da54a60ef97d5ad62f3de61b3f3b5252294b280efb80f24c50c2c9b1e0775b8e263170b373b876051e34e2e8bb14a0d"
- deposit_data_root: "0x992ec5657a0236c36cdeb5c71669678c8d28314815f3f267ee7791968f93ee5a"
- eth1_data:
- deposit_root: "0x178c069965cd1da6422db237305cb7d972195a3320cb2e863a3e36aa0d7a29e6"
- deposit_count: "487"
- block_hash: "0xfbc23345cce8edc158f0ca53ecd03de7f09bc65f648cce073dff8588a7195f0a"
- block_height: 488
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xf8fc1b0c4abcf5d5c5214689c52a6c792ebb882fa93e6cdd79998c5bd752a4e1"
- - "0xc40108b2f8489c8b37335014f19abcb82e4493969e2c8ec160e771f38a2ac79b"
- - "0x992ec5657a0236c36cdeb5c71669678c8d28314815f3f267ee7791968f93ee5a"
- deposit_root: "0x178c069965cd1da6422db237305cb7d972195a3320cb2e863a3e36aa0d7a29e6"
- deposit_count: 487
- execution_block_hash: "0xfbc23345cce8edc158f0ca53ecd03de7f09bc65f648cce073dff8588a7195f0a"
- execution_block_height: 488
-- deposit_data:
- pubkey: "0xa70362ba9834a49f9f1ffdccf221fc2eb1f7a5cb584bded1d79c44e7e7890ab28d787004c5cc6a45d0e941ae27f1fe39"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9840593dfd806431b6892e7c3026ea49084c25df871ba5dc8c9a28d5b2f8c9bd5379233c68d4af650f4409c6c5d814dd1337059655b61267c924f0f271eb7284702eff667a9ee4ac2994fef2a8c601d32a3ab39406f31c55976b824e5569f2c0"
- deposit_data_root: "0xd5b2e76b1095e39dc9cd525aab3f0ad77b8e3210c9950cffd3247cca2c2d93d9"
- eth1_data:
- deposit_root: "0xacc5e8c62a70a8b48ea72c2b7dcf7e81d33b98d0e7299f96830c4c9a87bc5b12"
- deposit_count: "488"
- block_hash: "0xe7952006db942a66abc5319d9ce249354eada481eee6cdaf97fe348f928dbd3e"
- block_height: 489
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- deposit_root: "0xacc5e8c62a70a8b48ea72c2b7dcf7e81d33b98d0e7299f96830c4c9a87bc5b12"
- deposit_count: 488
- execution_block_hash: "0xe7952006db942a66abc5319d9ce249354eada481eee6cdaf97fe348f928dbd3e"
- execution_block_height: 489
-- deposit_data:
- pubkey: "0xac66effd5784f677ff6fa5cb96d9cf14552d5888a8cd78ff54581b9fb35d3980c9b34cab41f565288812d77e3a44cceb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb7d4c0669a88e0f84cfc9c5d53bf41d7703bed37597ccc66902f8d8271e7a595b2f170c13072e25c9630384a5a9070cc18a783226667704a6858fff0e77ff24dba0df19aa8ad71056fd18598dce161e4d547c3f29190803204de160e859af69d"
- deposit_data_root: "0x952612c181f310ef8c2b53d2022d08549f4d21d9d0d603d44b2bd3809e5b333b"
- eth1_data:
- deposit_root: "0xaee05275977d88ab3de85c1ef629864f36fa9ad8bc59500eb34e56ebfb724130"
- deposit_count: "489"
- block_hash: "0xbb1f6f7c565f47fa6e524ee0901d2b8b7a402895f4ccb7ee210723d757715869"
- block_height: 490
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0x952612c181f310ef8c2b53d2022d08549f4d21d9d0d603d44b2bd3809e5b333b"
- deposit_root: "0xaee05275977d88ab3de85c1ef629864f36fa9ad8bc59500eb34e56ebfb724130"
- deposit_count: 489
- execution_block_hash: "0xbb1f6f7c565f47fa6e524ee0901d2b8b7a402895f4ccb7ee210723d757715869"
- execution_block_height: 490
-- deposit_data:
- pubkey: "0x933146088cae286d7d0c2759fab13c1f3e7cea13c05504c006e2ac25f322a779905fe4466f0db965620767d6270ac324"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa8a74b8afa78efaabefa3316ed4fb2715e2be3c0bc70b3df6b04c13f8d19ffe08df3558a083a1b34ceb06fb44c437cc9189378d8a785f2a3ac68606189d06f3787944c2b28f249bbd0755ffc2772f523a5cc2502a89f52be0d225c7330d9f478"
- deposit_data_root: "0xbc62013d7afb2e7f7c9c306c73449cef0f5b76e80568d3efe50744b3586c3c6a"
- eth1_data:
- deposit_root: "0x41dcb927c029b48451acb6f81bb177f21ec50556bce33f91939011f29fc834fd"
- deposit_count: "490"
- block_hash: "0x0af4b9127af4de48537331081e5d471983a3787901800be316b3060496e718dc"
- block_height: 491
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0xc2117c26af280c0c49598e0448112e04588ab6a3ee01b2be0a1380ccd6ab884a"
- deposit_root: "0x41dcb927c029b48451acb6f81bb177f21ec50556bce33f91939011f29fc834fd"
- deposit_count: 490
- execution_block_hash: "0x0af4b9127af4de48537331081e5d471983a3787901800be316b3060496e718dc"
- execution_block_height: 491
-- deposit_data:
- pubkey: "0xb31a6cb5ab165f4b7b66bee6fcab77e410a3c7d7049ca5a6a7bc64b30a1c49bef4a1ed72454b87c8b879c00c57212ac2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8b9393ad8fe5132742cb3f2cfc722f9f80c98dfec7055a09fe4d9ee744c484d5ab234d1be89e8686ab6173096be867340b7d4c8ec2b76a4974a5e4f75664fcf6a82f95089fa8d284296a9e7608a88e8668974abfc58c0cc5552bdb0633449312"
- deposit_data_root: "0x38e2586880e59ae2b10e79b4bbea1bbf4fff9eb24c0e76e9eeff1117ecf7e326"
- eth1_data:
- deposit_root: "0xdc6d5c39bd67371b5a38d2baa1180139c09dd6e762ed5274586d6fae140aef33"
- deposit_count: "491"
- block_hash: "0x10a29b7a13bbba866147b26e86cb01908d83599a1dd6734fc5cbab0c8d5c2761"
- block_height: 492
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0xc2117c26af280c0c49598e0448112e04588ab6a3ee01b2be0a1380ccd6ab884a"
- - "0x38e2586880e59ae2b10e79b4bbea1bbf4fff9eb24c0e76e9eeff1117ecf7e326"
- deposit_root: "0xdc6d5c39bd67371b5a38d2baa1180139c09dd6e762ed5274586d6fae140aef33"
- deposit_count: 491
- execution_block_hash: "0x10a29b7a13bbba866147b26e86cb01908d83599a1dd6734fc5cbab0c8d5c2761"
- execution_block_height: 492
-- deposit_data:
- pubkey: "0x9570f6171cbc78d58dd8afd84cc2f803ab049dcc15566b4c16406f798b65346f3bb36c45aff846e4604ab79ddba8125f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa93e273b50dbfbc9306d5dc86e49923e641166456f2930ebd3ca51ee1db9bc21bcfc27d90de43a76657c3f302456093b02adc0e553601ee8781f149c9c9e38021222db3614ac89f5789a9d0765bb94d03e0dc034b62a828317dd583d44a47efd"
- deposit_data_root: "0x52e9547d5df15475ad6635a94d60a382d8170a9e94db26e2948dfbc1838bba10"
- eth1_data:
- deposit_root: "0x22824f94535edf7e747a7ffe09ee5000d430a32a5eb63a223e6e888e558d6840"
- deposit_count: "492"
- block_hash: "0x24b8b1fb9de52367089b9098ba02dd01657c2da749dcefc4ff56f5c68c6852e7"
- block_height: 493
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0x4f8311465fde082df60a4db44e53bcd965cf3a8f39d3166b2a769cf8a5cdc758"
- deposit_root: "0x22824f94535edf7e747a7ffe09ee5000d430a32a5eb63a223e6e888e558d6840"
- deposit_count: 492
- execution_block_hash: "0x24b8b1fb9de52367089b9098ba02dd01657c2da749dcefc4ff56f5c68c6852e7"
- execution_block_height: 493
-- deposit_data:
- pubkey: "0x871e9ef179706974e0423fb0a6f17673dd3d91ac9625a5c034d2797c396698489dff3c53abea15b7b5604919fd36acf6"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x84eb083fb8262d0a9d6c1ba20a5ceeee8d8b4fa4643cca03b6fd7b8affe3245c57a60294732b27b05adf0ca549bf0187040b38828218e89fa3905975e37a6d0f7c3664b271bda3a996f698fb081f98606c079016017e45388f4abfed55d5acb6"
- deposit_data_root: "0x366bca78131fd8260d4223c1c7c2c4fed8d22a5f43647b8bb5692ede92d255bc"
- eth1_data:
- deposit_root: "0xe5cac4e82791679b4044bfa3435209aa4b6388af630191371a7851eaa79b3529"
- deposit_count: "493"
- block_hash: "0xe4511513af4b15a09c1f2e1fd8ca52c6425803ef329133541130331d5ea134ba"
- block_height: 494
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0x4f8311465fde082df60a4db44e53bcd965cf3a8f39d3166b2a769cf8a5cdc758"
- - "0x366bca78131fd8260d4223c1c7c2c4fed8d22a5f43647b8bb5692ede92d255bc"
- deposit_root: "0xe5cac4e82791679b4044bfa3435209aa4b6388af630191371a7851eaa79b3529"
- deposit_count: 493
- execution_block_hash: "0xe4511513af4b15a09c1f2e1fd8ca52c6425803ef329133541130331d5ea134ba"
- execution_block_height: 494
-- deposit_data:
- pubkey: "0x879391eff950beb2720f83aa628e43b313ec26e20cad9b75457bd8de5b1883fad8c5f28533ebebac4e377d82145d75da"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8a31291a8934809c33b88d68754d8abc0c6740474264c475d2e825f550b79cc4ba4d767f152afd628eb956ab0198014e18c365a66d4e9c6d5c92c8879791a41a9940304a419fabedb6d64d58706083e94afbca69c35718e6dbc8e97ead3ce50e"
- deposit_data_root: "0xa2d9df9463cd8a99c0caa53d39a2b5339149c329935288339b2dffda66babd34"
- eth1_data:
- deposit_root: "0x137fab1083cfe288afb0dc871b75b475b1cab3d6989cea5ec1ddc30588bcf9f3"
- deposit_count: "494"
- block_hash: "0xf5faca75aad4bc3195af3ce6e8cc953c804344697267f9621dc4d3d18d919ad4"
- block_height: 495
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0x4f8311465fde082df60a4db44e53bcd965cf3a8f39d3166b2a769cf8a5cdc758"
- - "0xa3645b2bae71b310416e701a535d888cc14e78d867e2e88703a09b93af06de0d"
- deposit_root: "0x137fab1083cfe288afb0dc871b75b475b1cab3d6989cea5ec1ddc30588bcf9f3"
- deposit_count: 494
- execution_block_hash: "0xf5faca75aad4bc3195af3ce6e8cc953c804344697267f9621dc4d3d18d919ad4"
- execution_block_height: 495
-- deposit_data:
- pubkey: "0xb03bdf830d2cf1c1d8f0bb100fb3d4d399b48ca2e67e8f8513809bdf49beeb4b710438d64bdd9f4d4aebc3cc844e9302"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb81d217f78655216903e2c617be8cc10455b5f58335f522a91c35329693d5af7e906e490edd919f63d74c27b142570bf1407f26517a16835c18f6032683939359fa721e3f9ed56b8a38aec6aa36d4fa344e80a0cf16f0c990bba0d4e1d9758bc"
- deposit_data_root: "0xd4872c8e2cd8f5fe969e07d8c702201df480500077039ef03baa524e4eecb5d5"
- eth1_data:
- deposit_root: "0x89ee072c31cf8d3c38c359eae18f99047dad53e040e404ce65f758d8973dd831"
- deposit_count: "495"
- block_hash: "0x2a4557f04eda1cfab40813fbfaa9d0cd3297311d4c35f56aa325e83b44667b4f"
- block_height: 496
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0x3875f467344ea7151aaeaf8d2f3c78cf2dacd91f8a81b6ab8ca1e02df2fff953"
- - "0x4f8311465fde082df60a4db44e53bcd965cf3a8f39d3166b2a769cf8a5cdc758"
- - "0xa3645b2bae71b310416e701a535d888cc14e78d867e2e88703a09b93af06de0d"
- - "0xd4872c8e2cd8f5fe969e07d8c702201df480500077039ef03baa524e4eecb5d5"
- deposit_root: "0x89ee072c31cf8d3c38c359eae18f99047dad53e040e404ce65f758d8973dd831"
- deposit_count: 495
- execution_block_hash: "0x2a4557f04eda1cfab40813fbfaa9d0cd3297311d4c35f56aa325e83b44667b4f"
- execution_block_height: 496
-- deposit_data:
- pubkey: "0xadf6fceba8b405cb2a0e853da1a8db38799eaf868a91294a297f0ba4601731a438f1f7a8b15c91cbc7b4f07734d74ac0"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9055a60776e60b558d5722e5f168b13f4ba31940ad146948423a771e4973081bc99b9247ad648af178b11d1331cadd83014504c0cc289afa2c399b983dca0a01c5a5c4b321fcd615b185f982e6663dbaadb0b9222681e841c452810421ce28c0"
- deposit_data_root: "0xb89408cff9700bea9c5070d4bcae6f0a4b5171f4232a341f5f6d259b15d51461"
- eth1_data:
- deposit_root: "0xed3c614ac36483433d060e8e8576cb18c7aaad8b5fa57c067869a892e83aff98"
- deposit_count: "496"
- block_hash: "0x15efa8aba9883de6c511364fc9949a2ce28fd1320914681c40cff4c7d03dd4e3"
- block_height: 497
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- deposit_root: "0xed3c614ac36483433d060e8e8576cb18c7aaad8b5fa57c067869a892e83aff98"
- deposit_count: 496
- execution_block_hash: "0x15efa8aba9883de6c511364fc9949a2ce28fd1320914681c40cff4c7d03dd4e3"
- execution_block_height: 497
-- deposit_data:
- pubkey: "0xa931ae0ef4447284cad9e27b334924088b87f489d1c1eb49883cd2f35e4cd445dfac88e564605b32d471b56b4d98a4cb"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x927f3ded1db0e263965b5dc1433649056672f337df5a66e46e23be11287c60fb5fb83cc1878af02f020a41a52a5524730965f98460e4ec8faa34cfa7f82f84f7847e163a97bde7fd6326048787a0e65e71eb49225d2e00ef180a46eacb5821d9"
- deposit_data_root: "0x8526ea94647b0af12f3cda3d20987c8914451a827b81da295d625c6621de481c"
- eth1_data:
- deposit_root: "0x421728e94bc65613888da789ec8a68a70a9396a248416cf46a2ade5debdf71c7"
- deposit_count: "497"
- block_hash: "0x01e5154c23dc0820fddb99b9d1c36c7564750cb38a39c18cf3b1f2f6db3d036c"
- block_height: 498
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0x8526ea94647b0af12f3cda3d20987c8914451a827b81da295d625c6621de481c"
- deposit_root: "0x421728e94bc65613888da789ec8a68a70a9396a248416cf46a2ade5debdf71c7"
- deposit_count: 497
- execution_block_hash: "0x01e5154c23dc0820fddb99b9d1c36c7564750cb38a39c18cf3b1f2f6db3d036c"
- execution_block_height: 498
-- deposit_data:
- pubkey: "0xb304ff0820279e94ad069248706d39bddb36cb1ef69e1031f2f0683c69b4e8fe5bee35a64a7d160f8f207253bf6a1080"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xad022d059131eaf12492893f3b4d531ef72f713a18b5965e2f24a30d759e997809ae16fa808210f38cab0f7b3a244a0419913fb6805654a9b0e02e426e47b2aa363b8bddcaaf36569383559214a5a79d8190f9a268a30532c3e42866e02ca21f"
- deposit_data_root: "0x46c229cd0c3e568093841a1e7d92c9bfa369d9dc633067c83aee89f0cd754c3e"
- eth1_data:
- deposit_root: "0xdb3a62269b0ddfe5139f62b8b90c661c1f7e5e36821357e1b6e7e3288d9ec2ab"
- deposit_count: "498"
- block_hash: "0xcdd347d62aa299215a836ce87a9f671d2cb8dd4541325c26dfc66b5c87cf937e"
- block_height: 499
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf2b54cd30ee3995c110c2028f35d5a400cb8a1ce9600757c8bae0e426db572c9"
- deposit_root: "0xdb3a62269b0ddfe5139f62b8b90c661c1f7e5e36821357e1b6e7e3288d9ec2ab"
- deposit_count: 498
- execution_block_hash: "0xcdd347d62aa299215a836ce87a9f671d2cb8dd4541325c26dfc66b5c87cf937e"
- execution_block_height: 499
-- deposit_data:
- pubkey: "0xb51c0882970b04879282a60dcfda6577abd62328859c811ad190b4a77b824e4ef7dcfa544f7e76ad0d0c53372e9ba43f"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb67d9631d1380573c574fc1a57dfd7266a42318b253955bfc2fadb55af3eabdbb311950c219ae6ca5ea8e7a8967ba7a41519a96a7437c7fa24bdbe02ae13f7191308eacab1528639d0efd1b4d195006b63f862202175e8975fa5b7f86461f481"
- deposit_data_root: "0x5342789288be2a5531cb6f31633584200615948145d3542a266e2b8965edc64b"
- eth1_data:
- deposit_root: "0x54c8df95f9d2b54939012347e05c3214e517c55d8540807b1ad754619c5a971d"
- deposit_count: "499"
- block_hash: "0x0b9574a4021e274198282a737f25de33d496573581e0912393315b491ea15ef2"
- block_height: 500
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf2b54cd30ee3995c110c2028f35d5a400cb8a1ce9600757c8bae0e426db572c9"
- - "0x5342789288be2a5531cb6f31633584200615948145d3542a266e2b8965edc64b"
- deposit_root: "0x54c8df95f9d2b54939012347e05c3214e517c55d8540807b1ad754619c5a971d"
- deposit_count: 499
- execution_block_hash: "0x0b9574a4021e274198282a737f25de33d496573581e0912393315b491ea15ef2"
- execution_block_height: 500
-- deposit_data:
- pubkey: "0xa24dd1ce8d1d5af40401a2c2d47027de989313ead893a646456eb4ea9d6e38cf8cd37f75e2dfa631beed89970848a39c"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x91637e293d8b865c76aa80ccaa42e10dce7e1002647423cefa8e67c740f755a5b7b833a7b201e54a4d1a0a563963716412cb466eadd67b17d67c922d34f9f6e3c9ec1ad09434685cd0c7c3e1008ec84f4db02c3054023cea1d7716739129a3fe"
- deposit_data_root: "0x721297ec667e7bfec80ee3780c2a99c345a4a4de112c6c18acf2b2f7d9c01539"
- eth1_data:
- deposit_root: "0x695c65690f919bc3d1a81d29b03fbe3799754db34e73dd334d614198f58e7f78"
- deposit_count: "500"
- block_hash: "0x525ada6ebdc963f5b0cb396229e629557816abb142eb8e8161d5cfc5b7d2432d"
- block_height: 501
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf71b0bf2bd3427f729de49cbe1f7cad35e2e80960e2f4a865c936f4197f74327"
- deposit_root: "0x695c65690f919bc3d1a81d29b03fbe3799754db34e73dd334d614198f58e7f78"
- deposit_count: 500
- execution_block_hash: "0x525ada6ebdc963f5b0cb396229e629557816abb142eb8e8161d5cfc5b7d2432d"
- execution_block_height: 501
-- deposit_data:
- pubkey: "0x943c88ab60e1b649772ebefea93e27bdc89bae1901cb8f181fb813a753861bf7e3c460b909566f30be2ad7ecc7e345aa"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb6cbee3d623fcd4a2bdf4b372ac8a54bea60d3b9a3c1079336a2250f6584b0bb0f5ff6fe074211a733ba8c0bd52d102e0ead892d2c8c7258d80048f03717498493cba834a30c966fff67b205ad6ac3a1ede20f3c9ed50305f07d3f2ac89863af"
- deposit_data_root: "0x563286c1b77c9e1d183fb518d9f263071cb48a8069db366a6aeca6bd4ec35842"
- eth1_data:
- deposit_root: "0xb11904549318b9f97731d696ceaf2a039e35e5b779234026e50f7e8a678bbdb9"
- deposit_count: "501"
- block_hash: "0xa936f16a1d89a846f3001253b571b6ca0f0aba7e546382dee4a0dbcc7a63c63a"
- block_height: 502
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf71b0bf2bd3427f729de49cbe1f7cad35e2e80960e2f4a865c936f4197f74327"
- - "0x563286c1b77c9e1d183fb518d9f263071cb48a8069db366a6aeca6bd4ec35842"
- deposit_root: "0xb11904549318b9f97731d696ceaf2a039e35e5b779234026e50f7e8a678bbdb9"
- deposit_count: 501
- execution_block_hash: "0xa936f16a1d89a846f3001253b571b6ca0f0aba7e546382dee4a0dbcc7a63c63a"
- execution_block_height: 502
-- deposit_data:
- pubkey: "0xa2eea192ab4a2213efc58879ce008f8684c3b8da24d7a0124ed33c6ee9d3d12adcac702a938e2ccad79fde467fa413c4"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa25236c672bf2eb19b4a8a9da4564a35e2f3c8545f4190ce5916009f0957a28784622d6840a806f29df5a27e99d58057014595ab84d62f0d8edb67e4fa91504f68b906f9a975bb62da0714929fb0cb1262345bca6e2b71d0db4bc5d7f353397d"
- deposit_data_root: "0x3691a26d2ceb9f3a6417d2c53d9ed3fd5cc2fbcc1211d78ed5d2e21d7930ac17"
- eth1_data:
- deposit_root: "0x601b2c94d23ab5858f4eacb14fda5eeb7408d13582a6afdb24b8fc91f1ade8a1"
- deposit_count: "502"
- block_hash: "0x040c9bd5cc7316ee54b15126e380a8795a352165ba3eea6328e65389101541bb"
- block_height: 503
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf71b0bf2bd3427f729de49cbe1f7cad35e2e80960e2f4a865c936f4197f74327"
- - "0xa3d1c3c7ccbc27ed4d1edd2579de324b7a53144a936ee798b133252cb1eb8466"
- deposit_root: "0x601b2c94d23ab5858f4eacb14fda5eeb7408d13582a6afdb24b8fc91f1ade8a1"
- deposit_count: 502
- execution_block_hash: "0x040c9bd5cc7316ee54b15126e380a8795a352165ba3eea6328e65389101541bb"
- execution_block_height: 503
-- deposit_data:
- pubkey: "0xa1792fc5047546bc98391908b80fc9b4a790018b580836cfa593426624ab1785d11449a03c93759f34645d277e9f26ee"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xaa2521a398340e4fa390e4335a1cb3fe7e840ad6da4dec4c03332250ebd2d43fb6b7a968c6c06e50389fd654b08c338a143b1ccd26fb428a0b6df28d07d294d87cb214f7be07a59cf4f5326a17b801b9d1c37e8e44930420639784b5ee777cb8"
- deposit_data_root: "0x4bec8c542e2bfb99d7e4703013705c2c3192f21335f1ea00d5267e869640c31c"
- eth1_data:
- deposit_root: "0x3f0fbcbb62eb78578683087a8869a260b30b001bb6afdb53246538c61e686b6f"
- deposit_count: "503"
- block_hash: "0x5c8134c7e7bb2f1bc0781ddc9b331afd5be19587aaac6c911a617f8cdb9a6204"
- block_height: 504
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xf71b0bf2bd3427f729de49cbe1f7cad35e2e80960e2f4a865c936f4197f74327"
- - "0xa3d1c3c7ccbc27ed4d1edd2579de324b7a53144a936ee798b133252cb1eb8466"
- - "0x4bec8c542e2bfb99d7e4703013705c2c3192f21335f1ea00d5267e869640c31c"
- deposit_root: "0x3f0fbcbb62eb78578683087a8869a260b30b001bb6afdb53246538c61e686b6f"
- deposit_count: 503
- execution_block_hash: "0x5c8134c7e7bb2f1bc0781ddc9b331afd5be19587aaac6c911a617f8cdb9a6204"
- execution_block_height: 504
-- deposit_data:
- pubkey: "0xb2f64f70753f79fc04398f220f2ee1a54d14c8bd31c1b27105aae559d5006434135e516e975f57c7a41241ac74ab6aaa"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa17e776cdecb5f4c33b2a84cd37b12bb2bba06fc0e95ec255a0722ef32b2b273d2dd47001574d9ac254c7451be09614702d2761cada37688adb3babade14bbaf03a480f771ce1bc52824f73518dc1dea9786d1dfd34407fa83974ad8c79c5849"
- deposit_data_root: "0xd4b6855d328858c320b36bbffda4a196e410d8ddf105c387c8ed7d3781853ab3"
- eth1_data:
- deposit_root: "0xd656f74b083d9e27e3d9a38247dc8ef3a48fa128173e054d6e8cc476a07a5dc0"
- deposit_count: "504"
- block_hash: "0xfd8f2f9a3cbc74fc6def66bcf7362ab06ffaa26414ec2be744954381e6e6c8e9"
- block_height: 505
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- deposit_root: "0xd656f74b083d9e27e3d9a38247dc8ef3a48fa128173e054d6e8cc476a07a5dc0"
- deposit_count: 504
- execution_block_hash: "0xfd8f2f9a3cbc74fc6def66bcf7362ab06ffaa26414ec2be744954381e6e6c8e9"
- execution_block_height: 505
-- deposit_data:
- pubkey: "0x86195e4462e04f6e0f4c2545ecc9c0fa812f1ffd6cde31bef2f59c5806d839937d60bd8180c2362555f73aadf6591965"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x834363e5f9c86333ab75a6a75f31324e5789d3fa705a4cb13c86a8045c27b9a37e8648ce6b0bf3f1d1c57007e40b54d80a3cc975baff2463345a3c438668f70ba5fa4cf906f7a23687eddb0b2c46a2957ecc1d3867ff5c2462c7448112089311"
- deposit_data_root: "0xfa190fba4e1bf49150b7c76cfd7d07f269d46fe04f08995bb7473345b2bb4499"
- eth1_data:
- deposit_root: "0x723a02ae297d5787bbc4a3a1b30783fcd486c0ccd9428873c237d78d97ecdf2b"
- deposit_count: "505"
- block_hash: "0xd31b757dc9ab9e121243a12efd22177616a1a0327335121b63f0d91f175b3344"
- block_height: 506
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0xfa190fba4e1bf49150b7c76cfd7d07f269d46fe04f08995bb7473345b2bb4499"
- deposit_root: "0x723a02ae297d5787bbc4a3a1b30783fcd486c0ccd9428873c237d78d97ecdf2b"
- deposit_count: 505
- execution_block_hash: "0xd31b757dc9ab9e121243a12efd22177616a1a0327335121b63f0d91f175b3344"
- execution_block_height: 506
-- deposit_data:
- pubkey: "0x8a6d7746a13800bc06e455dc52786c35065e2b08054ab8e569e28391dbef3d2527eea72aa60e1b53a54dc477055bccf2"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x96725d9c529a3bec9780a7d693e589c2e1b8e2d328d21e52a9ade535810501c0f2f9e45022564b3e8c9c371d9cfada1e03098990f36a9a2e6defd299ce06e9ff8f90a683a2a4bc0083bb2c424a4e3311f95cbd030962305808dfafd5967eb1ba"
- deposit_data_root: "0x998a3d35a682a46fde29ea288109b96a4b24a246a7d4b24f7572bcff109d6ade"
- eth1_data:
- deposit_root: "0xc748ed0905ebcfec8085a8c67091ac467642915c73dd758f432b5e8658a90044"
- deposit_count: "506"
- block_hash: "0x28b47914e0960b493976bc8ee4cc861fa19f640d6a3369df08b413c550540df9"
- block_height: 507
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x9e659e07ef110f0141fdce5a789ae1a54952cadb33028e879430eb600ef4d58a"
- deposit_root: "0xc748ed0905ebcfec8085a8c67091ac467642915c73dd758f432b5e8658a90044"
- deposit_count: 506
- execution_block_hash: "0x28b47914e0960b493976bc8ee4cc861fa19f640d6a3369df08b413c550540df9"
- execution_block_height: 507
-- deposit_data:
- pubkey: "0x961cc399896c8daecb0784f91943dd32077c9ad661f460f27f048ffc557010b4bd9a4a692306b6f70ff0f597fd31ecbe"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x9049a268bf99261658ce1087a0b7874a059b951c7a03bc56f46ab0474efefc1c245bbda655bd994d25576df5ce7ef3e30345a606af54bf4d171dc0dddcf6122f71ec286f57a543767b2869ff2f84df30e324a682011c250e52d2bda21eef798d"
- deposit_data_root: "0xc0107b388528dd8ec080388c8313dd88c9c6e6fc742a27081881a5209c084295"
- eth1_data:
- deposit_root: "0x0c016b6f117e5507d6e740412dda9f7e5cdd539650a8a424e7a06c836408078a"
- deposit_count: "507"
- block_hash: "0xf89a37f7162803e84f7ffbaf0f5ea73306993adfd524d7aa060d49316b96c607"
- block_height: 508
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x9e659e07ef110f0141fdce5a789ae1a54952cadb33028e879430eb600ef4d58a"
- - "0xc0107b388528dd8ec080388c8313dd88c9c6e6fc742a27081881a5209c084295"
- deposit_root: "0x0c016b6f117e5507d6e740412dda9f7e5cdd539650a8a424e7a06c836408078a"
- deposit_count: 507
- execution_block_hash: "0xf89a37f7162803e84f7ffbaf0f5ea73306993adfd524d7aa060d49316b96c607"
- execution_block_height: 508
-- deposit_data:
- pubkey: "0x8edb799cc0407cf8db901082d7fcd613b7dd4ea03caef14073841e54531bdcdf3f661d551edae045b960b506e70b8dc8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xa88cca9dc14b177d45e96da17be05c999f86f12db33ad5060b82e53f9a94949542bcec1ca0422d16de2439ee5fa1215615d16bd0e50ea1e3f9abcbe8096ca51837243a709a6fb02c9dfe443dc2e175af845465108d49132b0e94a3833e10080d"
- deposit_data_root: "0xdc384b4f094fc826477b19d9126ec7e2937fc95fb19397073f00e211e9dfc8b1"
- eth1_data:
- deposit_root: "0xf0ac44f68f2ebad7f114356cabeee522a8dfd5713da8a875d28630edbf2ba3d6"
- deposit_count: "508"
- block_hash: "0x14ce1569b047c9a4015e7ff6b15b90cf19bae216e88e578651af70927afc5425"
- block_height: 509
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x755680bc147f24f2b5988a005d2af577aaa2f9364a17d97436a7296698418aa3"
- deposit_root: "0xf0ac44f68f2ebad7f114356cabeee522a8dfd5713da8a875d28630edbf2ba3d6"
- deposit_count: 508
- execution_block_hash: "0x14ce1569b047c9a4015e7ff6b15b90cf19bae216e88e578651af70927afc5425"
- execution_block_height: 509
-- deposit_data:
- pubkey: "0x8eab84a4394a69ff45dad4a17d4a8ce3bb04948c68bc70abbdebdd76c2156507a319d5bf9cfcaf750fe3b4d5c66723ee"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x921e0672eee586061a353cb40a0586354fbcf92c7c94be47a0e35f58c183bac72959dac50d83cc6e826ae29540ae4924048bfa5adc5b6be5fc4df54816a41fc265f514e2393796c454e822baff3ecedfcff8c36ca56731df32ca9f868219db1a"
- deposit_data_root: "0x9538b1a35a2401f1ae3146672fb986168c4872d6ce0ff63f9fd8fcc590b81a05"
- eth1_data:
- deposit_root: "0x2be7501704a28527b0cde140e090ae14b1951facdd019b1bbdb5a53165663b90"
- deposit_count: "509"
- block_hash: "0xc092fd8e7712ceb3e8b1db31d939638233c0768396159d836fd8fae04a020db3"
- block_height: 510
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x755680bc147f24f2b5988a005d2af577aaa2f9364a17d97436a7296698418aa3"
- - "0x9538b1a35a2401f1ae3146672fb986168c4872d6ce0ff63f9fd8fcc590b81a05"
- deposit_root: "0x2be7501704a28527b0cde140e090ae14b1951facdd019b1bbdb5a53165663b90"
- deposit_count: 509
- execution_block_hash: "0xc092fd8e7712ceb3e8b1db31d939638233c0768396159d836fd8fae04a020db3"
- execution_block_height: 510
-- deposit_data:
- pubkey: "0xb4c37ed40d2d3d2ace8ba3e1d0bb1b0651d3d21c3dc5e8a4ef42513d649fc14d6dcd1ba7c8b893a2205f6afc870feb75"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x990065021cd5c4395a74ee4ef2bd3ae57e6a69afbb520c9af1793e2272ccf96252cb24cdc06f566d930939e709493e700610c5de71a888a01ae07f6e9eae7995e8c4a8e2ae2a0c9d19832ebd90dc3218857253a453f419681fe5974a56f5beee"
- deposit_data_root: "0x79922ab72714b5a5f07b6d4ad531260bdc3da6b2723f5a621a19f49d14f080d4"
- eth1_data:
- deposit_root: "0x904cf102790d85df5521caba1f278f99ed62a6b72fc1aa7a9c9731014b4b08c7"
- deposit_count: "510"
- block_hash: "0x59ecebf2c2f7d2de32d3de30320e7b278ca84c9ab21fecb0bc129a56eab60ef0"
- block_height: 511
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x755680bc147f24f2b5988a005d2af577aaa2f9364a17d97436a7296698418aa3"
- - "0x1ae3fbc472814f00a5434bbc76e084c37564a55fee67c206c9977c152b12c38e"
- deposit_root: "0x904cf102790d85df5521caba1f278f99ed62a6b72fc1aa7a9c9731014b4b08c7"
- deposit_count: 510
- execution_block_hash: "0x59ecebf2c2f7d2de32d3de30320e7b278ca84c9ab21fecb0bc129a56eab60ef0"
- execution_block_height: 511
-- deposit_data:
- pubkey: "0xb02b650ec8c8a75cdb3c8cc64b612c5180aa31e0345ce16b1d9d8e5c7ce28d4feb8ed6bab0be68c13a5acd71f326fab8"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0x8eb8590912f2736f59f2fc221f167f9806159c922a041d94e1cb7dbd1703e84d7ea54623ffd01aeefab48ded3accac940610dacc940565a4bdadbd586bb7ea7e95cd8a6439363963618fb3332ae2eb1a33fdde5a20871550188a5a21657b141b"
- deposit_data_root: "0xaa58eeff0a6439e85c0062387253ed726b0dcb040f1ad6f9e2dd2ea9ef6b0d41"
- eth1_data:
- deposit_root: "0xdf4c6590595af97badd52a23a3d2da9e1171340d3e9d299ea462b482822e3680"
- deposit_count: "511"
- block_hash: "0xc5db6286114149aacff6eaae584d859fbbcbb914cb3f111447844e76e7623822"
- block_height: 512
- snapshot:
- finalized:
- - "0x1be35e1ed8992a8d55a57ee0a215ffa733e7e66282acfd151ad96e813963f4a1"
- - "0xce176f39f29e8b5f6cbd3d107bf8a2e6162266aef4ee4aa784e6c899474ca670"
- - "0xbfa916399e17a4550bfb5997c9b20433cc80c876ad0cf18df57493bce4dc8d29"
- - "0x61f220b3f77327db30183075bd0e691acebd9aa729ace9b85d6381f40bbabd15"
- - "0xbe91342b23cac4f3b516349701aa3357b170da8ebd6769691d1c633f0391b2be"
- - "0xe129a1eb08eea7dc270c6d43e68441450375894e2bb046328e0ce35a68faca31"
- - "0x755680bc147f24f2b5988a005d2af577aaa2f9364a17d97436a7296698418aa3"
- - "0x1ae3fbc472814f00a5434bbc76e084c37564a55fee67c206c9977c152b12c38e"
- - "0xaa58eeff0a6439e85c0062387253ed726b0dcb040f1ad6f9e2dd2ea9ef6b0d41"
- deposit_root: "0xdf4c6590595af97badd52a23a3d2da9e1171340d3e9d299ea462b482822e3680"
- deposit_count: 511
- execution_block_hash: "0xc5db6286114149aacff6eaae584d859fbbcbb914cb3f111447844e76e7623822"
- execution_block_height: 512
-- deposit_data:
- pubkey: "0x890bbabc36dc93557dffada73af2e71bd15481fb5345d7b4755498ddb1bd8733f0140cc40007c76ccc8764ba42678d1e"
- withdrawal_credentials: "0x0000000000000000000000000000000000000000000000000000000000000000"
- amount: "32000000000"
- signature: "0xb2e4b4c3d177fbeacd0a4cfbb4eb8504e380b2354b5ffac72705ff61fbea065af6793ec133971dcc7da8cef0fe3ff61d06ea05be4f1e2b88c29be2d769008a9a1385c156861553587913c0a0fe74fc3a2efdc90111a0a1fbc96f7c16234c0909"
- deposit_data_root: "0xa26a328f61bac695e879575ad50b38d5e643ff8df03bfd1cd7f55da6e64e9228"
- eth1_data:
- deposit_root: "0x556a4bfa525440a9e36ac1758db883caf80a0226ea195e91445e01621a67f875"
- deposit_count: "512"
- block_hash: "0x5d025ae62b16de0ebfc98e502cc0aa0e583efa4537d6c68273634ebbcb648749"
- block_height: 513
- snapshot:
- finalized:
- - "0xff99e90235f5818855c9114be9ce29d0f028bcab5032cfbcf634609b211268b1"
- deposit_root: "0x556a4bfa525440a9e36ac1758db883caf80a0226ea195e91445e01621a67f875"
- deposit_count: 512
- execution_block_hash: "0x5d025ae62b16de0ebfc98e502cc0aa0e583efa4537d6c68273634ebbcb648749"
- execution_block_height: 513
-
diff --git a/assets/eip-4881/test_deposit_snapshot.py b/assets/eip-4881/test_deposit_snapshot.py
deleted file mode 100755
index c0b8ed1..0000000
--- a/assets/eip-4881/test_deposit_snapshot.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env python3
-import pytest
-import yaml
-from dataclasses import dataclass
-from deposit_snapshot import DepositTree,DepositTreeSnapshot
-from eip_4881 import DepositData,DEPOSIT_CONTRACT_DEPTH,Eth1Data,Hash32,sha256,uint64,zerohashes
-
-@dataclass
-class DepositTestCase:
- deposit_data: DepositData
- deposit_data_root: Hash32
- eth1_data: Eth1Data
- block_height: uint64
- snapshot: DepositTreeSnapshot
-
-def get_hex(some_bytes) -> str:
- return "0x{}".format(some_bytes.hex())
-
-def get_bytes(hexstr) -> bytes:
- return bytes.fromhex(hexstr.replace("0x",""))
-
-def read_test_cases(filename):
- with open(filename, "r") as file:
- try:
- test_cases = yaml.safe_load(file)
- result = []
- for test_case in test_cases:
- deposit_data = DepositData(
- get_bytes(test_case['deposit_data']['pubkey']),
- get_bytes(test_case['deposit_data']['withdrawal_credentials']),
- int(test_case['deposit_data']['amount']),
- get_bytes(test_case['deposit_data']['signature'])
- )
- eth1_data = Eth1Data(
- get_bytes(test_case['eth1_data']['deposit_root']),
- int(test_case['eth1_data']['deposit_count']),
- get_bytes(test_case['eth1_data']['block_hash'])
- )
- finalized = []
- for block_hash in test_case['snapshot']['finalized']:
- finalized.append(get_bytes(block_hash))
- snapshot = DepositTreeSnapshot(
- finalized,
- get_bytes(test_case['snapshot']['deposit_root']),
- int(test_case['snapshot']['deposit_count']),
- get_bytes(test_case['snapshot']['execution_block_hash']),
- int(test_case['snapshot']['execution_block_height'])
- )
- result.append(DepositTestCase(
- deposit_data,
- get_bytes(test_case['deposit_data_root']),
- eth1_data,
- int(test_case['block_height']),
- snapshot
- ))
- return result
- except yaml.YAMLError as exc:
- print(exc)
- assert(False)
-
-def merkle_root_from_branch(leaf, branch, index) -> Hash32:
- root = leaf
- for (i, leaf) in enumerate(branch):
- ith_bit = (index >> i) & 0x1
- if ith_bit == 1:
- root = sha256(leaf + root)
- else:
- root = sha256(root + leaf)
- return root
-
-def check_proof(tree, index):
- leaf, proof = tree.get_proof(index)
- calc_root = merkle_root_from_branch(leaf, proof, index)
- assert(calc_root == tree.get_root())
-
-def compare_proof(tree1, tree2, index):
- assert(tree1.get_root() == tree2.get_root())
- check_proof(tree1, index)
- check_proof(tree2, index)
-
-def clone_from_snapshot(snapshot, test_cases):
- copy = DepositTree.from_snapshot(snapshot)
- for case in test_cases:
- copy.push_leaf(case.deposit_data_root)
- return copy
-
-def test_instantiate():
- DepositTree.new()
-
-def test_empty_root():
- empty = DepositTree.new()
- assert(
- empty.get_root() ==
- bytes.fromhex(
- "d70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e"
- )
- )
-
-def test_deposit_cases():
- tree = DepositTree.new()
- test_cases = read_test_cases("test_cases.yaml")
- for case in test_cases:
- tree.push_leaf(case.deposit_data_root)
- expected = case.eth1_data.deposit_root
- assert(case.snapshot.calculate_root() == expected)
- assert(tree.get_root() == expected)
-
-def test_finalization():
- tree = DepositTree.new()
- test_cases = read_test_cases("test_cases.yaml")[:128] # only need subset
- for case in test_cases:
- tree.push_leaf(case.deposit_data_root)
- original_root = tree.get_root()
- assert(original_root == test_cases[127].eth1_data.deposit_root)
- tree.finalize(test_cases[100].eth1_data, test_cases[100].block_height)
- # ensure finalization doesn't change root
- assert(tree.get_root() == original_root)
- snapshot = tree.get_snapshot()
- assert(snapshot == test_cases[100].snapshot)
- # create a copy of the tree from a snapshot by replaying
- # the deposits after the finalized deposit
- copy = clone_from_snapshot(snapshot, test_cases[101:128])
- # ensure original and copy have the same root
- assert(tree.get_root() == copy.get_root())
- # finalize original again to check double finalization
- tree.finalize(test_cases[105].eth1_data, test_cases[105].block_height)
- # root should still be the same
- assert(tree.get_root() == original_root)
- # create a copy of the tree by taking a snapshot again
- copy = clone_from_snapshot(tree.get_snapshot(), test_cases[106:128])
- # create a copy of the tree by replaying ALL deposits from nothing
- full_tree_copy = DepositTree.new()
- for case in test_cases:
- full_tree_copy.push_leaf(case.deposit_data_root)
- # ensure the proofs are the same and valid for each tree
- for index in range(106, 128):
- compare_proof(tree, copy, index)
- compare_proof(tree, full_tree_copy, index)
-
-def test_snapshot_cases():
- tree = DepositTree.new()
- test_cases = read_test_cases("test_cases.yaml")
- for case in test_cases:
- tree.push_leaf(case.deposit_data_root)
-
- for case in test_cases:
- tree.finalize(case.eth1_data, case.block_height)
- assert(tree.get_snapshot() == case.snapshot)
-
-def test_empty_tree_snapshot():
- with pytest.raises(AssertionError):
- # can't get snapshot from tree that hasn't been finalized
- snapshot = DepositTree.new().get_snapshot()
-
-def test_invalid_snapshot():
- with pytest.raises(AssertionError):
- # invalid snapshot (deposit root doesn't match)
- invalid_snapshot = DepositTreeSnapshot([], zerohashes[0], 0, zerohashes[0], 0)
- tree = DepositTree.from_snapshot(invalid_snapshot)
-
diff --git a/assets/eip-4886/contracts/EPS.sol b/assets/eip-4886/contracts/EPS.sol
deleted file mode 100644
index 303450c..0000000
--- a/assets/eip-4886/contracts/EPS.sol
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.7.0 (epsproxy/contracts/EPS.sol)
-
-pragma solidity ^0.8.9;
-
-/**
- * @dev Implementation of the EPS register interface.
- */
-interface EPS {
- // Emitted when an address nominates a proxy address:
- event NominationMade(address indexed nominator, address indexed proxy, uint256 timestamp, uint256 provider);
- // Emitted when an address accepts a proxy nomination:
- event NominationAccepted(address indexed nominator, address indexed proxy, address indexed delivery, uint256 timestamp, uint256 provider);
- // Emitted when the proxy address updates the delivery address on a record:
- event DeliveryUpdated(address indexed nominator, address indexed proxy, address indexed delivery, address oldDelivery, uint256 timestamp, uint256 provider);
- // Emitted when a nomination record is deleted. initiator 0 = nominator, 1 = proxy:
- event NominationDeleted(string initiator, address indexed nominator, address indexed proxy, uint256 timestamp, uint256 provider);
- // Emitted when a register record is deleted. initiator 0 = nominator, 1 = proxy:
- event RecordDeleted(string initiator, address indexed nominator, address indexed proxy, address indexed delivery, uint256 timestamp, uint256 provider);
- // Emitted when the register fee is set:
- event RegisterFeeSet(uint256 indexed registerFee);
- // Emitted when the treasury address is set:
- event TreasuryAddressSet(address indexed treasuryAddress);
- // Emitted on withdrawal to the treasury address:
- event Withdrawal(uint256 indexed amount, uint256 timestamp);
-
- function nominationExists(address _nominator) external view returns (bool);
- function nominationExistsForCaller() external view returns (bool);
- function proxyRecordExists(address _proxy) external view returns (bool);
- function proxyRecordExistsForCaller() external view returns (bool);
- function nominatorRecordExists(address _nominator) external view returns (bool);
- function nominatorRecordExistsForCaller() external view returns (bool);
- function getProxyRecord(address _proxy) external view returns (address nominator, address proxy, address delivery);
- function getProxyRecordForCaller() external view returns (address nominator, address proxy, address delivery);
- function getNominatorRecord(address _nominator) external view returns (address nominator, address proxy, address delivery);
- function getNominatorRecordForCaller() external view returns (address nominator, address proxy, address delivery);
- function addressIsActive(address _receivedAddress) external view returns (bool);
- function addressIsActiveForCaller() external view returns (bool);
- function getNomination(address _nominator) external view returns (address proxy);
- function getNominationForCaller() external view returns (address proxy);
- function getAddresses(address _receivedAddress) external view returns (address nominator, address delivery, bool isProxied);
- function getAddressesForCaller() external view returns (address nominator, address delivery, bool isProxied);
- function getRole(address _roleAddress) external view returns (string memory currentRole);
- function getRoleForCaller() external view returns (string memory currentRole);
- function makeNomination(address _proxy, uint256 _provider) external payable;
- function acceptNomination(address _nominator, address _delivery, uint256 _provider) external;
- function updateDeliveryAddress(address _delivery, uint256 _provider) external;
- function deleteRecordByNominator(uint256 _provider) external;
- function deleteRecordByProxy(uint256 _provider) external;
- function setRegisterFee(uint256 _registerFee) external returns (bool);
- function getRegisterFee() external view returns (uint256 _registerFee);
- function setTreasuryAddress(address _treasuryAddress) external returns (bool);
- function getTreasuryAddress() external view returns (address _treasuryAddress);
- function withdraw(uint256 _amount) external returns (bool);
-}
\ No newline at end of file
diff --git a/assets/eip-4886/contracts/Proxiable.sol b/assets/eip-4886/contracts/Proxiable.sol
deleted file mode 100644
index c6607b6..0000000
--- a/assets/eip-4886/contracts/Proxiable.sol
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.7.0 (epsproxy/contracts/Proxiable.sol)
-
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/utils/Context.sol";
-import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import "@epsproxy/contracts/EPS.sol";
-
-/**
- * @dev Contract module which allows children to implement calls to the EPS
- * proxy registry
- */
-
-abstract contract Proxiable is Context {
-
- EPS eps; // Address for the relevant chain passed in on the constructor.
-
- /**
- * @dev Constructor initialises the register contract object
- */
- constructor(
- address _epsRegisterAddress
- ) {
- eps = EPS(_epsRegisterAddress);
- }
-
- /**
- * @dev Returns the proxied address details (nominator and delivery address) for a passed proxy address
- */
- function getAddresses(address _receivedAddress) internal view returns (address nominator, address delivery, bool isProxied) {
- return (eps.getAddresses(_receivedAddress));
- }
-
- /**
- * @dev Returns true if this is currently a proxy address (i.e. has an entry that isn't expired):
- */
- function proxyRecordExists(address _receivedAddress) internal view returns (bool isProxied) {
- return (eps.proxyRecordExists(_receivedAddress));
- }
-
- /**
- * @dev Returns an ERC20 token balance for the nominator, if a proxy record exists, or for the address
- * passed in if no proxy record exists.
- */
- function ERC20BalanceOfNominator(address _receivedAddress, address tokenContract) internal virtual view returns (uint256 _tokenBalance){
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_receivedAddress);
- return IERC20(tokenContract).balanceOf(nominator);
- }
-
- /**
- * @dev Returns an ERC20 token balance for the nominator, if a proxy record exists, or for the address
- * passed in if no proxy record exists, IF we have been passed a bool indicating
- * that a proxied address is in use. This function should be used in conjunction with an off-chain call
- * to proxyRecordExists that determines if a proxy address is in use, which is then passed in on the call
- * to the contract inheriting this method. This saves gas for anyone who is NOT using a proxy as we do not needlessly check for proxy details.
- */
- function ERC20BalanceOfNominatorSwitched(address _receivedAddress, address _tokenContract, bool _isProxied) internal virtual view returns (uint256 _tokenBalance){
- if (_isProxied) {
- return ERC20BalanceOfNominator(_receivedAddress, _tokenContract);
- }
- else {
- return IERC20(_tokenContract).balanceOf(_receivedAddress);
- }
- }
-
- /**
- * @dev Returns an ERC721 token balance for the nominator, if a proxy record exists, or for the address
- * passed in if no proxy record exists.
- */
- function ERC721BalanceOfNominator(address _proxy, address tokenContract) internal virtual view returns (uint256 _tokenBalance){
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_proxy);
- return IERC721(tokenContract).balanceOf(nominator);
- }
-
- /**
- * @dev Returns an ERC721 token balance for the nominator, if a proxy record exists, or for the address
- * passed in if no proxy record exists, IF we have been passed a bool indicating
- * that a proxied address is in use. This function should be used in conjunction with an off-chain call
- * to proxyRecordExists that determines if a proxy address is in use, which is then passed in on the call
- * to the contract inheriting this method . This saves gas for anyone who is NOT using a proxy as we do not needlessly check for proxy details.
- */
- function ERC721BalanceOfNominatorSwitched(address _receivedAddress, address _tokenContract, bool _isProxied) internal virtual view returns (uint256 _tokenBalance){
- if (_isProxied) {
- return ERC721BalanceOfNominator(_receivedAddress, _tokenContract);
- }
- else {
- return IERC721(_tokenContract).balanceOf(_receivedAddress);
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4886/contracts/ProxyRegister.sol b/assets/eip-4886/contracts/ProxyRegister.sol
deleted file mode 100644
index cf84817..0000000
--- a/assets/eip-4886/contracts/ProxyRegister.sol
+++ /dev/null
@@ -1,347 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.7.0 (epsproxy/contracts/ProxyRegister.sol)
-
-pragma solidity ^0.8.9;
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@epsproxy/contracts/EPS.sol";
-
-/**
- * @dev The EPS Register contract.
- */
-contract ProxyRegister is EPS, Ownable {
-
- struct Record {
- address nominator;
- address delivery;
- }
-
- uint256 private registerFee;
- address private treasury;
-
- mapping (address => address) nominatorToProxy;
- mapping (address => Record) proxyToRecord;
-
- /**
- * @dev Constructor initialises the register fee and treasury address:
- */
- constructor(
- uint256 _registerFee,
- address _treasury
- ) {
- setRegisterFee(_registerFee);
- setTreasuryAddress(_treasury);
- }
-
- /**
- * @dev Nominators can nominate ONCE only
- */
- modifier isNotCurrentNominator(address _nominator) {
- require(!nominationExists(_nominator), "Address has an existing nomination");
- _;
- }
-
- /**
- * @dev Check if this nominator is already on the registry
- */
- modifier isExistingNominator(address _nominator) {
- require(nominationExists(_nominator), "Nominator entry does not exist");
- _;
- }
-
- /**
- * @dev Proxys can act as proxy ONCE only
- */
- modifier isNotCurrentProxy(address _proxy) {
- require(!proxyRecordExists(_proxy), "Address is already acting as a proxy");
- _;
- }
-
- /**
- * @dev Check if this proxy is already on the registry
- */
- modifier isExistingProxy(address _proxy) {
- require(proxyRecordExists(_proxy), "Proxy entry does not exist");
- _;
- }
-
- /**
- * @dev Return if an entry exists for this nominator address
- */
- function nominationExists(address _nominator) public view returns (bool) {
- return nominatorToProxy[_nominator] != address(0);
- }
-
- /**
- * @dev Return if an entry exists for this nominator address - For Caller
- */
- function nominationExistsForCaller() public view returns (bool) {
- return nominationExists(msg.sender);
- }
-
- /**
- * @dev Return if an entry exists for this proxy address
- */
- function proxyRecordExists(address _proxy) public view returns (bool) {
- return proxyToRecord[_proxy].nominator != address(0);
- }
-
- /**
- * @dev Return if an entry exists for this proxy address - For Caller
- */
- function proxyRecordExistsForCaller() external view returns (bool) {
- return proxyRecordExists(msg.sender);
- }
-
- /**
- * @dev Return if an entry exists for this nominator address
- */
- function nominatorRecordExists(address _nominator) public view returns (bool) {
- return proxyToRecord[nominatorToProxy[_nominator]].nominator != address(0);
- }
-
- /**
- * @dev Return if an entry exists for this nominator address - For Caller
- */
- function nominatorRecordExistsForCaller() external view returns (bool) {
- return nominatorRecordExists(msg.sender);
- }
-
- /**
- * @dev Return if the address is an active proxy address OR a nominator with an active proxy
- */
- function addressIsActive(address _receivedAddress) public view returns (bool) {
- bool isActive = false;
- // Check if the address is an active proxy address or active nominator:
- if (proxyRecordExists(_receivedAddress) || nominatorRecordExists(_receivedAddress)){
- isActive = true;
- }
- return isActive;
- }
-
- /**
- * @dev Return if the address is an active proxy address OR a nominator with an active proxy - For Caller
- */
- function addressIsActiveForCaller() external view returns (bool) {
- return addressIsActive(msg.sender);
- }
-
- /**
- * @dev Get entry details by proxy
- */
- function getProxyRecord(address _proxy) public view returns (address nominator, address proxy, address delivery) {
- Record memory currentItem = proxyToRecord[_proxy];
- return (currentItem.nominator, nominatorToProxy[currentItem.nominator], currentItem.delivery);
- }
-
- /**
- * @dev Get entry details by proxy - For Caller
- */
- function getProxyRecordForCaller() external view returns (address nominator, address proxy, address delivery) {
- return (getProxyRecord(msg.sender));
- }
-
- /**
- * @dev Get entry details by nominator
- */
- function getNominatorRecord(address _nominator) public view returns (address nominator, address proxy, address delivery) {
- address proxyAddress = nominatorToProxy[_nominator];
- if (proxyToRecord[proxyAddress].nominator == address(0)) {
- // This function returns registry entries. If there is no entry on the registry (despite there being a nomination), do
- // not return the proxy address:
- proxyAddress = address(0);
- }
- return (proxyToRecord[proxyAddress].nominator, proxyAddress, proxyToRecord[proxyAddress].delivery);
- }
-
- /**
- * @dev Get entry details by nominator - For Caller
- */
- function getNominatorRecordForCaller() external view returns (address nominator, address proxy, address delivery) {
- return (getNominatorRecord(msg.sender));
- }
-
- /**
- * @dev Get nomination details only for nominator
- */
- function getNomination(address _nominator) public view returns (address proxy) {
- return (nominatorToProxy[_nominator]);
- }
-
- /**
- * @dev Get nomination details only for nominator - For Caller
- */
- function getNominationForCaller() public view returns (address proxy) {
- return (getNomination(msg.sender));
- }
-
- /**
- * @dev Returns the proxied address details (nominator and delivery address) for a passed proxy address
- */
- function getAddresses(address _receivedAddress) public view returns (address nominator, address delivery, bool isProxied) {
- require(!nominationExists(_receivedAddress), "Nominator address cannot interact directly, only through the proxy address");
- Record memory currentItem = proxyToRecord[_receivedAddress];
- if (proxyToRecord[_receivedAddress].nominator == address(0)) {
- return(_receivedAddress, _receivedAddress, false);
- }
- else {
- return (currentItem.nominator, currentItem.delivery, true);
- }
- }
-
- /**
- * @dev Returns the proxied address details (owner and delivery address) for the msg.sender being interacted with
- */
- function getAddressesForCaller() external view returns (address nominator, address delivery, bool isProxied) {
- return (getAddresses(msg.sender));
- }
-
- /**
- * @dev Returns the current role of a given address (nominator, proxy, none)
- */
- function getRole(address _roleAddress) public view returns (string memory currentRole) {
- if (proxyRecordExists(_roleAddress)) {
- return "Proxy";
- }
- if (nominationExists(_roleAddress)) {
- if (proxyRecordExists(nominatorToProxy[_roleAddress])) {
- return "Nominator - Proxy Active";
- }
- else {
- return "Nominator - Proxy Pending";
- }
- }
- return "None";
- }
-
- /**
- * @dev Returns the current role of a given address (nominator, proxy, none) - For Caller
- */
- function getRoleForCaller() external view returns (string memory currentRole) {
- return getRole(msg.sender);
- }
-
- /**
- * @dev The nominator initiates a proxy entry
- */
- function makeNomination(address _proxy, uint256 _provider) external payable isNotCurrentNominator(msg.sender) isNotCurrentProxy(_proxy) isNotCurrentProxy(msg.sender) {
- require (_proxy != address(0), "Proxy address must be provided");
- require (_proxy != msg.sender, "Proxy address cannot be the same as Nominator address");
- require(msg.value == registerFee, "Register fee must be paid");
- nominatorToProxy[msg.sender] = _proxy;
- emit NominationMade(msg.sender, _proxy, block.timestamp, _provider);
- }
-
- /**
- * @dev Proxy accepts nomination
- */
- function acceptNomination(address _nominator, address _delivery, uint256 _provider) external isNotCurrentProxy(msg.sender) isNotCurrentProxy(_nominator) {
- // The nominator must be passed in:
- require (_nominator != address(0), "Nominator address must be provided");
- // The sender must match the proxy nomination:
- require (nominatorToProxy[_nominator] == msg.sender, "Caller is not the nominated proxy for this nominator");
- // We have a valid nomination, create the ProxyRegisterItem:
- proxyToRecord[msg.sender] = Record(_nominator, _delivery);
- emit NominationAccepted(_nominator, msg.sender, _delivery, block.timestamp, _provider);
- }
-
- /**
- * @dev Change delivery address on an existing proxy item. Can only be called by the proxy address.
- */
- function updateDeliveryAddress(address _delivery, uint256 _provider) external isExistingProxy(msg.sender) {
- Record memory priorItem = proxyToRecord[msg.sender];
- proxyToRecord[msg.sender].delivery = _delivery;
- emit DeliveryUpdated(priorItem.nominator, msg.sender, _delivery, priorItem.delivery, block.timestamp, _provider);
- }
-
- /**
- * @dev delete a proxy entry. BOTH the nominator and proxy can delete a proxy arrangement and all
- * aspects of that proxy arrangement will be removed.
- */
- function deleteRecordByNominator(uint256 _provider) external isExistingNominator(msg.sender) {
- deleteProxyRegisterItems(msg.sender, nominatorToProxy[msg.sender], "nominator", _provider);
- }
-
- /**
- * @dev delete a proxy entry. BOTH the nominator and proxy can delete a proxy arrangement and all
- * aspects of that proxy arrangement will be removed.
- */
- function deleteRecordByProxy(uint256 _provider) external isExistingProxy(msg.sender) {
- deleteProxyRegisterItems(proxyToRecord[msg.sender].nominator, msg.sender, "proxy", _provider);
- }
-
- /**
- * @dev delete the nomination and record (if present)
- */
- function deleteProxyRegisterItems(address _nominator, address _proxy, string memory _initiator, uint256 _provider) internal {
- // First remove the nomination. We know this must exists, as it has to come before the proxy can be accepted:
- delete nominatorToProxy[_nominator];
- emit NominationDeleted(_initiator, _nominator, _proxy, block.timestamp, _provider);
- // Now remove the proxy register item. If the nominator is deleting a nomination that has not been accepted by a proxy
- // then this will not exists. Check that the proxy is for this nominator.
- if (proxyToRecord[_proxy].nominator == _nominator) {
- address deletedDelivery = proxyToRecord[_proxy].delivery;
- delete proxyToRecord[_proxy];
- emit RecordDeleted(_initiator, _nominator, _proxy, deletedDelivery, block.timestamp, _provider);
- }
- }
-
- /**
- * @dev set the fee for initiating a registration (accepting a proxy, updating the delivery address and deletions will always be free)
- */
- function setRegisterFee(uint256 _registerFee) public onlyOwner returns (bool)
- {
- require(_registerFee != registerFee, "No change to register fee");
- registerFee = _registerFee;
- emit RegisterFeeSet(registerFee);
- return true;
- }
-
- /**
- * @dev return the register fee:
- */
- function getRegisterFee() external view returns (uint256 _registerFee) {
- return(registerFee);
- }
-
- /**
- * @dev set the treasury address:
- */
- function setTreasuryAddress(address _treasuryAddress) public onlyOwner returns (bool)
- {
- require(_treasuryAddress != treasury, "No change to treasury address");
- treasury = _treasuryAddress;
- emit TreasuryAddressSet(treasury);
- return true;
- }
-
- /**
- * @dev get the treasury address:
- */
- function getTreasuryAddress() external view returns (address _treasuryAddress) {
- return(treasury);
- }
-
- /**
- * @dev withdraw eth to the treasury:
- */
- function withdraw(uint256 _amount) external onlyOwner returns (bool) {
- (bool success, ) = treasury.call{value: _amount}("");
- require(success, "Withdrawal failed.");
- emit Withdrawal(_amount, block.timestamp);
- return true;
- }
-
- /**
- * @dev revert fallback
- */
- fallback() external payable {
- revert();
- }
-
- /**
- * @dev revert receive
- */
- receive() external payable {
- revert();
- }
-}
diff --git a/assets/eip-4886/contracts/examples/EPSExample721.sol b/assets/eip-4886/contracts/examples/EPSExample721.sol
deleted file mode 100644
index b603ff2..0000000
--- a/assets/eip-4886/contracts/examples/EPSExample721.sol
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.8.0 (epsproxy/contracts/examples/EPSExample721.sol)
-
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/utils/Counters.sol";
-import "@openzeppelin/contracts/utils/Strings.sol";
-import "@epsproxy/contracts/Proxiable.sol";
-
-contract EPSExample721 is ERC721, ERC721Burnable, Ownable, Proxiable {
- using Counters for Counters.Counter;
- using Strings for uint256;
-
- Counters.Counter private _tokenIdCounter;
- bool hasMinted;
-
- mapping (address => bool) minterHasMinted;
- uint256 constant MAX_SUPPLY = 10000;
-
- constructor(address _epsRegisterAddress)
- ERC721("EPSExample721", "EPS721")
- Proxiable(_epsRegisterAddress) {
- }
-
- /**
- * @dev This address hasn't minted already
- */
- modifier hasNotAlreadyMinted(address _receivedAddress) {
- require(minterHasMinted[_receivedAddress] != true, "Address has already minted, allocation exhausted");
- _;
- }
-
- modifier isProxyAddress(address _receivedAddress) {
- require(proxyRecordExists(_receivedAddress), "Only a proxy address can mint this token - go to app.epsproxy.com");
- _;
- }
-
- modifier supplyNotExhausted() {
- require(_tokenIdCounter.current() < MAX_SUPPLY, "Max supply reached - cannot be minted");
- _;
- }
-
- function _baseURI() internal pure override returns (string memory) {
- return "https://epsproxy.com/test/";
- }
-
- function totalSupply() public pure returns (uint256) {
- return (MAX_SUPPLY);
- }
-
- function tokenURI(uint256 tokenId) public view override(ERC721) returns (string memory)
- {
- require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
-
- string memory baseURI = _baseURI();
- return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : "";
- }
-
- function proxyMint() external hasNotAlreadyMinted(msg.sender) isProxyAddress(msg.sender) supplyNotExhausted() {
- uint256 tokenId = _tokenIdCounter.current();
- _tokenIdCounter.increment();
- _safeMintProxied(msg.sender, tokenId);
- minterHasMinted[msg.sender] = true;
- }
-
- function _burn(uint256 tokenId) internal override(ERC721) {
- super._burn(tokenId);
- }
-
- /**
- * @dev call safemint after determining the delivery address.
- */
- function _safeMintProxied(address _to, uint256 _tokenId) internal virtual {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_to);
- _safeMint(delivery, _tokenId);
- }
-
- /**
- * @dev call safemint after determining the delivery address IF we have been passed a bool indicating
- * that a proxied address is in use. This function should be used in conjunction with an off-chain call
- * to _proxyRecordExists that determines if a proxy address is in use. This saves gas for anyone who is
- * NOT using a proxy as we do not needlessly check for proxy details.
- */
- function safeMintProxiedSwitch(address _to, uint256 _tokenId, bool _isProxied) internal virtual {
- if (_isProxied) {
- _safeMintProxied(_to, _tokenId);
- }
- else {
- _safeMint(_to, _tokenId);
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4886/contracts/examples/EPSGenesis.sol b/assets/eip-4886/contracts/examples/EPSGenesis.sol
deleted file mode 100644
index f3eab57..0000000
--- a/assets/eip-4886/contracts/examples/EPSGenesis.sol
+++ /dev/null
@@ -1,191 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.8.0 (epsproxy/contracts/examples/EPSGenesis.sol)
-
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
-import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
-import "@epsproxy/contracts/Proxiable.sol";
-
-/**
-* @dev Contract instance for the EPS Genesis ERC-1155. This contract provides two token
-* types designed to showcase the capabilities of the Eternal Proxy Service.
-* - Open mint: Every proxy address can mint ONE of these tokens. Delivery will be to the
-* delivery address. This demonstrates:
-* (a) Retrieval of information and processing based on information in the EPS Register.
-* (b) Delivery of new assets to the delivery address specified on the register.
-* - Gated mint: Every proxy address that acts for a nominator one of three pre-determined
-* NFTs can mint the 'gated' token. This will again be delivered to the delivery address
-* specified on the EPS register. In addition this demonstrates:
-* (c) Checking of the contract balance of the Nominator to determine eligibility. In
-* this use of the EPS register risk to the eligibility asset is entirely eliminated
-* as the contract interaction is with the proxy address, which does not hold the
-* asset, not the nominator.
-*/
-contract EPSGenesis is ERC1155, Ownable, ERC1155Burnable, ERC1155Supply, Proxiable {
-
-/**
-* @dev Not required, but provided to give consistency with ERC-721 in terms of display
-* in tools like etherscan:
-*/
- string public constant NAME = "EPSGenesis";
- string public constant SYMBOL = "EPSGEN";
-
- /**
- * @dev Definition of token classes and max supply of each:
- */
- uint256 public constant OPEN_TOKEN = 0;
- uint256 public constant GATED_TOKEN = 1;
- uint256 public constant MAX_SUPPLY_OPEN = 10000;
- uint256 public constant MAX_SUPPLY_GATED = 10000;
-
- /**
- * @dev tokens that need to be held to mint the gated tokens, provided on the constructor:
- */
- address public immutable GATE_1;
- address public immutable GATE_2;
- address public immutable GATE_3;
-
- /**
- * @dev each address is entitled to just ONE of each type. Each is free, except gas.
- */
- mapping (address => bool) minterHasMintedOpen;
- mapping (address => bool) minterHasMintedGated;
-
- constructor(address _epsRegisterAddress, address _GATE_1, address _GATE_2, address _GATE_3, string memory _contractURI)
- ERC1155(_contractURI)
- Proxiable(_epsRegisterAddress) {
- GATE_1 = _GATE_1;
- GATE_2 = _GATE_2;
- GATE_3 = _GATE_3;
- }
-
- /**
- * @dev modifiers to control access based on previous minting:
- */
- modifier hasNotAlreadyMintedOpen(address _receivedAddress) {
- require(minterHasMintedOpen[_receivedAddress] != true, "Address has already minted in open mint, allocation exhausted");
- _;
- }
-
- modifier hasNotAlreadyMintedGated(address _receivedAddress) {
- require(minterHasMintedGated[_receivedAddress] != true, "Address has already minted in gated mint, allocation exhausted");
- _;
- }
-
- /**
- * @dev modifier to only allow minting from a proxy address:
- */
- modifier isProxyAddress(address _receivedAddress) {
- require(proxyRecordExists(_receivedAddress), "Only a proxy address can mint this token - go to app.epsproxy.com");
- _;
- }
-
- /**
- * @dev modifier to ensure supply(s) is not exhausted:
- */
- modifier supplyNotExhaustedOpen() {
- require(totalSupply(OPEN_TOKEN) < MAX_SUPPLY_OPEN, "Max supply reached for open mint - cannot be minted");
- _;
- }
-
- modifier supplyNotExhaustedGated() {
- require(totalSupply(GATED_TOKEN) < MAX_SUPPLY_GATED, "Max supply reached for gated mint - cannot be minted");
- _;
- }
-
- /**
- * @dev perform minting of the open tokens:
- */
- function proxyMintOpen(address _receivedAddress) internal hasNotAlreadyMintedOpen(_receivedAddress) isProxyAddress(_receivedAddress) supplyNotExhaustedOpen() {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_receivedAddress);
-
- _mint(delivery, OPEN_TOKEN, 1, "");
-
- minterHasMintedOpen[_receivedAddress] = true;
- }
-
- /**
- * @dev perform minting of the gated tokens:
- */
- function proxyMintGated(address _receivedAddress) internal hasNotAlreadyMintedGated(_receivedAddress) isProxyAddress(_receivedAddress) supplyNotExhaustedGated() {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_receivedAddress);
-
- require((IERC721(GATE_1).balanceOf(nominator) >= 1 || IERC721(GATE_2).balanceOf(nominator) >= 1 || IERC721(GATE_3).balanceOf(nominator) >= 1), "Must hold an eligible token for this mint");
-
- _mint(delivery, GATED_TOKEN, 1, "");
-
- minterHasMintedGated[_receivedAddress] = true;
- }
-
- /**
- * @dev external function for minting calls. Required boolean values for open and gated minting (can pass both as true to perform both)
- */
- function mintEPSGenesis(bool mintOpen, bool mintGated) external {
- if (mintOpen) {
- proxyMintOpen(msg.sender);
- }
- if (mintGated) {
- proxyMintGated(msg.sender);
- }
- }
-
- /**
- * @dev external and public functions to determine eligibility off-chain:
- */
- function hasMintedOpen(address _receivedAddress) external view returns (bool) {
- return(minterHasMintedOpen[_receivedAddress]);
- }
-
- function hasMintedGated(address _receivedAddress) external view returns (bool) {
- return(minterHasMintedGated[_receivedAddress]);
- }
-
- function hasAProxyRecord(address _receivedAddress) external view returns (bool) {
- return(proxyRecordExists(_receivedAddress));
- }
-
- function hasNominatorWithEligibleToken(address _receivedAddress) public view returns (bool) {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_receivedAddress);
- return((IERC721(GATE_1).balanceOf(nominator) >= 1 || IERC721(GATE_2).balanceOf(nominator) >= 1 || IERC721(GATE_3).balanceOf(nominator) >= 1));
- }
-
- function addressStatus(address _receivedAddress) public view returns (bool open, bool gated, bool proxy, bool eligible) {
- return(minterHasMintedOpen[_receivedAddress], minterHasMintedGated[_receivedAddress], proxyRecordExists(_receivedAddress), hasNominatorWithEligibleToken(_receivedAddress));
- }
-
- /**
- * @dev name, max and total supply for tools like etherscan:
- */
- function name() public pure returns (string memory) {
- return NAME;
- }
-
- function symbol() public pure returns (string memory) {
- return SYMBOL;
- }
-
- function totalSupply() public pure returns (uint256) {
- return (MAX_SUPPLY_OPEN + MAX_SUPPLY_GATED);
- }
-
- // The following functions are overrides required by Solidity.
-
- function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
- internal
- override(ERC1155, ERC1155Supply)
- {
- super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4886/contracts/examples/ERC20Proxied.sol b/assets/eip-4886/contracts/examples/ERC20Proxied.sol
deleted file mode 100644
index 9971c3f..0000000
--- a/assets/eip-4886/contracts/examples/ERC20Proxied.sol
+++ /dev/null
@@ -1,41 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.8.0 (epsproxy/contracts/examples/ERC20Proxied.sol)
-
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/utils/Context.sol";
-import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
-import "@epsproxy/contracts/Proxiable.sol";
-
-/**
- * @dev Contract module which allows children to implement proxied delivery
- * on minting calls
- */
-abstract contract ERC20Proxied is Context, ERC20, Proxiable {
-
- /**
- * @dev call mint after determining the delivery address.
- */
- function _mintProxied(address _account, uint256 _amount) internal virtual {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_account);
- _mint(delivery, _amount);
- }
-
- /**
- * @dev call mint after determining the delivery address IF we have been passed a bool indicating
- * that a proxied address is in use. This function should be used in conjunction with an off-chain call
- * to _proxyRecordExists that determines if a proxy address is in use. This saves gas for anyone who is
- * NOT using a proxy as we do not needlessly check for proxy details.
- */
- function _MintProxiedSwitch(address _account, uint256 _amount, bool _isProxied) internal virtual {
- if (_isProxied) {
- _mintProxied(_account, _amount);
- }
- else {
- _mint(_account, _amount);
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4886/contracts/examples/ERC721Proxied.sol b/assets/eip-4886/contracts/examples/ERC721Proxied.sol
deleted file mode 100644
index f0df21e..0000000
--- a/assets/eip-4886/contracts/examples/ERC721Proxied.sol
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// EPSProxy Contracts v1.8.0 (epsproxy/contracts/examples/ERC721Proxied.sol)
-
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/utils/Context.sol";
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@epsproxy/contracts/Proxiable.sol";
-
-/**
- * @dev Contract module which allows children to implement proxied delivery
- * on minting calls
- */
-abstract contract ERC721Proxied is Context, ERC721, Proxiable {
-
- constructor(
- address _epsRegisterAddress,
- string memory _name,
- string memory _symbol
- ) Proxiable(_epsRegisterAddress)
- ERC721("_name", "_symbol")
- {
- }
-
- /**
- * @dev Returns the proxied address details (nominator address, delivery address) for a passed proxy address.
- * Call this to view the details for any given proxy address.
- */
- function _getAddresses(address _receivedAddress) internal virtual view returns (address _nominator, address _delivery, bool _isProxied){
- return (getAddresses(_receivedAddress));
- }
-
- /**
- * @dev Returns if a given address is a proxy or not:
- */
- function _proxyRecordExists(address _receivedAddress) internal virtual view returns (bool _isProxied){
- return (proxyRecordExists(_receivedAddress));
- }
-
- /**
- * @dev call safemint after determining the delivery address.
- */
- function _safeMintProxied(address _to, uint256 _tokenId) internal virtual {
- address nominator;
- address delivery;
- bool isProxied;
- (nominator, delivery, isProxied) = getAddresses(_to);
- _safeMint(delivery, _tokenId);
- }
-
- /**
- * @dev call safemint after determining the delivery address IF we have been passed a bool indicating
- * that a proxied address is in use. This function should be used in conjunction with an off-chain call
- * to _proxyRecordExists that determines if a proxy address is in use. This saves gas for anyone who is
- * NOT using a proxy as we do not needlessly check for proxy details.
- */
- function _safeMintProxiedSwitch(address _to, uint256 _tokenId, bool _isProxied) internal virtual {
- if (_isProxied) {
- _safeMintProxied(_to, _tokenId);
- }
- else {
- _safeMint(_to, _tokenId);
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-4886/test/ProxyRegister.js b/assets/eip-4886/test/ProxyRegister.js
deleted file mode 100644
index 47da8a1..0000000
--- a/assets/eip-4886/test/ProxyRegister.js
+++ /dev/null
@@ -1,1412 +0,0 @@
-const { expect } = require("chai")
-const registerFee = 0.005;
-const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"
-const tokenURI = "https://arweave.net/_Kk3lIGmZTnwT6Q67UOTlNG2biZq1F8F9jmoH3EaA14/{id}.json"
-
-describe("Genesis1155", function () {
- let hardhatProxyRegister
- let owner
- let addr1
- let addr2
- let addr3
- let treasury
- let addrs
-
- beforeEach(async function () {
- ;[owner, addr1, addr2, addr3, treasury, ...addrs] = await ethers.getSigners()
-
- const ProxyRegister = await ethers.getContractFactory("ProxyRegister")
- hardhatProxyRegister = await ProxyRegister.deploy(
- ethers.utils.parseEther(registerFee.toString()),
- treasury.address,
- )
-
- const mockERC721 = await ethers.getContractFactory("mockERC721")
- hardhatBoredApes = await mockERC721.deploy()
- hardhatLazyLions = await mockERC721.deploy()
- hardhatLoomlockNFT = await mockERC721.deploy()
-
- const EPSGenOne = await ethers.getContractFactory("EPSGenesis")
- hardhatEPSGenOne = await EPSGenOne.deploy(
- hardhatProxyRegister.address,
- hardhatBoredApes.address,
- hardhatLazyLions.address,
- hardhatLoomlockNFT.address,
- tokenURI
- )
-
- })
-
- context("Non-proxy addresses", function () {
- describe("Minting", function () {
- it("Cannot mint both NFTs", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(true, true),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
-
- })
- it("Cannot mint open NFT", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(true, false),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
- })
- it("Cannot mint gated NFT", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(false, true),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
- })
- })
-
- });
-
- context("Proxy address", function () {
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
- })
-
- describe("Nominator Minting", function () {
- it("Cannot mint both NFTs", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(true, true),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
-
- })
- it("Cannot mint open NFT", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(true, false),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
- })
- it("Cannot mint gated NFT", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr1).mintEPSGenesis(false, true),
- ).to.be.revertedWith("Only a proxy address can mint this token - go to app.epsproxy.com")
- })
- })
-
- describe("Proxy Minting - no eligible token", function () {
- it("Cannot mint both NFTs", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr2).mintEPSGenesis(true, true),
- ).to.be.revertedWith("Must hold an eligible token for this mint")
-
- })
- it("CAN mint open NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, false)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
- })
- it("Cannot mint gated NFT", async () => {
- await expect(
- hardhatEPSGenOne.connect(addr2).mintEPSGenesis(false, true),
- ).to.be.revertedWith("Must hold an eligible token for this mint")
- })
- })
-
- describe("Proxy Minting - eligible token 1", function () {
- beforeEach(async function () {
- var tx1 = await hardhatBoredApes
- .connect(addr1)
- .safeMint()
-
- })
-
- it("CAN mint both NFTs", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
-
- })
- it("CAN mint open NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, false)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
- })
- it("CAN mint gated NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(false, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(1)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
- })
- })
-
- describe("Proxy Minting - eligible token 2", function () {
- beforeEach(async function () {
- var tx1 = await hardhatLazyLions
- .connect(addr1)
- .safeMint()
-
- })
-
- it("CAN mint both NFTs", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
-
- })
- it("CAN mint open NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, false)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
- })
- it("CAN mint gated NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(false, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(1)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
- })
- })
-
- describe("Proxy Minting - eligible token 3", function () {
- beforeEach(async function () {
- var tx1 = await hardhatLoomlockNFT
- .connect(addr1)
- .safeMint()
-
- })
-
- it("CAN mint both NFTs", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
-
- })
- it("CAN mint open NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, false)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
- })
- it("CAN mint gated NFT", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(false, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(1)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
- })
- })
-
- describe("Proxy Minting - eligible token, cannot mint 2 of either", function () {
- beforeEach(async function () {
- var tx1 = await hardhatBoredApes
- .connect(addr1)
- .safeMint()
-
- })
-
- it("Cannot mint 2 on call to both", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
-
- await expect(
- hardhatEPSGenOne.connect(addr2).mintEPSGenesis(true, true),
- ).to.be.revertedWith("Address has already minted in open mint, allocation exhausted")
-
- })
- it("Cannot mint 2 open", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(true, false)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(0)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 0)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 0)).to.equal(1)
-
- await expect(
- hardhatEPSGenOne.connect(addr2).mintEPSGenesis(true, false),
- ).to.be.revertedWith("Address has already minted in open mint, allocation exhausted")
- })
- it("Cannot mint 2 gated", async () => {
- var tx1 = await hardhatEPSGenOne
- .connect(addr2)
- .mintEPSGenesis(false, true)
- expect(tx1).to.emit(hardhatEPSGenOne, "TransferSingle")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.to).to.equal(addr3.address)
- expect(receipt.events[0].args.id).to.equal(1)
- expect(receipt.events[0].args.value).to.equal(1)
-
- expect(await hardhatEPSGenOne.balanceOf(addr1.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr2.address, 1)).to.equal(0)
- expect(await hardhatEPSGenOne.balanceOf(addr3.address, 1)).to.equal(1)
-
- await expect(
- hardhatEPSGenOne.connect(addr2).mintEPSGenesis(false, true),
- ).to.be.revertedWith("Address has already minted in gated mint, allocation exhausted")
- })
- })
- });
-});
-
-describe("ProxyRegister", function () {
- let hardhatProxyRegister
- let owner
- let addr1
- let addr2
- let addr3
- let treasury
- let addrs
-
- beforeEach(async function () {
- ;[owner, addr1, addr2, addr3, treasury, ...addrs] = await ethers.getSigners()
-
- const ProxyRegister = await ethers.getContractFactory("ProxyRegister")
- hardhatProxyRegister = await ProxyRegister.deploy(
- ethers.utils.parseEther(registerFee.toString()),
- treasury.address,
- )
- })
-
- context("Contract Setup", function () {
- describe("Constructor", function () {
- it("Has a contract balance of 0", async () => {
- const contractBalance = await ethers.provider.getBalance(
- hardhatProxyRegister.address,
- )
- expect(contractBalance).to.equal(0)
- })
- })
- });
-
- context("Owner Only Functions", function () {
- describe("Owner can execute", function () {
-
- it("Set registerFee", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(owner)
- .setRegisterFee(ethers.utils.parseEther("0.01"))
- expect(tx1).to.emit(hardhatProxyRegister, "RegisterFeeSet")
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.registerFee).to.equal(BigInt(ethers.utils.parseEther("0.01")))
-
- const registerFeeParameter = await hardhatProxyRegister.getRegisterFee()
- expect(registerFeeParameter).to.equal(ethers.utils.parseEther("0.01"))
- })
-
- it("Set treasuryAddress", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(owner)
- .setTreasuryAddress(addr3.address)
- expect(tx1).to.emit(hardhatProxyRegister, "TreasuryAddressSet")
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.treasuryAddress).to.equal(addr3.address)
-
- const treasuryAddressParameter = await hardhatProxyRegister.getTreasuryAddress()
- expect(treasuryAddressParameter).to.equal(addr3.address)
- })
- })
-
- describe("Non-owner cannot execute", function () {
- it("Set registerFee", async () => {
- await expect(
- hardhatProxyRegister.connect(addr1).setRegisterFee(ethers.utils.parseEther("0.01")),
- ).to.be.revertedWith("Ownable: caller is not the owner")
- })
-
- it("Set treasuryAddress", async () => {
- await expect(
- hardhatProxyRegister.connect(addr1).setTreasuryAddress(addr3.address),
- ).to.be.revertedWith("Ownable: caller is not the owner")
- })
- })
-
- describe("Withdraw", async () => {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- })
-
- it("fails if not owner", async () => {
- await expect(
- hardhatProxyRegister.connect(addr1).withdraw(ethers.utils.parseEther(registerFee.toString())),
- ).to.be.revertedWith("Ownable: caller is not the owner")
- })
-
- it("allows owner to withdraw to the treasury", async () => {
- const withdrawalAmount = ethers.utils.parseEther(registerFee.toString())
-
- expect(
- await ethers.provider.getBalance(hardhatProxyRegister.address),
- ).to.equal(withdrawalAmount)
-
- const initialTreasuryBalance = await ethers.provider.getBalance(
- treasury.address,
- )
- tx = await hardhatProxyRegister.connect(owner).withdraw(withdrawalAmount)
- const receipt = await tx.wait()
- const finalTreasuryBalance = await ethers.provider.getBalance(
- treasury.address,
- )
- const finalContractBalance = await ethers.provider.getBalance(
- hardhatProxyRegister.address,
- )
-
- expect(finalTreasuryBalance).to.equal(
- initialTreasuryBalance.add(withdrawalAmount),
- )
- expect(finalContractBalance).to.equal(0)
- })
- })
- });
-
- context("Nominate a Proxy", function () {
- describe("Add a nomination", function () {
- it("New proxy nomination is added", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.nominator).to.equal(addr1.address)
- expect(receipt.events[0].args.proxy).to.equal(addr2.address)
- currentTime = (await ethers.provider.getBlock("latest")).timestamp
- expect(receipt.events[0].args.timestamp).to.equal(currentTime)
-
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
- })
-
- it("Duplicate proxy nomination not added", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- await expect(
- hardhatProxyRegister.connect(addr1).makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),})
- ).to.be.revertedWith("Address has an existing nomination")
- })
-
- it("Duplicate proxy nomination not added, even to a new proxy address", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- await expect(
-
- hardhatProxyRegister.connect(addr1).makeNomination( addr3.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),})
- ).to.be.revertedWith("Address has an existing nomination")
- })
-
- it("Proxy nomination where nominator is an existing proxy not added", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- await expect(
- hardhatProxyRegister.connect(addr2).makeNomination( addr3.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),})
- ).to.be.revertedWith("Address is already acting as a proxy")
-
- })
-
- it("Proxy nomination for an address that is already a proxy not added", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- await expect(
- hardhatProxyRegister.connect(addr3).makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),})
- ).to.be.revertedWith("Address is already acting as a proxy")
- })
-
- it("Address cannot be proxied to itself", async () => {
- await expect(
- hardhatProxyRegister.connect(addr1).makeNomination( addr1.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),})
- ).to.be.revertedWith("Proxy address cannot be the same as Nominator address")
- })
- })
- })
-
- context("Accept a Nomination", function () {
- describe("Accept the Nomination", function () {
-
- it("Can do if valid", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- const registerEntry1 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr1.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr3.address)
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr2).getProxyRecordForCaller()
- expect(registerEntry2[0]).to.equal(addr1.address)
- expect(registerEntry2[1]).to.equal(addr2.address)
- expect(registerEntry2[2]).to.equal(addr3.address)
-
- })
-
- it("Cannot do for non-existent nomination", async () => {
- await expect(
- hardhatProxyRegister.connect(addr2).acceptNomination( addr1.address, addr3.address, 1)
- ).to.be.revertedWith("Caller is not the nominated proxy for this nominator")
- })
-
- it("Cannot do for another address's nomination", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr3)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- await expect(
- hardhatProxyRegister.connect(addr2).acceptNomination( addr1.address, addr3.address, 1)
- ).to.be.revertedWith("Caller is not the nominated proxy for this nominator")
- })
-
- it("Cannot do for a nominator that is now a proxy", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr3)
- .makeNomination( addr1.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx2).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx3 = await hardhatProxyRegister
- .connect(addr1)
- .acceptNomination( addr3.address, addr3.address, 1,)
- expect(tx3).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- await expect(
- hardhatProxyRegister.connect(addr2).acceptNomination( addr1.address, addr3.address, 1)
- ).to.be.revertedWith("Address is already acting as a proxy")
- })
-
- it("Cannot do for address that is already a proxy", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr3)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx3 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr3.address, addr3.address, 1,)
- expect(tx3).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- await expect(
- hardhatProxyRegister.connect(addr2).acceptNomination( addr1.address, addr3.address, 1)
- ).to.be.revertedWith("Address is already acting as a proxy")
- })
- })
- });
-
-
- context("Change a proxy entry", function () {
-
- describe("Change delivery address", function () {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- const registerEntry1 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr1.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr3.address)
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr2).getProxyRecordForCaller()
- expect(registerEntry2[0]).to.equal(addr1.address)
- expect(registerEntry2[1]).to.equal(addr2.address)
- expect(registerEntry2[2]).to.equal(addr3.address)
- })
-
- it("Proxy Address can update delivery", async () => {
- const previousRegistryEntry = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(previousRegistryEntry[0]).to.equal(addr1.address)
- expect(previousRegistryEntry[1]).to.equal(addr2.address)
- expect(previousRegistryEntry[2]).to.equal(addr3.address)
-
- var tx1 = await hardhatProxyRegister
- .connect(addr2)
- .updateDeliveryAddress( addr1.address, 1,)
- expect(tx1).to.emit(hardhatProxyRegister, "DeliveryUpdated")
-
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.nominator).to.equal(addr1.address)
- expect(receipt.events[0].args.proxy).to.equal(addr2.address)
- expect(receipt.events[0].args.delivery).to.equal(addr1.address)
- expect(receipt.events[0].args.oldDelivery).to.equal(addr3.address)
- currentTime = (await ethers.provider.getBlock("latest")).timestamp
- expect(receipt.events[0].args.timestamp).to.equal(currentTime)
-
- const newRegistryEntry = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(newRegistryEntry[0]).to.equal(addr1.address)
- expect(newRegistryEntry[1]).to.equal(addr2.address)
- expect(newRegistryEntry[2]).to.equal(addr1.address)
- })
-
- it("Nominator cannot edit an entry", async () => {
- const previousRegistryEntry = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(previousRegistryEntry[0]).to.equal(addr1.address)
- expect(previousRegistryEntry[1]).to.equal(addr2.address)
- expect(previousRegistryEntry[2]).to.equal(addr3.address)
-
- await expect(
- hardhatProxyRegister.connect(addr1).updateDeliveryAddress( addr1.address, 1,)
- ).to.be.revertedWith("Proxy entry does not exist")
- })
-
- it("Another address cannot edit an entry", async () => {
- const previousRegistryEntry = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(previousRegistryEntry[0]).to.equal(addr1.address)
- expect(previousRegistryEntry[1]).to.equal(addr2.address)
- expect(previousRegistryEntry[2]).to.equal(addr3.address)
-
- await expect(
- hardhatProxyRegister.connect(addr3).updateDeliveryAddress( addr1.address, 1,)
- ).to.be.revertedWith("Proxy entry does not exist")
- })
- })
- });
-
- context("Delete a proxy entry", function () {
-
- describe("Delete called from Nominator", function () {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.nominator).to.equal(addr1.address)
- expect(receipt.events[0].args.proxy).to.equal(addr2.address)
- currentTime = (await ethers.provider.getBlock("latest")).timestamp
- expect(receipt.events[0].args.timestamp).to.equal(currentTime)
-
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
- })
-
- it("Removes a nomination only", async () => {
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
-
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .deleteRecordByNominator(1,)
- expect(tx1).to.emit(hardhatProxyRegister, "NominationDeleted")
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry2).to.equal(ZERO_ADDRESS)
- })
-
- it("Doesn't remove a proxy entry that is for another nominator", async () => {
- // edge case test, but you can have two addresses both nominate a third address
- // as a proxy. This is OK. Let's say the proxy accepts the second nomination. If the
- // first address (the nomination that wasn't accepted) deletes that nominoation we DON'T
- // want that to delete the second nominator's valud proxy entry, so let's check that
- // doesn't happen
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
-
- // Now load a proxy up from address 3 to address 2:
- var tx1 = await hardhatProxyRegister
- .connect(addr3)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- var receipt = await tx1.wait()
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr3.address, addr1.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- // Verify that addr3 has the proxy with 2:
- const registerEntry1 = await hardhatProxyRegister.connect(addr3).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr3.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr1.address)
-
- // Delete the nomination from address 1:
- var tx3 = await hardhatProxyRegister
- .connect(addr1)
- .deleteRecordByNominator(1,)
- expect(tx3).to.emit(hardhatProxyRegister, "NominationDeleted")
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry2).to.equal(ZERO_ADDRESS)
-
- // Verify that addr3 has the proxy with 2:
- const registerEntry3 = await hardhatProxyRegister.connect(addr3).getNominatorRecordForCaller()
- expect(registerEntry3[0]).to.equal(addr3.address)
- expect(registerEntry3[1]).to.equal(addr2.address)
- expect(registerEntry3[2]).to.equal(addr1.address)
- })
-
- it("Removes nomination and proxy register Item", async () => {
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
-
- const proxyRecordExists = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false)
-
- const proxyEntryExists1 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists1).to.equal(false)
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- const registerEntry1 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr1.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr3.address)
-
- const proxyEntryExists2 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists2).to.equal(true)
-
- const proxyEntryExists3 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists3).to.equal(true)
-
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .deleteRecordByNominator(1,)
- expect(tx1).to.emit(hardhatProxyRegister, "NominationDeleted")
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry2).to.equal(ZERO_ADDRESS)
-
- const proxyEntryExists4 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists4).to.equal(false)
-
- const proxyEntryExists5 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists5).to.equal(false)
- })
- })
-
- describe("Delete called from Proxy", function () {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- var receipt = await tx1.wait()
- expect(receipt.events[0].args.nominator).to.equal(addr1.address)
- expect(receipt.events[0].args.proxy).to.equal(addr2.address)
- currentTime = (await ethers.provider.getBlock("latest")).timestamp
- expect(receipt.events[0].args.timestamp).to.equal(currentTime)
-
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
- })
-
- it("Removes nomination and proxy register Item", async () => {
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
-
- const proxyRecordExists = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false)
-
- const proxyEntryExists1 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists1).to.equal(false)
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- const registerEntry1 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr1.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr3.address)
-
- const proxyEntryExists2 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists2).to.equal(true)
-
- const proxyEntryExists3 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists3).to.equal(true)
-
- var tx1 = await hardhatProxyRegister
- .connect(addr2)
- .deleteRecordByProxy(1,)
- expect(tx1).to.emit(hardhatProxyRegister, "NominationDeleted")
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry2[0]).to.equal(ZERO_ADDRESS)
- expect(registerEntry2[1]).to.equal(ZERO_ADDRESS)
- expect(registerEntry2[2]).to.equal(ZERO_ADDRESS)
-
- const proxyEntryExists4 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists4).to.equal(false)
-
- const proxyEntryExists5 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists5).to.equal(false)
- })
-
- it("Call from Nominator does not work", async () => {
- const registerEntry = await hardhatProxyRegister.connect(addr1).getNominationForCaller()
- expect(registerEntry).to.equal(addr2.address)
-
- const proxyRecordExists = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false)
-
- const proxyEntryExists1 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists1).to.equal(false)
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- const registerEntry1 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry1[0]).to.equal(addr1.address)
- expect(registerEntry1[1]).to.equal(addr2.address)
- expect(registerEntry1[2]).to.equal(addr3.address)
-
- const proxyEntryExists2 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists2).to.equal(true)
-
- const proxyEntryExists3 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists3).to.equal(true)
-
- await expect(
- hardhatProxyRegister.connect(addr1).deleteRecordByProxy(1,)
- ).to.be.revertedWith("Proxy entry does not exist")
-
- const registerEntry2 = await hardhatProxyRegister.connect(addr1).getNominatorRecordForCaller()
- expect(registerEntry2[0]).to.equal(addr1.address)
- expect(registerEntry2[1]).to.equal(addr2.address)
- expect(registerEntry2[2]).to.equal(addr3.address)
-
- const proxyEntryExists4 = await hardhatProxyRegister.connect(addr1).nominatorRecordExistsForCaller()
- expect(proxyEntryExists4).to.equal(true)
-
- const proxyEntryExists5 = await hardhatProxyRegister.connect(addr2).proxyRecordExistsForCaller()
- expect(proxyEntryExists5).to.equal(true)
- })
- })
- });
-
- context("Getter Functions", function () {
-
- describe("Fee and Treasury", function () {
- it("getRegisterFee", async () => {
- const fee = await hardhatProxyRegister.getRegisterFee()
- expect(fee).to.equal(ethers.utils.parseEther(registerFee.toString()));
- })
-
- it("getTreasuryAddress", async () => {
- const treasuryAddress = await hardhatProxyRegister.getTreasuryAddress()
- expect(treasuryAddress).to.equal(treasury.address);
- })
- })
-
- describe("No proxy details saved", function () {
- it("nominationExists", async () => {
- const nominationExists = await hardhatProxyRegister.nominationExists(addr1.address)
- expect(nominationExists).to.equal(false);
- })
-
- it("nominationExistsForCaller", async () => {
- const nominationExists = await hardhatProxyRegister.connect(addr1.address).nominationExistsForCaller()
- expect(nominationExists).to.equal(false);
- })
-
- it("getNomination", async () => {
- const proxy = await hardhatProxyRegister.getNomination(addr1.address)
- expect(proxy).to.equal(ZERO_ADDRESS);
- })
-
- it("getNominationForCaller", async () => {
- const proxy = await hardhatProxyRegister.getNominationForCaller()
- expect(proxy).to.equal(ZERO_ADDRESS);
- })
-
- it("proxyRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.proxyRecordExists(addr2.address)
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("proxyRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr2.address).proxyRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("nominatorRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.nominatorRecordExists(addr1.address)
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("nominatorRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr1.address).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("addressIsActive", async () => {
- const addressIsActive = await hardhatProxyRegister.addressIsActive(addr1.address)
- expect(addressIsActive).to.equal(false);
-
- const addressIsActive2 = await hardhatProxyRegister.addressIsActive(addr2.address)
- expect(addressIsActive2).to.equal(false);
- })
-
- it("addressIsActiveForCaller", async () => {
- const addressIsActive = await hardhatProxyRegister.connect(addr1.address).addressIsActiveForCaller()
- expect(addressIsActive).to.equal(false);
-
- const addressIsActive2 = await hardhatProxyRegister.connect(addr2.address).addressIsActiveForCaller()
- expect(addressIsActive2).to.equal(false);
- })
-
- it("getProxyRecord", async () => {
- const entry = await hardhatProxyRegister.getProxyRecord(addr2.address)
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getProxyRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getProxyRecordForCaller()
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getNominatorRecord", async () => {
- const entry = await hardhatProxyRegister.getNominatorRecord(addr1.address)
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getNominatorRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr1.address).getNominatorRecordForCaller()
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getAddresses", async () => {
- const entry = await hardhatProxyRegister.getAddresses(addr2.address)
- expect(entry[0]).to.equal(addr2.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(false);
- })
-
- it("getAddressesForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getAddressesForCaller()
- expect(entry[0]).to.equal(addr2.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(false);
- })
- })
-
- describe("With Proxy Nomination", function () {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
- })
-
- it("nominationExists", async () => {
- const nominationExists = await hardhatProxyRegister.nominationExists(addr1.address)
- expect(nominationExists).to.equal(true);
- })
-
- it("nominationExistsForCaller", async () => {
- const nominationExists = await hardhatProxyRegister.connect(addr1.address).nominationExistsForCaller()
- expect(nominationExists).to.equal(true);
- })
-
- it("getNomination", async () => {
- const proxy = await hardhatProxyRegister.getNomination(addr1.address)
- expect(proxy).to.equal(addr2.address);
- })
-
- it("getNominationForCaller", async () => {
- const proxy = await hardhatProxyRegister.connect(addr1.address).getNominationForCaller()
- expect(proxy).to.equal(addr2.address);
- })
-
- it("proxyRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.proxyRecordExists(addr2.address)
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("proxyRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr2.address).proxyRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("nominatorRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.nominatorRecordExists(addr1.address)
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("nominatorRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr2.address).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(false);
- })
-
- it("addressIsActive", async () => {
- const addressIsActive = await hardhatProxyRegister.addressIsActive(addr1.address)
- expect(addressIsActive).to.equal(false);
-
- const addressIsActive2 = await hardhatProxyRegister.addressIsActive(addr2.address)
- expect(addressIsActive2).to.equal(false);
- })
-
- it("addressIsActiveForCaller", async () => {
- const addressIsActive = await hardhatProxyRegister.connect(addr1.address).addressIsActiveForCaller()
- expect(addressIsActive).to.equal(false);
-
- const addressIsActive2 = await hardhatProxyRegister.connect(addr2.address).addressIsActiveForCaller()
- expect(addressIsActive2).to.equal(false);
- })
-
- it("getProxyRecord", async () => {
- const entry = await hardhatProxyRegister.getProxyRecord(addr2.address)
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getProxyRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getProxyRecordForCaller()
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getNominatorRecord", async () => {
- const entry = await hardhatProxyRegister.getNominatorRecord(addr1.address)
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getNominatorRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr1.address).getNominatorRecordForCaller()
- expect(entry[0]).to.equal(ZERO_ADDRESS);
- expect(entry[1]).to.equal(ZERO_ADDRESS);
- expect(entry[2]).to.equal(ZERO_ADDRESS);
- })
-
- it("getAddresses", async () => {
- const entry = await hardhatProxyRegister.getAddresses(addr2.address)
- expect(entry[0]).to.equal(addr2.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(false);
- })
-
- it("getAddressesForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getAddressesForCaller()
- expect(entry[0]).to.equal(addr2.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(false);
- })
- })
-
- describe("With Proxy Active", function () {
-
- beforeEach(async function () {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
- })
-
- it("nominationExists", async () => {
- const nominationExists = await hardhatProxyRegister.nominationExists(addr1.address)
- expect(nominationExists).to.equal(true);
- })
-
- it("nominationExistsForCaller", async () => {
- const nominationExists = await hardhatProxyRegister.connect(addr1.address).nominationExistsForCaller()
- expect(nominationExists).to.equal(true);
- })
-
- it("getNomination", async () => {
- const proxy = await hardhatProxyRegister.getNomination(addr1.address)
- expect(proxy).to.equal(addr2.address);
- })
-
- it("getNominationForCaller", async () => {
- const proxy = await hardhatProxyRegister.connect(addr1.address).getNominationForCaller()
- expect(proxy).to.equal(addr2.address);
- })
-
- it("proxyRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.proxyRecordExists(addr2.address)
- expect(proxyRecordExists).to.equal(true);
- })
-
- it("proxyRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr2.address).proxyRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(true);
- })
-
- it("nominatorRecordExists", async () => {
- const proxyRecordExists = await hardhatProxyRegister.nominatorRecordExists(addr1.address)
- expect(proxyRecordExists).to.equal(true);
- })
-
- it("nominatorRecordExistsForCaller", async () => {
- const proxyRecordExists = await hardhatProxyRegister.connect(addr1.address).nominatorRecordExistsForCaller()
- expect(proxyRecordExists).to.equal(true);
- })
-
- it("addressIsActive", async () => {
- const addressIsActive = await hardhatProxyRegister.addressIsActive(addr1.address)
- expect(addressIsActive).to.equal(true);
-
- const addressIsActive2 = await hardhatProxyRegister.addressIsActive(addr2.address)
- expect(addressIsActive2).to.equal(true);
- })
-
- it("addressIsActiveForCaller", async () => {
- const addressIsActive = await hardhatProxyRegister.connect(addr1.address).addressIsActiveForCaller()
- expect(addressIsActive).to.equal(true);
-
- const addressIsActive2 = await hardhatProxyRegister.connect(addr2.address).addressIsActiveForCaller()
- expect(addressIsActive2).to.equal(true);
- })
-
- it("getProxyRecord", async () => {
- const entry = await hardhatProxyRegister.getProxyRecord(addr2.address)
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(addr3.address);
- })
-
- it("getProxyRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getProxyRecordForCaller()
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(addr3.address);
- })
-
- it("getNominatorRecord", async () => {
- const entry = await hardhatProxyRegister.getNominatorRecord(addr1.address)
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(addr3.address);
- })
-
- it("getNominatorRecordForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr1.address).getNominatorRecordForCaller()
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr2.address);
- expect(entry[2]).to.equal(addr3.address);
- })
-
- it("getAddresses", async () => {
- const entry = await hardhatProxyRegister.getAddresses(addr2.address)
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr3.address);
- expect(entry[2]).to.equal(true);
- })
-
- it("getAddressesForCaller", async () => {
- const entry = await hardhatProxyRegister.connect(addr2.address).getAddressesForCaller()
- expect(entry[0]).to.equal(addr1.address);
- expect(entry[1]).to.equal(addr3.address);
- expect(entry[2]).to.equal(true);
- })
-
- it("getAddresses for nominator with valid proxy", async () => {
- const nominationExists = await hardhatProxyRegister.nominationExists(addr1.address)
- expect(nominationExists).to.equal(true);
- await expect(
- hardhatProxyRegister.getAddresses(addr1.address)
- ).to.be.revertedWith("Nominator address cannot interact directly, only through the proxy address")
- })
-
- it("getAddressesForCaller for nominator with valid proxy", async () => {
- await expect(
- hardhatProxyRegister.connect(addr1.address).getAddressesForCaller()
- ).to.be.revertedWith("Nominator address cannot interact directly, only through the proxy address")
- })
- })
-
- describe("Role", function () {
- it("Returns none with no proxy or nomination", async () => {
- var role = await hardhatProxyRegister.getRole(addr1.address)
- expect(role).to.equal("None");
-
- role = await hardhatProxyRegister.connect(addr1.address).getRoleForCaller()
- expect(role).to.equal("None");
- })
-
- it("Returns pending with unaccepted nomination", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var role = await hardhatProxyRegister.getRole(addr1.address)
- expect(role).to.equal("Nominator - Proxy Pending");
-
- role = await hardhatProxyRegister.connect(addr1.address).getRoleForCaller()
- expect(role).to.equal("Nominator - Proxy Pending");
- })
-
- it("Returns active with accepted nomination", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- var role = await hardhatProxyRegister.getRole(addr1.address)
- expect(role).to.equal("Nominator - Proxy Active");
-
- role = await hardhatProxyRegister.connect(addr1.address).getRoleForCaller()
- expect(role).to.equal("Nominator - Proxy Active");
- })
-
- it("Returns proxy with unaccepted nomination", async () => {
- var tx1 = await hardhatProxyRegister
- .connect(addr1)
- .makeNomination( addr2.address, 1, {
- value: ethers.utils.parseEther(registerFee.toString()),
- })
- expect(tx1).to.emit(hardhatProxyRegister, "NominationMade")
-
- var tx2 = await hardhatProxyRegister
- .connect(addr2)
- .acceptNomination( addr1.address, addr3.address, 1)
- expect(tx2).to.emit(hardhatProxyRegister, "NominationAccepted")
-
- var role = await hardhatProxyRegister.getRole(addr2.address)
- expect(role).to.equal("Proxy");
-
- role = await hardhatProxyRegister.connect(addr2.address).getRoleForCaller()
- expect(role).to.equal("Proxy");
- })
- })
-
- });
-})
diff --git a/assets/eip-4907/.gitignore b/assets/eip-4907/.gitignore
deleted file mode 100644
index 504afef..0000000
--- a/assets/eip-4907/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules/
-package-lock.json
diff --git a/assets/eip-4907/README.md b/assets/eip-4907/README.md
deleted file mode 100644
index 720f084..0000000
--- a/assets/eip-4907/README.md
+++ /dev/null
@@ -1,20 +0,0 @@
-# EIP-4907
-EIP-4907 is an extension of ERC-721. It proposes an additional role **user** and a valid duration indicator **expires**. It allows users and developers manage the use right more simple and efficient.
-
-### Tools
-* [Visual Studio Code](https://code.visualstudio.com/)
-* [Solidity](https://marketplace.visualstudio.com/items?itemName=JuanBlanco.solidity) - Solidity support for Visual Studio code
-* [Truffle](https://truffleframework.com/) - the most popular development framework for Ethereum
-
-### Install
-```
-npm install
-```
-
-### Test
-```
-truffle test
-```
-
-### Additional Resources
-* [Official Truffle Documentation](http://truffleframework.com/docs/) for complete and detailed guides, tips, and sample code.
\ No newline at end of file
diff --git a/assets/eip-4907/contracts/ERC4907.sol b/assets/eip-4907/contracts/ERC4907.sol
deleted file mode 100644
index 6bc044f..0000000
--- a/assets/eip-4907/contracts/ERC4907.sol
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC4907.sol";
-
-contract ERC4907 is ERC721, IERC4907 {
- struct UserInfo
- {
- address user; // address of user role
- uint64 expires; // unix timestamp, user expires
- }
-
- mapping (uint256 => UserInfo) internal _users;
-
- constructor(string memory name_, string memory symbol_)
- ERC721(name_,symbol_)
- {
- }
-
- /// @notice set the user and expires of a NFT
- /// @dev The zero address indicates there is no user
- /// Throws if `tokenId` is not valid NFT
- /// @param user The new user of the NFT
- /// @param expires UNIX timestamp, The new user could use the NFT before expires
- function setUser(uint256 tokenId, address user, uint64 expires) public virtual{
- require(_isApprovedOrOwner(msg.sender, tokenId),"ERC721: transfer caller is not owner nor approved");
- UserInfo storage info = _users[tokenId];
- info.user = user;
- info.expires = expires;
- emit UpdateUser(tokenId,user,expires);
- }
-
- /// @notice Get the user address of an NFT
- /// @dev The zero address indicates that there is no user or the user is expired
- /// @param tokenId The NFT to get the user address for
- /// @return The user address for this NFT
- function userOf(uint256 tokenId)public view virtual returns(address){
- if( uint256(_users[tokenId].expires) >= block.timestamp){
- return _users[tokenId].user;
- }
- else{
- return address(0);
- }
- }
-
- /// @notice Get the user expires of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user expires for
- /// @return The user expires for this NFT
- function userExpires(uint256 tokenId) public view virtual returns(uint256){
- return _users[tokenId].expires;
- }
-
- /// @dev See {IERC165-supportsInterface}.
- function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- return interfaceId == type(IERC4907).interfaceId || super.supportsInterface(interfaceId);
- }
-
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override{
- super._beforeTokenTransfer(from, to, tokenId);
-
- if (from != to && _users[tokenId].user != address(0)) {
- delete _users[tokenId];
- emit UpdateUser(tokenId, address(0), 0);
- }
- }
-}
diff --git a/assets/eip-4907/contracts/ERC4907Demo.sol b/assets/eip-4907/contracts/ERC4907Demo.sol
deleted file mode 100644
index daa6d99..0000000
--- a/assets/eip-4907/contracts/ERC4907Demo.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./ERC4907.sol";
-
-contract ERC4907Demo is ERC4907 {
-
- constructor(string memory name_, string memory symbol_)
- ERC4907(name_,symbol_)
- {
- }
-
- function mint(uint256 tokenId, address to) public {
- _mint(to, tokenId);
- }
-
-}
diff --git a/assets/eip-4907/contracts/IERC4907.sol b/assets/eip-4907/contracts/IERC4907.sol
deleted file mode 100644
index 9858dfe..0000000
--- a/assets/eip-4907/contracts/IERC4907.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC4907 {
- // Logged when the user of a token assigns a new user or updates expires
- /// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed
- /// The zero address for user indicates that there is no user address
- event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires);
-
- /// @notice set the user and expires of a NFT
- /// @dev The zero address indicates there is no user
- /// Throws if `tokenId` is not valid NFT
- /// @param user The new user of the NFT
- /// @param expires UNIX timestamp, The new user could use the NFT before expires
- function setUser(uint256 tokenId, address user, uint64 expires) external ;
-
- /// @notice Get the user address of an NFT
- /// @dev The zero address indicates that there is no user or the user is expired
- /// @param tokenId The NFT to get the user address for
- /// @return The user address for this NFT
- function userOf(uint256 tokenId) external view returns(address);
-
- /// @notice Get the user expires of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user expires for
- /// @return The user expires for this NFT
- function userExpires(uint256 tokenId) external view returns(uint256);
-}
diff --git a/assets/eip-4907/migrations/1_initial_migration.js b/assets/eip-4907/migrations/1_initial_migration.js
deleted file mode 100644
index 1eb915e..0000000
--- a/assets/eip-4907/migrations/1_initial_migration.js
+++ /dev/null
@@ -1,5 +0,0 @@
-const ERC4907Demo = artifacts.require("ERC4907Demo");
-
-module.exports = function (deployer) {
- deployer.deploy(ERC4907Demo, "ERC4907Demo", "ERC4907Demo");
-};
diff --git a/assets/eip-4907/package.json b/assets/eip-4907/package.json
deleted file mode 100644
index 9104d3d..0000000
--- a/assets/eip-4907/package.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "ERC-4907",
- "version": "1.0.0",
- "description": "",
- "main": "truffle-config.js",
- "directories": {
- "test": "test"
- },
- "scripts": {},
- "keywords": [],
- "author": "",
- "license": "CC0-1.0",
- "dependencies": {
- "@openzeppelin/contracts": "^4.3.3",
- "@types/chai": "^4.3.0",
- "@types/mocha": "^9.1.0",
- "chai": "^4.3.6"
- }
-}
diff --git a/assets/eip-4907/test/test.js b/assets/eip-4907/test/test.js
deleted file mode 100644
index f2df2ed..0000000
--- a/assets/eip-4907/test/test.js
+++ /dev/null
@@ -1,25 +0,0 @@
-const { assert } = require("chai");
-
-const ERC4907Demo = artifacts.require("ERC4907Demo");
-
-contract("test", async (accounts) => {
- it("should set user to Bob", async () => {
- // Get initial balances of first and second account.
- const Alice = accounts[0];
- const Bob = accounts[1];
-
- const instance = await ERC4907Demo.deployed("T", "T");
- const demo = instance;
-
- await demo.mint(1, Alice);
- let expires = Math.floor(new Date().getTime() / 1000) + 1000;
- await demo.setUser(1, Bob, BigInt(expires));
-
- let user_1 = await demo.userOf(1);
-
- assert.equal(user_1, Bob, "User of NFT 1 should be Bob");
-
- let owner_1 = await demo.ownerOf(1);
- assert.equal(owner_1, Alice, "Owner of NFT 1 should be Alice");
- });
-});
diff --git a/assets/eip-4907/truffle-config.js b/assets/eip-4907/truffle-config.js
deleted file mode 100644
index 3517e05..0000000
--- a/assets/eip-4907/truffle-config.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * Use this file to configure your truffle project. It's seeded with some
- * common settings for different networks and features like migrations,
- * compilation and testing. Uncomment the ones you need or modify
- * them to suit your project as necessary.
- *
- * More information about configuration can be found at:
- *
- * trufflesuite.com/docs/advanced/configuration
- *
- * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
- * to sign your transactions before they're sent to a remote public node. Infura accounts
- * are available for free at: infura.io/register.
- *
- * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
- * public/private key pairs. If you're publishing your code to GitHub make sure you load this
- * phrase from a file you've .gitignored so it doesn't accidentally become public.
- *
- */
-
-// const HDWalletProvider = require('@truffle/hdwallet-provider');
-//
-// const fs = require('fs');
-// const mnemonic = fs.readFileSync(".secret").toString().trim();
-
-module.exports = {
- /**
- * Networks define how you connect to your ethereum client and let you set the
- * defaults web3 uses to send transactions. If you don't specify one truffle
- * will spin up a development blockchain for you on port 9545 when you
- * run `develop` or `test`. You can ask a truffle command to use a specific
- * network from the command line, e.g
- *
- * $ truffle test --network
- */
-
- networks: {
- // Useful for testing. The `development` name is special - truffle uses it by default
- // if it's defined here and no other network is specified at the command line.
- // You should run a client (like ganache-cli, geth or parity) in a separate terminal
- // tab if you use this network and you must also set the `host`, `port` and `network_id`
- // options below to some value.
- //
- // development: {
- // host: "127.0.0.1", // Localhost (default: none)
- // port: 8545, // Standard Ethereum port (default: none)
- // network_id: "*", // Any network (default: none)
- // },
- // Another network with more advanced options...
- // advanced: {
- // port: 8777, // Custom port
- // network_id: 1342, // Custom network
- // gas: 8500000, // Gas sent with each transaction (default: ~6700000)
- // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
- // from: , // Account to send txs from (default: accounts[0])
- // websocket: true // Enable EventEmitter interface for web3 (default: false)
- // },
- // Useful for deploying to a public network.
- // NB: It's important to wrap the provider as a function.
- // ropsten: {
- // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
- // network_id: 3, // Ropsten's id
- // gas: 5500000, // Ropsten has a lower block limit than mainnet
- // confirmations: 2, // # of confs to wait between deployments. (default: 0)
- // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
- // skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
- // },
- // Useful for private networks
- // private: {
- // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
- // network_id: 2111, // This network is yours, in the cloud.
- // production: true // Treats this network as if it was a public net. (default: false)
- // }
- },
-
- // Set default mocha options here, use special reporters etc.
- mocha: {
- // timeout: 100000
- },
-
- // Configure your compilers
- compilers: {
- solc: {
- version: "0.8.10", // Fetch exact version from solc-bin (default: truffle's version)
- // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
- settings: {
- // See the solidity docs for advice about optimization and evmVersion
- optimizer: {
- enabled: false,
- runs: 200,
- },
- // ,
- // evmVersion: "byzantium"
- // }
- },
- },
-
- // Truffle DB is currently disabled by default; to enable it, change enabled:
- // false to enabled: true. The default storage location can also be
- // overridden by specifying the adapter settings, as shown in the commented code below.
- //
- // NOTE: It is not possible to migrate your contracts to truffle DB and you should
- // make a backup of your artifacts to a safe location before enabling this feature.
- //
- // After you backed up your artifacts you can utilize db by running migrate as follows:
- // $ truffle migrate --reset --compile-all
- //
- // db: {
- // enabled: false,
- // host: "127.0.0.1",
- // adapter: {
- // name: "sqlite",
- // settings: {
- // directory: ".db"
- // }
- // }
- },
-};
diff --git a/assets/eip-4910/eip-4910-print-families.png b/assets/eip-4910/eip-4910-print-families.png
deleted file mode 100644
index 30815ee..0000000
Binary files a/assets/eip-4910/eip-4910-print-families.png and /dev/null differ
diff --git a/assets/eip-4910/eip-4910-royalties.png b/assets/eip-4910/eip-4910-royalties.png
deleted file mode 100644
index ddf6951..0000000
Binary files a/assets/eip-4910/eip-4910-royalties.png and /dev/null differ
diff --git a/assets/eip-4955/different-renders.jpeg b/assets/eip-4955/different-renders.jpeg
deleted file mode 100644
index 6a36d11..0000000
Binary files a/assets/eip-4955/different-renders.jpeg and /dev/null differ
diff --git a/assets/eip-4973/ERC4973-flat.sol b/assets/eip-4973/ERC4973-flat.sol
deleted file mode 100644
index e20aa82..0000000
--- a/assets/eip-4973/ERC4973-flat.sol
+++ /dev/null
@@ -1,1028 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.8;
-
-// OpenZeppelin Contracts (last updated v4.7.1) (utils/cryptography/SignatureChecker.sol)
-
-// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)
-
-// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)
-
-/**
- * @dev String operations.
- */
-library Strings {
- bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
- uint8 private constant _ADDRESS_LENGTH = 20;
-
- /**
- * @dev Converts a `uint256` to its ASCII `string` decimal representation.
- */
- function toString(uint256 value) internal pure returns (string memory) {
- // Inspired by OraclizeAPI's implementation - MIT licence
- // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
-
- if (value == 0) {
- return "0";
- }
- uint256 temp = value;
- uint256 digits;
- while (temp != 0) {
- digits++;
- temp /= 10;
- }
- bytes memory buffer = new bytes(digits);
- while (value != 0) {
- digits -= 1;
- buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
- value /= 10;
- }
- return string(buffer);
- }
-
- /**
- * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
- */
- function toHexString(uint256 value) internal pure returns (string memory) {
- if (value == 0) {
- return "0x00";
- }
- uint256 temp = value;
- uint256 length = 0;
- while (temp != 0) {
- length++;
- temp >>= 8;
- }
- return toHexString(value, length);
- }
-
- /**
- * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
- */
- function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
- bytes memory buffer = new bytes(2 * length + 2);
- buffer[0] = "0";
- buffer[1] = "x";
- for (uint256 i = 2 * length + 1; i > 1; --i) {
- buffer[i] = _HEX_SYMBOLS[value & 0xf];
- value >>= 4;
- }
- require(value == 0, "Strings: hex length insufficient");
- return string(buffer);
- }
-
- /**
- * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
- */
- function toHexString(address addr) internal pure returns (string memory) {
- return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
- }
-}
-
-/**
- * @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,
- InvalidSignatureV
- }
-
- function _throwError(RecoverError error) private pure {
- if (error == RecoverError.NoError) {
- return; // no error: do nothing
- } else if (error == RecoverError.InvalidSignature) {
- revert("ECDSA: invalid signature");
- } else if (error == RecoverError.InvalidSignatureLength) {
- revert("ECDSA: invalid signature length");
- } else if (error == RecoverError.InvalidSignatureS) {
- revert("ECDSA: invalid signature 's' value");
- } else if (error == RecoverError.InvalidSignatureV) {
- revert("ECDSA: invalid signature 'v' value");
- }
- }
-
- /**
- * @dev Returns the address that signed a hashed message (`hash`) with
- * `signature` or error string. This address can then be used for verification purposes.
- *
- * The `ecrecover` EVM opcode 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 {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]
- *
- * _Available since v4.3._
- */
- function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
- 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);
- }
- }
-
- /**
- * @dev Returns the address that signed a hashed message (`hash`) with
- * `signature`. This address can then be used for verification purposes.
- *
- * The `ecrecover` EVM opcode 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 {toEthSignedMessageHash} on it.
- */
- function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
- (address recovered, RecoverError error) = tryRecover(hash, signature);
- _throwError(error);
- 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]
- *
- * _Available since v4.3._
- */
- function tryRecover(
- bytes32 hash,
- bytes32 r,
- bytes32 vs
- ) internal pure returns (address, RecoverError) {
- bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
- 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.
- *
- * _Available since v4.2._
- */
- function recover(
- bytes32 hash,
- bytes32 r,
- bytes32 vs
- ) internal pure returns (address) {
- (address recovered, RecoverError error) = tryRecover(hash, r, vs);
- _throwError(error);
- return recovered;
- }
-
- /**
- * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
- * `r` and `s` signature fields separately.
- *
- * _Available since v4.3._
- */
- function tryRecover(
- bytes32 hash,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) internal pure returns (address, RecoverError) {
- // 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);
- }
- if (v != 27 && v != 28) {
- return (address(0), RecoverError.InvalidSignatureV);
- }
-
- // 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);
- }
-
- return (signer, RecoverError.NoError);
- }
-
- /**
- * @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) = tryRecover(hash, v, r, s);
- _throwError(error);
- return recovered;
- }
-
- /**
- * @dev Returns an Ethereum Signed Message, created from a `hash`. This
- * produces hash corresponding to the one signed with the
- * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
- * JSON-RPC method as part of EIP-191.
- *
- * See {recover}.
- */
- function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
- // 32 is the length in bytes of hash,
- // enforced by the type signature above
- return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
- }
-
- /**
- * @dev Returns an Ethereum Signed Message, created from `s`. This
- * produces hash corresponding to the one signed with the
- * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
- * JSON-RPC method as part of EIP-191.
- *
- * See {recover}.
- */
- function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
- return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
- }
-
- /**
- * @dev Returns an Ethereum Signed Typed Data, created from a
- * `domainSeparator` and a `structHash`. This produces hash corresponding
- * to the one signed with the
- * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
- * JSON-RPC method as part of EIP-712.
- *
- * See {recover}.
- */
- function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
- return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
- }
-}
-
-// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)
-
-/**
- * @dev Collection of functions related to the address type
- */
-library Address {
- /**
- * @dev Returns true if `account` is a contract.
- *
- * [IMPORTANT]
- * ====
- * It is unsafe to assume that an address for which this function returns
- * false is an externally-owned account (EOA) and not a contract.
- *
- * Among others, `isContract` will return false for the following
- * types of addresses:
- *
- * - an externally-owned account
- * - a contract in construction
- * - an address where a contract will be created
- * - an address where a contract lived, but was destroyed
- * ====
- *
- * [IMPORTANT]
- * ====
- * You shouldn't rely on `isContract` to protect against flash loan attacks!
- *
- * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
- * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
- * constructor.
- * ====
- */
- function isContract(address account) internal view returns (bool) {
- // This method relies on extcodesize/address.code.length, which returns 0
- // for contracts in construction, since the code is only stored at the end
- // of the constructor execution.
-
- return account.code.length > 0;
- }
-
- /**
- * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
- * `recipient`, forwarding all available gas and reverting on errors.
- *
- * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
- * of certain opcodes, possibly making contracts go over the 2300 gas limit
- * imposed by `transfer`, making them unable to receive funds via
- * `transfer`. {sendValue} removes this limitation.
- *
- * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
- *
- * IMPORTANT: because control is transferred to `recipient`, care must be
- * taken to not create reentrancy vulnerabilities. Consider using
- * {ReentrancyGuard} or the
- * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
- */
- function sendValue(address payable recipient, uint256 amount) internal {
- require(address(this).balance >= amount, "Address: insufficient balance");
-
- (bool success, ) = recipient.call{value: amount}("");
- require(success, "Address: unable to send value, recipient may have reverted");
- }
-
- /**
- * @dev Performs a Solidity function call using a low level `call`. A
- * plain `call` is an unsafe replacement for a function call: use this
- * function instead.
- *
- * If `target` reverts with a revert reason, it is bubbled up by this
- * function (like regular Solidity function calls).
- *
- * Returns the raw returned data. To convert to the expected return value,
- * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
- *
- * Requirements:
- *
- * - `target` must be a contract.
- * - calling `target` with `data` must not revert.
- *
- * _Available since v3.1._
- */
- function functionCall(address target, bytes memory data) internal returns (bytes memory) {
- return functionCall(target, data, "Address: low-level call failed");
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
- * `errorMessage` as a fallback revert reason when `target` reverts.
- *
- * _Available since v3.1._
- */
- function functionCall(
- address target,
- bytes memory data,
- string memory errorMessage
- ) internal returns (bytes memory) {
- return functionCallWithValue(target, data, 0, errorMessage);
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
- * but also transferring `value` wei to `target`.
- *
- * Requirements:
- *
- * - the calling contract must have an ETH balance of at least `value`.
- * - the called Solidity function must be `payable`.
- *
- * _Available since v3.1._
- */
- function functionCallWithValue(
- address target,
- bytes memory data,
- uint256 value
- ) internal returns (bytes memory) {
- return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
- }
-
- /**
- * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
- * with `errorMessage` as a fallback revert reason when `target` reverts.
- *
- * _Available since v3.1._
- */
- function functionCallWithValue(
- address target,
- bytes memory data,
- uint256 value,
- string memory errorMessage
- ) internal returns (bytes memory) {
- require(address(this).balance >= value, "Address: insufficient balance for call");
- require(isContract(target), "Address: call to non-contract");
-
- (bool success, bytes memory returndata) = target.call{value: value}(data);
- return verifyCallResult(success, returndata, errorMessage);
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
- * but performing a static call.
- *
- * _Available since v3.3._
- */
- function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
- return functionStaticCall(target, data, "Address: low-level static call failed");
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
- * but performing a static call.
- *
- * _Available since v3.3._
- */
- function functionStaticCall(
- address target,
- bytes memory data,
- string memory errorMessage
- ) internal view returns (bytes memory) {
- require(isContract(target), "Address: static call to non-contract");
-
- (bool success, bytes memory returndata) = target.staticcall(data);
- return verifyCallResult(success, returndata, errorMessage);
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
- * but performing a delegate call.
- *
- * _Available since v3.4._
- */
- function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
- return functionDelegateCall(target, data, "Address: low-level delegate call failed");
- }
-
- /**
- * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
- * but performing a delegate call.
- *
- * _Available since v3.4._
- */
- function functionDelegateCall(
- address target,
- bytes memory data,
- string memory errorMessage
- ) internal returns (bytes memory) {
- require(isContract(target), "Address: delegate call to non-contract");
-
- (bool success, bytes memory returndata) = target.delegatecall(data);
- return verifyCallResult(success, returndata, errorMessage);
- }
-
- /**
- * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
- * revert reason using the provided one.
- *
- * _Available since v4.3._
- */
- function verifyCallResult(
- bool success,
- bytes memory returndata,
- string memory errorMessage
- ) internal pure returns (bytes memory) {
- if (success) {
- return returndata;
- } else {
- // Look for revert reason and bubble it up if present
- if (returndata.length > 0) {
- // The easiest way to bubble the revert reason is using memory via assembly
- /// @solidity memory-safe-assembly
- assembly {
- let returndata_size := mload(returndata)
- revert(add(32, returndata), returndata_size)
- }
- } else {
- revert(errorMessage);
- }
- }
- }
-}
-
-// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
-
-/**
- * @dev Interface of the ERC1271 standard signature validation method for
- * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
- *
- * _Available since v4.1._
- */
-interface IERC1271 {
- /**
- * @dev Should return whether the signature provided is valid for the provided data
- * @param hash Hash of the data to be signed
- * @param signature Signature byte array associated with _data
- */
- function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
-}
-
-/**
- * @dev Signature verification helper that can be used instead of `ECDSA.recover` to seamlessly support both ECDSA
- * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets like
- * Argent and Gnosis Safe.
- *
- * _Available since v4.1._
- */
-library SignatureChecker {
- /**
- * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the
- * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECDSA.recover`.
- *
- * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus
- * change through time. It could return true at block N and false at block N+1 (or the opposite).
- */
- function isValidSignatureNow(
- address signer,
- bytes32 hash,
- bytes memory signature
- ) internal view returns (bool) {
- (address recovered, ECDSA.RecoverError error) = ECDSA.tryRecover(hash, signature);
- if (error == ECDSA.RecoverError.NoError && recovered == signer) {
- return true;
- }
-
- (bool success, bytes memory result) = signer.staticcall(
- abi.encodeWithSelector(IERC1271.isValidSignature.selector, hash, signature)
- );
- return (success &&
- result.length == 32 &&
- abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector));
- }
-}
-
-// OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol)
-
-/**
- * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
- *
- * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
- * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
- * they need in their contracts using a combination of `abi.encode` and `keccak256`.
- *
- * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
- * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
- * ({_hashTypedDataV4}).
- *
- * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
- * the chain id to protect against replay attacks on an eventual fork of the chain.
- *
- * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
- * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
- *
- * _Available since v3.4._
- */
-abstract contract EIP712 {
- /* solhint-disable var-name-mixedcase */
- // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
- // invalidate the cached domain separator if the chain id changes.
- bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
- uint256 private immutable _CACHED_CHAIN_ID;
- address private immutable _CACHED_THIS;
-
- bytes32 private immutable _HASHED_NAME;
- bytes32 private immutable _HASHED_VERSION;
- bytes32 private immutable _TYPE_HASH;
-
- /* solhint-enable var-name-mixedcase */
-
- /**
- * @dev Initializes the domain separator and parameter caches.
- *
- * The meaning of `name` and `version` is specified in
- * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
- *
- * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
- * - `version`: the current major version of the signing domain.
- *
- * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
- * contract upgrade].
- */
- constructor(string memory name, string memory version) {
- bytes32 hashedName = keccak256(bytes(name));
- bytes32 hashedVersion = keccak256(bytes(version));
- bytes32 typeHash = keccak256(
- "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
- );
- _HASHED_NAME = hashedName;
- _HASHED_VERSION = hashedVersion;
- _CACHED_CHAIN_ID = block.chainid;
- _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
- _CACHED_THIS = address(this);
- _TYPE_HASH = typeHash;
- }
-
- /**
- * @dev Returns the domain separator for the current chain.
- */
- function _domainSeparatorV4() internal view returns (bytes32) {
- if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) {
- return _CACHED_DOMAIN_SEPARATOR;
- } else {
- return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
- }
- }
-
- function _buildDomainSeparator(
- bytes32 typeHash,
- bytes32 nameHash,
- bytes32 versionHash
- ) private view returns (bytes32) {
- return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));
- }
-
- /**
- * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
- * function returns the hash of the fully encoded EIP712 message for this domain.
- *
- * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
- *
- * ```solidity
- * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
- * keccak256("Mail(address to,string contents)"),
- * mailTo,
- * keccak256(bytes(mailContents))
- * )));
- * address signer = ECDSA.recover(digest, signature);
- * ```
- */
- function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
- return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
- }
-}
-
-// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
-
-// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
-
-/**
- * @dev Interface of the ERC165 standard, as defined in the
- * https://eips.ethereum.org/EIPS/eip-165[EIP].
- *
- * Implementers can declare support of contract interfaces, which can then be
- * queried by others ({ERC165Checker}).
- *
- * For an implementation, see {ERC165}.
- */
-interface IERC165 {
- /**
- * @dev Returns true if this contract implements the interface defined by
- * `interfaceId`. See the corresponding
- * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
- * to learn more about how these ids are created.
- *
- * This function call must use less than 30 000 gas.
- */
- function supportsInterface(bytes4 interfaceId) external view returns (bool);
-}
-
-/**
- * @dev Implementation of the {IERC165} interface.
- *
- * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
- * for the additional interface id that will be supported. For example:
- *
- * ```solidity
- * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
- * }
- * ```
- *
- * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
- */
-abstract contract ERC165 is IERC165 {
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- return interfaceId == type(IERC165).interfaceId;
- }
-}
-
-// OpenZeppelin Contracts v4.4.1 (utils/structs/BitMaps.sol)
-
-/**
- * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential.
- * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor].
- */
-library BitMaps {
- struct BitMap {
- mapping(uint256 => uint256) _data;
- }
-
- /**
- * @dev Returns whether the bit at `index` is set.
- */
- function get(BitMap storage bitmap, uint256 index) internal view returns (bool) {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- return bitmap._data[bucket] & mask != 0;
- }
-
- /**
- * @dev Sets the bit at `index` to the boolean `value`.
- */
- function setTo(
- BitMap storage bitmap,
- uint256 index,
- bool value
- ) internal {
- if (value) {
- set(bitmap, index);
- } else {
- unset(bitmap, index);
- }
- }
-
- /**
- * @dev Sets the bit at `index`.
- */
- function set(BitMap storage bitmap, uint256 index) internal {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- bitmap._data[bucket] |= mask;
- }
-
- /**
- * @dev Unsets the bit at `index`.
- */
- function unset(BitMap storage bitmap, uint256 index) internal {
- uint256 bucket = index >> 8;
- uint256 mask = 1 << (index & 0xff);
- bitmap._data[bucket] &= ~mask;
- }
-}
-
-interface IERC721Metadata {
- function name() external view returns (string memory);
- function symbol() external view returns (string memory);
- function tokenURI(uint256 tokenId) external view returns (string memory);
-}
-
-/// @title Account-bound tokens
-/// @dev See https://eips.ethereum.org/EIPS/eip-4973
-/// Note: the ERC-165 identifier for this interface is 0xeb72bb7c
-interface IERC4973 {
- /// @dev This emits when ownership of any ABT changes by any mechanism.
- /// This event emits when ABTs are given or equipped and unequipped
- /// (`to` == 0).
- event Transfer(
- address indexed from, address indexed to, uint256 indexed tokenId
- );
- /// @notice Count all ABTs assigned to an owner
- /// @dev ABTs assigned to the zero address are considered invalid, and this
- /// function throws for queries about the zero address.
- /// @param owner An address for whom to query the balance
- /// @return The number of ABTs owned by `address owner`, possibly zero
-
- function balanceOf(address owner) external view returns (uint256);
- /// @notice Find the address bound to an ERC4973 account-bound token
- /// @dev ABTs assigned to zero address are considered invalid, and queries
- /// about them do throw.
- /// @param tokenId The identifier for an ABT.
- /// @return The address of the owner bound to the ABT.
- function ownerOf(uint256 tokenId) external view returns (address);
- /// @notice Removes the `uint256 tokenId` from an account. At any time, an
- /// ABT receiver must be able to disassociate themselves from an ABT
- /// publicly through calling this function. After successfully executing this
- /// function, given the parameters for calling `function give` or
- /// `function take` a token must be re-equipable.
- /// @dev Must emit a `event Transfer` with the `address to` field pointing to
- /// the zero address.
- /// @param tokenId The identifier for an ABT.
- function unequip(uint256 tokenId) external;
- /// @notice Creates and transfers the ownership of an ABT from the
- /// transaction's `msg.sender` to `address to`.
- /// @dev Throws unless `bytes signature` represents a signature of the
- // EIP-712 structured data hash
- /// `Agreement(address active,address passive,bytes metadata)` expressing
- /// `address to`'s explicit agreement to be publicly associated with
- /// `msg.sender` and `bytes metadata`. A unique `uint256 tokenId` must be
- /// generated by type-casting the `bytes32` EIP-712 structured data hash to a
- /// `uint256`. If `bytes signature` is empty or `address to` is a contract,
- /// an EIP-1271-compatible call to `function isValidSignatureNow(...)` must
- /// be made to `address to`. A successful execution must result in the
- /// `event Transfer(msg.sender, to, tokenId)`. Once an ABT exists as an
- /// `uint256 tokenId` in the contract, `function give(...)` must throw.
- /// @param to The receiver of the ABT.
- /// @param metadata The metadata that will be associated to the ABT.
- /// @param signature A signature of the EIP-712 structured data hash
- /// `Agreement(address active,address passive,bytes metadata)` signed by
- /// `address to`.
- /// @return A unique `uint256 tokenId` generated by type-casting the `bytes32`
- /// EIP-712 structured data hash to a `uint256`.
- function give(address to, bytes calldata metadata, bytes calldata signature)
- external
- returns (uint256);
- /// @notice Creates and transfers the ownership of an ABT from an
- /// `address from` to the transaction's `msg.sender`.
- /// @dev Throws unless `bytes signature` represents a signature of the
- /// EIP-712 structured data hash
- /// `Agreement(address active,address passive,bytes metadata)` expressing
- /// `address from`'s explicit agreement to be publicly associated with
- /// `msg.sender` and `bytes metadata`. A unique `uint256 tokenId` must be
- /// generated by type-casting the `bytes32` EIP-712 structured data hash to a
- /// `uint256`. If `bytes signature` is empty or `address from` is a contract,
- /// an EIP-1271-compatible call to `function isValidSignatureNow(...)` must
- /// be made to `address from`. A successful execution must result in the
- /// emission of an `event Transfer(from, msg.sender, tokenId)`. Once an ABT
- /// exists as an `uint256 tokenId` in the contract, `function take(...)` must
- /// throw.
- /// @param from The origin of the ABT.
- /// @param metadata The metadata that will be associated to the ABT.
- /// @param signature A signature of the EIP-712 structured data hash
- /// `Agreement(address active,address passive,bytes metadata)` signed by
- /// `address from`.
- /// @return A unique `uint256 tokenId` generated by type-casting the `bytes32`
- /// EIP-712 structured data hash to a `uint256`.
- function take(address from, bytes calldata metadata, bytes calldata signature)
- external
- returns (uint256);
- /// @notice Decodes the opaque metadata bytestring of an ABT into the token
- /// URI that will be associated with it once it is created on chain.
- /// @param metadata The metadata that will be associated to an ABT.
- /// @return A URI that represents the metadata.
- function decodeURI(bytes calldata metadata) external returns (string memory);
-}
-
-bytes32 constant AGREEMENT_HASH =
- keccak256("Agreement(address active,address passive,bytes metadata)");
-
-/// @notice Reference implementation of EIP-4973 tokens.
-/// @author Tim Daubenschütz, Rahul Rumalla (https://github.com/rugpullindex/ERC4973/blob/master/src/ERC4973.sol)
-abstract contract ERC4973 is EIP712, ERC165, IERC721Metadata, IERC4973 {
- using BitMaps for BitMaps.BitMap;
-
- BitMaps.BitMap private _usedHashes;
-
- string private _name;
- string private _symbol;
-
- mapping(uint256 => address) private _owners;
- mapping(uint256 => string) private _tokenURIs;
- mapping(address => uint256) private _balances;
-
- constructor(string memory name_, string memory symbol_, string memory version)
- EIP712(name_, version)
- {
- _name = name_;
- _symbol = symbol_;
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return interfaceId == type(IERC721Metadata).interfaceId
- || interfaceId == type(IERC4973).interfaceId
- || super.supportsInterface(interfaceId);
- }
-
- function name() public view virtual override returns (string memory) {
- return _name;
- }
-
- function symbol() public view virtual override returns (string memory) {
- return _symbol;
- }
-
- function tokenURI(uint256 tokenId)
- public
- view
- virtual
- override
- returns (string memory)
- {
- require(_exists(tokenId), "tokenURI: token doesn't exist");
- return _tokenURIs[tokenId];
- }
-
- function unequip(uint256 tokenId) public virtual override {
- require(msg.sender == ownerOf(tokenId), "unequip: sender must be owner");
- _usedHashes.unset(tokenId);
- _burn(tokenId);
- }
-
- function balanceOf(address owner)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(owner != address(0), "balanceOf: address zero is not a valid owner");
- return _balances[owner];
- }
-
- function ownerOf(uint256 tokenId) public view virtual returns (address) {
- address owner = _owners[tokenId];
- require(owner != address(0), "ownerOf: token doesn't exist");
- return owner;
- }
-
- function give(address to, bytes calldata metadata, bytes calldata signature)
- external
- virtual
- returns (uint256)
- {
- require(msg.sender != to, "give: cannot give from self");
- uint256 tokenId = _safeCheckAgreement(msg.sender, to, metadata, signature);
- string memory uri = decodeURI(metadata);
- _mint(msg.sender, to, tokenId, uri);
- _usedHashes.set(tokenId);
- return tokenId;
- }
-
- function take(address from, bytes calldata metadata, bytes calldata signature)
- external
- virtual
- returns (uint256)
- {
- require(msg.sender != from, "take: cannot take from self");
- uint256 tokenId = _safeCheckAgreement(msg.sender, from, metadata, signature);
- string memory uri = decodeURI(metadata);
- _mint(from, msg.sender, tokenId, uri);
- _usedHashes.set(tokenId);
- return tokenId;
- }
-
- function decodeURI(bytes calldata metadata)
- public
- virtual
- returns (string memory)
- {
- return string(metadata);
- }
-
- function _safeCheckAgreement(
- address active,
- address passive,
- bytes calldata metadata,
- bytes calldata signature
- )
- internal
- virtual
- returns (uint256)
- {
- bytes32 hash = _getHash(active, passive, metadata);
- uint256 tokenId = uint256(hash);
-
- require(
- SignatureChecker.isValidSignatureNow(passive, hash, signature),
- "_safeCheckAgreement: invalid signature"
- );
- require(!_usedHashes.get(tokenId), "_safeCheckAgreement: already used");
- return tokenId;
- }
-
- function _getHash(address active, address passive, bytes calldata metadata)
- internal
- view
- returns (bytes32)
- {
- bytes32 structHash =
- keccak256(abi.encode(AGREEMENT_HASH, active, passive, keccak256(metadata)));
- return _hashTypedDataV4(structHash);
- }
-
- function _exists(uint256 tokenId) internal view virtual returns (bool) {
- return _owners[tokenId] != address(0);
- }
-
- function _mint(address from, address to, uint256 tokenId, string memory uri)
- internal
- virtual
- returns (uint256)
- {
- require(!_exists(tokenId), "mint: tokenID exists");
- _balances[to] += 1;
- _owners[tokenId] = to;
- _tokenURIs[tokenId] = uri;
- emit Transfer(from, to, tokenId);
- return tokenId;
- }
-
- function _burn(uint256 tokenId) internal virtual {
- address owner = ownerOf(tokenId);
-
- _balances[owner] -= 1;
- delete _owners[tokenId];
- delete _tokenURIs[tokenId];
-
- emit Transfer(owner, address(0), tokenId);
- }
-}
-
diff --git a/assets/eip-4973/package.json b/assets/eip-4973/package.json
deleted file mode 100644
index 496d41a..0000000
--- a/assets/eip-4973/package.json
+++ /dev/null
@@ -1,45 +0,0 @@
-{
- "name": "erc4973",
- "version": "0.4.0",
- "description": "A standard interface for non-transferrable non-fungible tokens, also known as \"account-bound\" or \"soulbound tokens\" or \"badges\".",
- "files": [
- "/src/ERC4973.sol",
- "/src/ERC165.sol",
- "/src/interfaces/IERC165.sol",
- "/src/interfaces/IERC4973.sol",
- "/src/interfaces/IERC721Metadata.sol",
- "/sdk/src/index.mjs"
- ],
- "scripts": {
- "test": "forge test",
- "test:sdk": "ava sdk/test",
- "gen:flatfile": "forge flatten src/ERC4973.sol > ./assets/ERC4973-flat.sol",
- "gen:sdk": "cp package.json assets/package.json && cp -r sdk/ assets/sdk",
- "gen:assets": "npm run gen:flatfile && npm run gen:sdk"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/rugpullindex/ERC4973.git"
- },
- "keywords": [
- "account-bound",
- "soulbound",
- "tokens",
- "ethereum",
- "eip",
- "badges",
- "non-transferrable"
- ],
- "author": "Tim Daubenschütz (https://timdaub.github.io/)",
- "license": "CC0-1.0",
- "bugs": {
- "url": "https://github.com/rugpullindex/ERC4973/issues"
- },
- "homepage": "https://github.com/rugpullindex/ERC4973#readme",
- "dependencies": {
- "ethers": "5.7.2"
- },
- "devDependencies": {
- "ava": "4.3.1"
- }
-}
diff --git a/assets/eip-4973/sdk/src/index.mjs b/assets/eip-4973/sdk/src/index.mjs
deleted file mode 100644
index dc94ae3..0000000
--- a/assets/eip-4973/sdk/src/index.mjs
+++ /dev/null
@@ -1,9 +0,0 @@
-import { utils } from "ethers";
-
-// See: https://docs.ethers.io/v5/api/signer/#Signer-signTypedData for more
-// detailed instructions.
-export async function generateSignature(signer, types, domain, agreement) {
- const signature = await signer._signTypedData(domain, types, agreement);
- const { r, s, v } = utils.splitSignature(signature);
- return utils.solidityPack(["bytes32", "bytes32", "uint8"], [r, s, v]);
-}
diff --git a/assets/eip-4973/sdk/test/index_test.mjs b/assets/eip-4973/sdk/test/index_test.mjs
deleted file mode 100644
index 2adf1fc..0000000
--- a/assets/eip-4973/sdk/test/index_test.mjs
+++ /dev/null
@@ -1,43 +0,0 @@
-// @format
-import test from "ava";
-
-import { Wallet, utils } from "ethers";
-
-import { generateSignature } from "../src/index.mjs";
-
-test("generating a compact signature for function give", async (t) => {
- // from: https://docs.ethers.io/v5/api/signer/#Wallet--methods
- const passiveAddress = "0x0f6A79A579658E401E0B81c6dde1F2cd51d97176";
- const passivePrivateKey =
- "0xad54bdeade5537fb0a553190159783e45d02d316a992db05cbed606d3ca36b39";
- const signer = new Wallet(passivePrivateKey);
- t.is(signer.address, passiveAddress);
-
- const types = {
- Agreement: [
- { name: "active", type: "address" },
- { name: "passive", type: "address" },
- { name: "metadata", type: "bytes" },
- ],
- };
- const domain = {
- name: "Name",
- version: "Version",
- chainId: 31337, // the chainId of foundry
- verifyingContract: "0xce71065d4017f316ec606fe4422e11eb2c47c246",
- };
-
- const agreement = {
- active: "0xb4c79dab8f259c7aee6e5b2aa729821864227e84",
- passive: passiveAddress,
- metadata: utils.toUtf8Bytes("https://example.com/metadata.json"),
- };
-
- const signature = await generateSignature(signer, types, domain, agreement);
- t.truthy(signature);
- t.is(signature.length, 64 + 64 + 2 + 2);
- t.is(
- signature,
- "0x4473afdec84287f10aa0b5eb608d360e2e9220bee657a4a5ca468e69a4de255c38691fca0c52f295d1831beaa0b7f079c1ab7959257578d2fb8d98740d9b0e111c"
- );
-});
diff --git a/assets/eip-4974/ERC4974.sol b/assets/eip-4974/ERC4974.sol
deleted file mode 100644
index 2619a2e..0000000
--- a/assets/eip-4974/ERC4974.sol
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-import "./IERC4974.sol";
-
-/**
- * See {IERC4974}
- * Implements the ERC4974 Metadata extension.
- */
-contract LoyaltyPoints is IERC4974 {
-
- // The address of the operator that can assign ratings
- address private _operator;
-
- // Mapping of customer addresses to their ratings
- mapping (bytes32 => int8) private _ratings;
-
- // Initializes the contract by setting the operator to msg.sender
- constructor () {
- _operator = msg.sender;
- }
-
- // Set the operator address
- // Only the current operator or the contract owner can call this function
- function setOperator(address newOperator) public override {
- require(_operator == msg.sender || msg.sender == address(this), "Only the current operator or the contract owner can set the operator.");
- _operator = newOperator;
- emit NewOperator(_operator);
- }
-
- // Rate a customer
- // Only the operator can call this function
- function rate(address customer, int8 rating) public override {
- require(_operator == msg.sender, "Only the operator can assign ratings.");
- bytes32 hash = keccak256(abi.encodePacked(customer));
- _ratings[hash] = rating;
- emit Rating(customer, rating);
- }
-
- // Remove a rating from a customer
- // Only the operator can call this function
- function removeRating(address customer) external override {
- require(_operator == msg.sender, "Only the operator can remove ratings.");
- bytes32 hash = keccak256(abi.encodePacked(customer));
- delete _ratings[hash];
- emit Removal(customer);
- }
-
- // Get the rating for a customer
- function getOperator() public view returns (address) {
- return _operator;
- }
-
- // Check if a customer has been rated
- function hasBeenRated(address customer) public view returns (bool) {
- // Hash the customer address
- bytes32 hash = keccak256(abi.encodePacked(customer));
-
- // Check if the hash exists in the mapping
- return _ratings[hash] != 0;
- }
-
- function ratingOf(address _rated) public view override returns (int8) {
- bytes32 hash = keccak256(abi.encodePacked(_rated));
- // Check if the customer has been rated
- require(hasBeenRated(_rated), "This customer has not been rated yet.");
- // Return the customer's rating
- return _ratings[hash];
- }
-
- // Award ETH to a customer based on their rating
- function awardEth(address payable customer) public payable {
- // Calculate the amount of ETH to award based on the customer's rating
- int8 rating = ratingOf(customer);
- require(rating > 0, "Sorry, this customer has a rating less than 0 and cannot be awarded.");
- uint256 award = uint256(int256(rating));
- // Transfer the ETH to the customer
- require(address(this).balance >= award, "Contract has insufficient balance to award ETH.");
- customer.transfer(award);
- }
-
- receive () external payable {}
-
-}
\ No newline at end of file
diff --git a/assets/eip-4974/IERC4974.sol b/assets/eip-4974/IERC4974.sol
deleted file mode 100644
index 8043c6e..0000000
--- a/assets/eip-4974/IERC4974.sol
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/// @title EIP-4974 Ratings
-/// @dev See https://eips.ethereum.org/EIPS/EIP-4974
-/// Note: the EIP-165 identifier for this interface is #######.
-/// Must initialize contracts with an `operator` address that is not `address(0)`.
-interface IERC4974 /* is ERC165 */ {
-
- /// @dev Emits when operator changes.
- /// MUST emit when `operator` changes by any mechanism.
- /// MUST ONLY emit by `setOperator`.
- event NewOperator(address indexed _operator);
-
- /// @dev Emits when operator issues a rating.
- /// MUST emit when rating is assigned by any mechanism.
- /// MUST ONLY emit by `rate`.
- event Rating(address _rated, int8 _rating);
-
- /// @dev Emits when operator removes a rating.
- /// MUST emit when rating is removed by any mechanism.
- /// MUST ONLY emit by `remove`.
- event Removal(address _removed);
-
- /// @notice Appoint operator authority.
- /// @dev MUST throw unless `msg.sender` is `operator`.
- /// MUST throw if `operator` address is either already current `operator`
- /// or is the zero address.
- /// MUST emit an `Appointment` event.
- /// @param _operator New operator of the smart contract.
- function setOperator(address _operator) external;
-
- /// @notice Rate an address.
- /// MUST emit a Rating event with each successful call.
- /// @param _rated Address to be rated.
- /// @param _rating Total EXP tokens to reallocate.
- function rate(address _rated, int8 _rating) external;
-
- /// @notice Remove a rating from an address.
- /// MUST emit a Remove event with each successful call.
- /// @param _removed Address to be removed.
- function removeRating(address _removed) external;
-
- /// @notice Return a rated address' rating.
- /// @dev MUST register each time `Rating` emits.
- /// SHOULD throw for queries about the zero address.
- /// @param _rated An address for whom to query rating.
- /// @return int8 The rating assigned.
- function ratingOf(address _rated) external view returns (int8);
-}
-
-interface IERC165 {
- /// @notice Query if a contract implements an interface.
- /// @dev Interface identification is specified in EIP-165. This function
- /// uses less than 30,000 gas.
- /// @param interfaceID The interface identifier, as specified in EIP-165.
- /// @return bool `true` if the contract implements `interfaceID` and
- /// `interfaceID` is not 0xffffffff, `false` otherwise.
- function supportsInterface(bytes4 interfaceID) external view returns (bool);
-}
\ No newline at end of file
diff --git a/assets/eip-4974/IERC4974Metadata.sol b/assets/eip-4974/IERC4974Metadata.sol
deleted file mode 100644
index fe75396..0000000
--- a/assets/eip-4974/IERC4974Metadata.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC4974.sol";
-
-/// @title ERC-4974 EXP Token Standard, optional metadata extension
-/// @dev See https://eips.ethereum.org/EIPS/EIP-4974
-/// Note: the ERC-165 identifier for this interface is 0x74793a15.
-interface IERC4974Metadata is IERC4974 {
- /// @notice A descriptive name for the EXP in this contract.
- function name() external view returns (string memory);
-
- /// @notice A one-line description of the EXP in this contract.
- function description() external view returns (string memory);
-}
\ No newline at end of file
diff --git a/assets/eip-4987/Consumer.sol b/assets/eip-4987/Consumer.sol
deleted file mode 100644
index 77302c8..0000000
--- a/assets/eip-4987/Consumer.sol
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Consumer
-
-SPDX-License-Identifier: CC0-1.0
-*/
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-
-import "./IERC721Holder.sol";
-
-/**
- * @title Consumer
- *
- * @notice this contract implements an example "consumer" of the proposed
- * held token ERC standard.
-
- * This example consumer contract will query ERC721 ownership and balances
- * including any "held" tokens
- */
-contract Consumer {
- using Address for address;
-
- // members
- IERC721 public token;
-
- /**
- * @param token_ address of ERC721 token
- */
- constructor(address token_) {
- token = IERC721(token_);
- }
-
- /**
- * @notice get the functional owner of a token
- * @param tokenId token id of interest
- */
- function getOwner(uint256 tokenId) external view returns (address) {
- // get raw owner
- address owner = token.ownerOf(tokenId);
-
- // if owner is not contract, return
- if (!owner.isContract()) {
- return owner;
- }
-
- // check for token holder interface support
- try IERC165(owner).supportsInterface(0x16b900ff) returns (bool ret) {
- if (!ret) return owner;
- } catch {
- return owner;
- }
-
- // check for held owner
- try IERC721Holder(owner).heldOwnerOf(address(token), tokenId) returns (address user) {
- if (user != address(0)) return user;
- } catch {}
-
- return owner;
- }
-
- /**
- * @notice get the total user balance including held tokens
- * @param owner user address
- * @param holders list of token holder addresses
- */
- function getBalance(address owner, address[] calldata holders)
- external
- view
- returns (uint256)
- {
- // start with raw token balance
- uint256 balance = token.balanceOf(owner);
-
- // consider each provided token holder contract
- for (uint256 i = 0; i < holders.length; i++) {
- balance += IERC721Holder(holders[i]).heldBalanceOf(address(token), owner);
- }
-
- return balance;
- }
-}
diff --git a/assets/eip-4987/IERC1155Holder.sol b/assets/eip-4987/IERC1155Holder.sol
deleted file mode 100644
index d98daee..0000000
--- a/assets/eip-4987/IERC1155Holder.sol
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-IERC1155Holder
-
-SPDX-License-Identifier: CC0-1.0
-*/
-
-import "@openzeppelin/contracts/interfaces/IERC165.sol";
-
-pragma solidity ^0.8.0;
-
-/**
- * @notice the ERC1155 holder standard provides a common interface to query
- * token balance information
- */
-interface IERC1155Holder is IERC165 {
- /**
- * @notice emitted when the token is transferred to the contract
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenId held token ID
- * @param tokenAmount held token amount
- */
- event Hold(
- address indexed owner,
- address indexed tokenAddress,
- uint256 indexed tokenId,
- uint256 tokenAmount
- );
-
- /**
- * @notice emitted when the token is released back to the user
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenId held token ID
- * @param tokenAmount held token amount
- */
- event Release(
- address indexed owner,
- address indexed tokenAddress,
- uint256 indexed tokenId,
- uint256 tokenAmount
- );
-
- /**
- * @notice get the held balance of the token owner
- * @param tokenAddress held token address
- * @param owner functional token owner
- * @param tokenId held token ID
- * @return held token balance
- */
- function heldBalanceOf(
- address tokenAddress,
- address owner,
- uint256 tokenId
- ) external view returns (uint256);
-}
diff --git a/assets/eip-4987/IERC20Holder.sol b/assets/eip-4987/IERC20Holder.sol
deleted file mode 100644
index fe040a2..0000000
--- a/assets/eip-4987/IERC20Holder.sol
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-IERC20Holder
-
-
-SPDX-License-Identifier: CC0-1.0
-*/
-
-import "@openzeppelin/contracts/interfaces/IERC165.sol";
-
-pragma solidity ^0.8.0;
-
-/**
- * @notice the ERC20 holder standard provides a common interface to query
- * token balance information
- */
-interface IERC20Holder is IERC165 {
- /**
- * @notice emitted when the token is transferred to the contract
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenAmount held token amount
- */
- event Hold(
- address indexed owner,
- address indexed tokenAddress,
- uint256 tokenAmount
- );
-
- /**
- * @notice emitted when the token is released back to the user
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenAmount held token amount
- */
- event Release(
- address indexed owner,
- address indexed tokenAddress,
- uint256 tokenAmount
- );
-
- /**
- * @notice get the held balance of the token owner
- * @param tokenAddress held token address
- * @param owner functional token owner
- * @return held token balance
- */
- function heldBalanceOf(address tokenAddress, address owner)
- external
- view
- returns (uint256);
-}
diff --git a/assets/eip-4987/IERC721Holder.sol b/assets/eip-4987/IERC721Holder.sol
deleted file mode 100644
index ed58be9..0000000
--- a/assets/eip-4987/IERC721Holder.sol
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
-IERC721Holder
-
-SPDX-License-Identifier: CC0-1.0
-*/
-
-import "@openzeppelin/contracts/interfaces/IERC165.sol";
-
-pragma solidity ^0.8.0;
-
-/**
- * @notice the ERC721 holder standard provides a common interface to query
- * token ownership and balance information
- */
-interface IERC721Holder is IERC165 {
- /**
- * @notice emitted when the token is transferred to the contract
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenId held token ID
- */
- event Hold(
- address indexed owner,
- address indexed tokenAddress,
- uint256 indexed tokenId
- );
-
- /**
- * @notice emitted when the token is released back to the user
- * @param owner functional token owner
- * @param tokenAddress held token address
- * @param tokenId held token ID
- */
- event Release(
- address indexed owner,
- address indexed tokenAddress,
- uint256 indexed tokenId
- );
-
- /**
- * @notice get the functional owner of a held token
- * @param tokenAddress held token address
- * @param tokenId held token ID
- * @return functional token owner
- */
- function heldOwnerOf(address tokenAddress, uint256 tokenId)
- external
- view
- returns (address);
-
- /**
- * @notice get the held balance of the token owner
- * @param tokenAddress held token address
- * @param owner functional token owner
- * @return held token balance
- */
- function heldBalanceOf(address tokenAddress, address owner)
- external
- view
- returns (uint256);
-}
diff --git a/assets/eip-4987/Vault.sol b/assets/eip-4987/Vault.sol
deleted file mode 100644
index 3045cd6..0000000
--- a/assets/eip-4987/Vault.sol
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
-Vault
-
-SPDX-License-Identifier: CC0-1.0
-*/
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-
-import "./IERC721Holder.sol";
-
-/**
- * @title Vault
- *
- * @notice this contract implements an example "holder" for the proposed
- * held token ERC standard.
-
- * This example vault contract allows a user to lock up an ERC721 token for
- * a specified period of time, while still reporting the functional owner
- */
-contract Vault is ERC165, IERC721Holder {
- // members
- IERC721 public token;
- uint256 public timelock;
- mapping(uint256 => address) public owners;
- mapping(uint256 => uint256) public locks;
- mapping(address => uint256) public balances;
-
- /**
- * @param token_ address of token to be stored in vault
- * @param timelock_ duration in seconds that tokens will be locked
- */
- constructor(address token_, uint256 timelock_) {
- token = IERC721(token_);
- timelock = timelock_;
- }
-
- /**
- * @inheritdoc IERC165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(ERC165, IERC165)
- returns (bool)
- {
- return
- interfaceId == type(IERC721Holder).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @inheritdoc IERC721Holder
- */
- function heldOwnerOf(address tokenAddress, uint256 tokenId)
- external
- view
- override
- returns (address)
- {
- require(
- tokenAddress == address(token),
- "ERC721Vault: invalid token address"
- );
- return owners[tokenId];
- }
-
- /**
- * @inheritdoc IERC721Holder
- */
- function heldBalanceOf(address tokenAddress, address owner)
- external
- view
- override
- returns (uint256)
- {
- require(
- tokenAddress == address(token),
- "ERC721Vault: invalid token address"
- );
- return balances[owner];
- }
-
- /**
- * @notice deposit and lock a token for a period of time
- * @param tokenId ID of token to deposit
- */
- function deposit(uint256 tokenId) public {
- require(
- msg.sender == token.ownerOf(tokenId),
- "ERC721Vault: sender does not own token"
- );
-
- owners[tokenId] = msg.sender;
- locks[tokenId] = block.timestamp + timelock;
- balances[msg.sender]++;
-
- emit Hold(msg.sender, address(token), tokenId);
-
- token.transferFrom(msg.sender, address(this), tokenId);
- }
-
- /**
- * @notice withdraw token after timelock has elapsed
- * @param tokenId ID of token to withdraw
- */
- function withdraw(uint256 tokenId) public {
- require(
- msg.sender == owners[tokenId],
- "ERC721Vault: sender does not own token"
- );
- require(block.timestamp > locks[tokenId], "ERC721Vault: token is locked");
-
- delete owners[tokenId];
- delete locks[tokenId];
- balances[msg.sender]--;
-
- emit Release(msg.sender, address(token), tokenId);
-
- token.safeTransferFrom(address(this), msg.sender, tokenId);
- }
-}
diff --git a/assets/eip-5006/.gitignore b/assets/eip-5006/.gitignore
deleted file mode 100644
index e0da618..0000000
--- a/assets/eip-5006/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules/
-package-lock.json
-typechain/
-cache/
-artifacts/
\ No newline at end of file
diff --git a/assets/eip-5006/contracts/ERC5006.sol b/assets/eip-5006/contracts/ERC5006.sol
deleted file mode 100644
index 1747438..0000000
--- a/assets/eip-5006/contracts/ERC5006.sol
+++ /dev/null
@@ -1,147 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
-import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Receiver.sol";
-import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
-import "./IERC5006.sol";
-
-contract ERC5006 is ERC1155, ERC1155Receiver, IERC5006 {
- using EnumerableSet for EnumerableSet.UintSet;
- mapping(uint256 => mapping(address => uint256)) private _frozens;
- mapping(uint256 => UserRecord) private _records;
- mapping(uint256 => mapping(address => EnumerableSet.UintSet))
- private _userRecordIds;
- uint256 _curRecordId;
- uint256 recordLimit;
-
- constructor(string memory uri_, uint256 recordLimit_) ERC1155(uri_) {
- recordLimit = recordLimit_;
- }
-
- function isOwnerOrApproved(address owner) public view returns (bool) {
- require(
- owner == msg.sender || isApprovedForAll(owner, msg.sender),
- "only owner or approved"
- );
- return true;
- }
-
- function usableBalanceOf(address account, uint256 tokenId)
- public
- view
- override
- returns (uint256 amount)
- {
- uint256[] memory recordIds = _userRecordIds[tokenId][account].values();
- for (uint256 i = 0; i < recordIds.length; i++) {
- if (block.timestamp <= _records[recordIds[i]].expiry) {
- amount += _records[recordIds[i]].amount;
- }
- }
- }
-
- function frozenBalanceOf(address account, uint256 tokenId)
- public
- view
- override
- returns (uint256)
- {
- return _frozens[tokenId][account];
- }
-
- function userRecordOf(uint256 recordId)
- public
- view
- override
- returns (UserRecord memory)
- {
- return _records[recordId];
- }
-
- function createUserRecord(
- address owner,
- address user,
- uint256 tokenId,
- uint64 amount,
- uint64 expiry
- ) public override returns (uint256) {
- require(isOwnerOrApproved(owner));
- require(user != address(0), "user cannot be the zero address");
- require(amount > 0, "amount must be greater than 0");
- require(expiry > block.timestamp, "expiry must after the block timestamp");
- require(
- _userRecordIds[tokenId][user].length() < recordLimit,
- "user cannot have more records"
- );
- _safeTransferFrom(owner, address(this), tokenId, amount, "");
- _frozens[tokenId][owner] += amount;
- _curRecordId++;
- _records[_curRecordId] = UserRecord(
- tokenId,
- owner,
- amount,
- user,
- expiry
- );
- _userRecordIds[tokenId][user].add(_curRecordId);
- emit CreateUserRecord(
- _curRecordId,
- tokenId,
- amount,
- owner,
- user,
- expiry
- );
- return _curRecordId;
- }
-
- function deleteUserRecord(uint256 recordId) public override {
- UserRecord storage _record = _records[recordId];
- require(isOwnerOrApproved(_record.owner));
- _safeTransferFrom(
- address(this),
- _record.owner,
- _record.tokenId,
- _record.amount,
- ""
- );
- _frozens[_record.tokenId][_record.owner] -= _record.amount;
- _userRecordIds[_record.tokenId][_record.user].remove(recordId);
- delete _records[recordId];
- emit DeleteUserRecord(recordId);
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- override(ERC1155, ERC1155Receiver)
- returns (bool)
- {
- return
- interfaceId == type(IERC5006).interfaceId ||
- ERC1155.supportsInterface(interfaceId) ||
- ERC1155Receiver.supportsInterface(interfaceId);
- }
-
- function onERC1155Received(
- address operator,
- address from,
- uint256 tokenId,
- uint256 value,
- bytes calldata data
- ) external pure override returns (bytes4) {
- return IERC1155Receiver.onERC1155Received.selector;
- }
-
- function onERC1155BatchReceived(
- address operator,
- address from,
- uint256[] calldata ids,
- uint256[] calldata values,
- bytes calldata data
- ) external pure override returns (bytes4) {
- return IERC1155Receiver.onERC1155BatchReceived.selector;
- }
-}
diff --git a/assets/eip-5006/contracts/ERC5006Demo.sol b/assets/eip-5006/contracts/ERC5006Demo.sol
deleted file mode 100644
index fd409e0..0000000
--- a/assets/eip-5006/contracts/ERC5006Demo.sol
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC5006.sol";
-
-contract ERC5006Demo is ERC5006 {
- constructor(string memory uri_, uint256 recordLimit_)
- ERC5006(uri_, recordLimit_)
- {}
-
- function mint(
- address to,
- uint256 id,
- uint256 amount
- ) public {
- _mint(to, id, amount, "");
- }
-
- function burn(
- address from,
- uint256 id,
- uint256 amount
- ) public {
- _burn(from, id, amount);
- }
-
- function getInterfaceId() public view returns (bytes4) {
- return type(IERC5006).interfaceId;
- }
-}
diff --git a/assets/eip-5006/contracts/IERC5006.sol b/assets/eip-5006/contracts/IERC5006.sol
deleted file mode 100644
index 4d7a147..0000000
--- a/assets/eip-5006/contracts/IERC5006.sol
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5006 {
- struct UserRecord {
- uint256 tokenId;
- address owner;
- uint64 amount;
- address user;
- uint64 expiry;
- }
- /**
- * @dev Emitted when permission (for `user` to use `amount` of `tokenId` token owned by `owner`
- * until `expiry`) is given.
- */
- event CreateUserRecord(
- uint256 recordId,
- uint256 tokenId,
- uint64 amount,
- address owner,
- address user,
- uint64 expiry
- );
- /**
- * @dev Emitted when record of `recordId` is deleted.
- */
- event DeleteUserRecord(uint256 recordId);
-
- /**
- * @dev Returns the usable amount of `tokenId` tokens by `account`.
- */
- function usableBalanceOf(address account, uint256 tokenId)
- external
- view
- returns (uint256);
-
- /**
- * @dev Returns the amount of frozen tokens of token type `id` by `account`.
- */
- function frozenBalanceOf(address account, uint256 tokenId)
- external
- view
- returns (uint256);
-
- /**
- * @dev Returns the `UserRecord` of `recordId`.
- */
- function userRecordOf(uint256 recordId)
- external
- view
- returns (UserRecord memory);
-
- /**
- * @dev Gives permission to `user` to use `amount` of `tokenId` token owned by `owner` until `expiry`.
- *
- * Emits a {CreateUserRecord} event.
- *
- * Requirements:
- *
- * - If the caller is not `owner`, it must be have been approved to spend ``owner``'s tokens
- * via {setApprovalForAll}.
- * - `owner` must have a balance of tokens of type `id` of at least `amount`.
- * - `user` cannot be the zero address.
- * - `amount` must be greater than 0.
- * - `expiry` must after the block timestamp.
- */
- function createUserRecord(
- address owner,
- address user,
- uint256 tokenId,
- uint64 amount,
- uint64 expiry
- ) external returns (uint256);
-
- /**
- * @dev Atomically delete `record` of `recordId` by the caller.
- *
- * Emits a {DeleteUserRecord} event.
- *
- * Requirements:
- *
- * - the caller must have allowance.
- */
- function deleteUserRecord(uint256 recordId) external;
-}
diff --git a/assets/eip-5006/hardhat.config.ts b/assets/eip-5006/hardhat.config.ts
deleted file mode 100644
index 9b10629..0000000
--- a/assets/eip-5006/hardhat.config.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { HardhatUserConfig, task } from "hardhat/config";
-import "@nomiclabs/hardhat-waffle";
-import "@typechain/hardhat";
-
-// This is a sample Hardhat task. To learn how to create your own go to
-// https://hardhat.org/guides/create-task.html
-task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
- const accounts = await hre.ethers.getSigners();
-
- for (const account of accounts) {
- console.log(account.address);
- }
-});
-
-
-const config: HardhatUserConfig = {
- solidity: {
- version: "0.8.9",
- settings: {
- optimizer: {
- enabled: true,
- runs: 200
- }
- }
- },
-
-};
-
-
-
-export default config;
diff --git a/assets/eip-5006/package.json b/assets/eip-5006/package.json
deleted file mode 100644
index a20ad3f..0000000
--- a/assets/eip-5006/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "EIP-5006",
- "devDependencies": {
- "@nomiclabs/hardhat-ethers": "^2.0.5",
- "@nomiclabs/hardhat-waffle": "^2.0.3",
- "@openzeppelin/contracts": "^4.5.0",
- "@typechain/ethers-v5": "^7.2.0",
- "@typechain/hardhat": "^2.3.1",
- "@types/chai": "^4.3.0",
- "@types/mocha": "^9.1.0",
- "@types/node": "^12.20.47",
- "chai": "^4.3.6",
- "ethers": "^5.6.1",
- "hardhat": "^2.9.2",
- "solhint": "^3.3.7",
- "ts-node": "^10.8.1",
- "typechain": "^5.2.0",
- "typescript": "^4.6.3"
- }
-}
diff --git a/assets/eip-5006/test/test.ts b/assets/eip-5006/test/test.ts
deleted file mode 100644
index 41fd7bd..0000000
--- a/assets/eip-5006/test/test.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import hre from "hardhat";
-
-describe("Test 1155 User Role", function () {
- let alice, bob, carl;
- let contract;
- let expiry;
-
- async function checkRecord(rid,tokenId,amount,owner,user,expiry_) {
- let record = await contract.userRecordOf(rid);
- expect(record[0]).equals(tokenId,"tokenId");
- expect(record[1]).equals(owner,"owner");
- expect(record[2]).equals(amount,"amount");
- expect(record[3]).equals(user,"user");
- expect(record[4]).equals(expiry_,"expiry_");
- }
-
- beforeEach(async function () {
- [alice, bob, carl] = await ethers.getSigners();
-
- const ERC5006Demo = await ethers.getContractFactory("ERC5006Demo");
-
- contract = await ERC5006Demo.deploy("", 3);
-
- expiry = Math.floor(new Date().getTime() / 1000) + 3600;
- });
-
-
-
- describe("", function () {
-
- it("InterfaceId should equals 0xc26d96cc", async function () {
- expect(await contract.getInterfaceId()).equals("0xc26d96cc");
- });
-
- it("Should set user to bob success", async function () {
-
- await contract.mint(alice.address, 1, 100);
-
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
-
- await checkRecord(1,1,10,alice.address,bob.address,expiry);
-
- expect(await contract.usableBalanceOf(bob.address, 1)).equals(10);
-
- expect(await contract.balanceOf(alice.address, 1)).equals(90);
-
- expect(await contract.frozenBalanceOf(alice.address, 1)).equals(10);
-
- });
-
- it("Should set user to bob fail", async function () {
-
- await contract.mint(alice.address, 1, 100);
-
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
- await expect(contract.createUserRecord(alice.address, bob.address, 1, 10, expiry)).to.be.revertedWith("user cannot have more records");
-
- });
-
- it("Should set user to bob fail : balance is not enough", async function () {
-
- await contract.mint(alice.address, 1, 100);
-
- await expect(contract.createUserRecord(alice.address, bob.address, 1, 101, expiry)).to.be.revertedWith('ERC1155: insufficient balance for transfer');
-
- });
-
- it("Should set user to bob fail : only owner or approved", async function () {
-
- await contract.mint(alice.address, 1, 100);
- await contract.mint(carl.address, 1, 100);
-
- await expect(contract.createUserRecord(carl.address, bob.address, 1, 110, expiry)).to.be.revertedWith('only owner or approved');
-
- });
-
- it("Should deleteUserRecord success", async function () {
-
- await contract.mint(alice.address, 1, 100);
-
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
-
- // await hre.network.provider.send("hardhat_mine", ["0x5a0", "0x3c"]);
-
- await contract.deleteUserRecord(1);
-
- await checkRecord(1,0,0,"0x0000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000",0);
-
- expect(await contract.usableBalanceOf(bob.address, 1)).equals(0);
-
- expect(await contract.balanceOf(alice.address, 1)).equals(100);
-
- expect(await contract.frozenBalanceOf(alice.address, 1)).equals(0);
-
- });
-
-
- it("bob should deleteUserRecord fail", async function () {
-
- await contract.mint(alice.address, 1, 100);
-
- await contract.createUserRecord(alice.address, bob.address, 1, 10, expiry);
-
- await expect(contract.connect(bob).deleteUserRecord(1)).to.be.revertedWith("only owner or approved");
-
- });
-
-
- });
-
-
-});
diff --git a/assets/eip-5006/tsconfig.json b/assets/eip-5006/tsconfig.json
deleted file mode 100644
index c458030..0000000
--- a/assets/eip-5006/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "module": "commonjs",
- "strict": false,
- "esModuleInterop": true,
- "outDir": "dist",
- "declaration": true
- },
- "include": ["./test", "./typechain"],
- "files": ["./hardhat.config.ts"]
-}
diff --git a/assets/eip-5007/.gitignore b/assets/eip-5007/.gitignore
deleted file mode 100644
index d5f19d8..0000000
--- a/assets/eip-5007/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-package-lock.json
diff --git a/assets/eip-5007/README.md b/assets/eip-5007/README.md
deleted file mode 100644
index 9bc3c31..0000000
--- a/assets/eip-5007/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# EIP-5007
-This standard is an extension of [ERC-721](../../EIPS/eip-721.md). It proposes some additional functions (`startTime`, `endTime`) to help with on-chain time management.
-
-## Tools
-* [Truffle](https://truffleframework.com/) - a development framework for Ethereum
-
-## Install
-```
-npm install
-```
-
-## Test
-```
-truffle test
-```
diff --git a/assets/eip-5007/contracts/ERC5007.sol b/assets/eip-5007/contracts/ERC5007.sol
deleted file mode 100644
index fecedb5..0000000
--- a/assets/eip-5007/contracts/ERC5007.sol
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC5007.sol";
-
-abstract contract ERC5007 is ERC721, IERC5007 {
- struct TimeNftInfo {
- int64 startTime;
- int64 endTime;
- }
-
- mapping(uint256 => TimeNftInfo) internal _timeNftMapping;
-
- /**
- * @dev See {IERC5007-startTime}.
- */
- function startTime(uint256 tokenId)
- public
- view
- virtual
- override
- returns (int64) {
- require(_exists(tokenId), "ERC5007: invalid tokenId");
- return _timeNftMapping[tokenId].startTime;
- }
-
- /**
- * @dev See {IERC5007-endTime}.
- */
- function endTime(uint256 tokenId)
- public
- view
- virtual
- override
- returns (int64) {
- require(_exists(tokenId), "ERC5007: invalid tokenId");
- return _timeNftMapping[tokenId].endTime;
- }
-
- /**
- * @dev mint a new time NFT.
- *
- * Requirements:
- *
- * - `tokenId_` must not exist.
- * - `to_` cannot be the zero address.
- * - `endTime_` should be equal or greater than `startTime_`
- */
- function _mintTimeNft(
- address to_,
- uint256 tokenId_,
- int64 startTime_,
- int64 endTime_
- ) internal virtual {
- require(endTime_ >= startTime_, 'ERC5007: invalid endTime');
- _mint(to_, tokenId_);
- TimeNftInfo storage info = _timeNftMapping[tokenId_];
- info.startTime = startTime_;
- info.endTime = endTime_;
- }
-
-
- /**
- * @dev Destroys `tokenId`.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- *
- */
- function _burn(uint256 tokenId) internal virtual override {
- super._burn(tokenId);
- delete _timeNftMapping[tokenId];
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool) {
- return
- interfaceId == type(IERC5007).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5007/contracts/ERC5007Composable.sol b/assets/eip-5007/contracts/ERC5007Composable.sol
deleted file mode 100644
index e27defe..0000000
--- a/assets/eip-5007/contracts/ERC5007Composable.sol
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-import "./ERC5007.sol";
-import "./IERC5007Composable.sol";
-
-abstract contract ERC5007Composable is ERC5007, IERC5007Composable {
- mapping(uint256 => uint256) internal _rootIdMapping;
-
- /**
- * @dev See {IERC5007Composable-rootTokenId}.
- */
- function rootTokenId(uint256 tokenId)
- public
- view
- override
- returns (uint256 rootId)
- {
- require(_exists(tokenId), "ERC5007: invalid tokenId");
- rootId = _rootIdMapping[tokenId];
- }
-
- /**
- * @dev See {IERC5007Composable-split}.
- */
- function split(
- uint256 oldTokenId,
- uint256 newTokenId,
- address newTokenOwner,
- int64 newTokenStartTime
- ) public virtual override {
- require(
- _isApprovedOrOwner(_msgSender(), oldTokenId),
- "ERC5007: caller is not owner nor approved"
- );
-
- int64 oldTokenStartTime = _timeNftMapping[oldTokenId].startTime;
- int64 oldTokenEndTime = _timeNftMapping[oldTokenId].endTime;
- require(
- oldTokenStartTime < newTokenStartTime &&
- newTokenStartTime <= oldTokenEndTime,
- "ERC5007: invalid newTokenStartTime"
- );
-
- _timeNftMapping[oldTokenId].endTime = newTokenStartTime - 1;
- int64 newTokenEndTime = oldTokenEndTime;
-
- _mintTimeNftWithRootId(
- newTokenOwner,
- newTokenId,
- _rootIdMapping[oldTokenId],
- newTokenStartTime,
- newTokenEndTime
- );
- }
-
- /**
- * @dev See {IERC5007Composable-merge}.
- */
- function merge(
- uint256 firstTokenId,
- uint256 secondTokenId,
- address newTokenOwner,
- uint256 newTokenId
- ) public virtual {
- require(
- _isApprovedOrOwner(_msgSender(), firstTokenId) &&
- _isApprovedOrOwner(_msgSender(), secondTokenId),
- "ERC5007: caller is not owner nor approved"
- );
-
- TimeNftInfo memory firstToken = _timeNftMapping[firstTokenId];
- TimeNftInfo memory secondToken = _timeNftMapping[secondTokenId];
- require(
- _rootIdMapping[firstTokenId] == _rootIdMapping[secondTokenId] &&
- firstToken.startTime <= firstToken.endTime &&
- (firstToken.endTime + 1) == secondToken.startTime &&
- secondToken.startTime <= secondToken.endTime,
- "ERC5007: invalid input data"
- );
-
-
- _mintTimeNftWithRootId(
- newTokenOwner,
- newTokenId,
- _rootIdMapping[firstTokenId],
- firstToken.startTime,
- secondToken.endTime
- );
-
- _burn(firstTokenId);
- _burn(secondTokenId);
- }
-
- /**
- * @dev mint a new common time NFT
- *
- * Requirements:
- *
- * - `to_` cannot be the zero address.
- * - `tokenId_` must not exist.
- * - `rootId_` must exist.
- * - `endTime_` should be equal or greater than `startTime_`
- */
- function _mintTimeNftWithRootId(
- address to_,
- uint256 tokenId_,
- uint256 rootId_,
- int64 startTime_,
- int64 endTime_
- ) internal virtual {
- require(_exists(rootId_), "ERC5007: invalid rootId_");
- super._mintTimeNft(to_, tokenId_, startTime_, endTime_);
- _rootIdMapping[tokenId_] = rootId_;
- }
-
- /**
- * @dev mint a new common time NFT
- *
- * Requirements:
- *
- * - `to_` cannot be the zero address.
- * - `tokenId_` must not exist.
- * - `endTime_` should be equal or greater than `startTime_`
- */
- function _mintTimeNft(
- address to_,
- uint256 tokenId_,
- int64 startTime_,
- int64 endTime_
- ) internal virtual override {
- super._mintTimeNft(to_, tokenId_, startTime_, endTime_);
-
- _rootIdMapping[tokenId_] = tokenId_;
- }
-
- /**
- * @dev Destroys `tokenId`.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- *
- */
- function _burn(uint256 tokenId) internal virtual override {
- super._burn(tokenId);
- delete _rootIdMapping[tokenId];
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5007Composable).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5007/contracts/ERC5007ComposableTest.sol b/assets/eip-5007/contracts/ERC5007ComposableTest.sol
deleted file mode 100644
index 7524ba2..0000000
--- a/assets/eip-5007/contracts/ERC5007ComposableTest.sol
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./ERC5007Composable.sol";
-
-contract ERC5007ComposableTest is ERC5007Composable {
-
- constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {}
-
- /// @notice mint a new root time NFT
- /// @param to_ The owner of the new token
- /// @param id_ The id of the new token
- /// @param startTime_ The start time of the new token
- /// @param endTime_ The end time of the new token
- function mint(
- address to_,
- uint256 id_,
- int64 startTime_,
- int64 endTime_
- ) public {
- super._mintTimeNft(to_, id_, startTime_, endTime_);
- }
-
- /**
- * @dev Returns the interfaceId of IERC5007Composable.
- */
- function getInterfaceId() public pure returns (bytes4) {
- return type(IERC5007Composable).interfaceId;
- }
-}
diff --git a/assets/eip-5007/contracts/ERC5007Demo.sol b/assets/eip-5007/contracts/ERC5007Demo.sol
deleted file mode 100644
index 67ee031..0000000
--- a/assets/eip-5007/contracts/ERC5007Demo.sol
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./ERC5007.sol";
-
-contract ERC5007Demo is ERC5007 {
- constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_){}
-
- /**
- * @dev mint a new time NFT
- *
- * Requirements:
- *
- * - `to_` cannot be the zero address.
- * - `tokenId_` must not exist.
- * - `endTime_` should be equal or greater than `startTime_`
- */
- function mint(
- address to_,
- uint256 tokenId_,
- int64 startTime_,
- int64 endTime_
- ) public {
- _mintTimeNft(to_, tokenId_, startTime_, endTime_);
- }
-
- /**
- * @dev Returns the interfaceId of IERC5007.
- */
- function getInterfaceId() public pure returns (bytes4) {
- return type(IERC5007).interfaceId;
- }
-}
diff --git a/assets/eip-5007/contracts/IERC5007.sol b/assets/eip-5007/contracts/IERC5007.sol
deleted file mode 100644
index 9e5f6d6..0000000
--- a/assets/eip-5007/contracts/IERC5007.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5007 /* is IERC1155 */ {
- /**
- * @dev Returns the start time of the NFT.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function startTime(uint256 tokenId) external view returns (int64);
-
- /**
- * @dev Returns the end time of the NFT.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function endTime(uint256 tokenId) external view returns (int64);
-}
diff --git a/assets/eip-5007/contracts/IERC5007Composable.sol b/assets/eip-5007/contracts/IERC5007Composable.sol
deleted file mode 100644
index f1c58c5..0000000
--- a/assets/eip-5007/contracts/IERC5007Composable.sol
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-
-interface IERC5007Composable /* is IERC5007 */ {
- /**
- * @dev Returns the ancestor token id of the NFT.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function rootTokenId(uint256 tokenId) external view returns (uint256);
-
- /**
- * @dev Mint a new token from an old token.
- * The rootTokenId of the new token is the same as the rootTokenId of the old token
- *
- * Requirements:
- *
- * - `oldTokenId` must exist.
- * - `newTokenId` must not exist.
- * - `newTokenOwner` cannot be the zero address.
- * - `newTokenStartTime` require(oldTokenStartTime < newTokenStartTime && newTokenStartTime <= oldTokenEndTime)
- */
- function split(
- uint256 oldTokenId,
- uint256 newTokenId,
- address newTokenOwner,
- int64 newTokenStartTime
- ) external;
-
- /**
- * @dev Merge the first token and second token into the new token.
- *
- * Requirements:
- *
- * - `firstTokenId` must exist.
- * - `secondTokenId` must exist. require((firstToken.endTime + 1) == secondToken.startTime)
- * - `newTokenOwner` cannot be the zero address.
- * - `newTokenId` must not exist.
- */
- function merge(
- uint256 firstTokenId,
- uint256 secondTokenId,
- address newTokenOwner,
- uint256 newTokenId
- ) external;
-}
diff --git a/assets/eip-5007/migrations/1_initial_migration.js b/assets/eip-5007/migrations/1_initial_migration.js
deleted file mode 100644
index 31c03a3..0000000
--- a/assets/eip-5007/migrations/1_initial_migration.js
+++ /dev/null
@@ -1,7 +0,0 @@
-const ERC5007Demo = artifacts.require("ERC5007Demo");
-const ERC5007ComposableTest = artifacts.require("ERC5007ComposableTest");
-
-module.exports = function (deployer) {
- deployer.deploy(ERC5007Demo,'ERC5007Demo','ERC5007Demo');
- deployer.deploy(ERC5007ComposableTest,'ERC5007ComposableTest','ERC5007ComposableTest');
-};
diff --git a/assets/eip-5007/package.json b/assets/eip-5007/package.json
deleted file mode 100644
index eb917b7..0000000
--- a/assets/eip-5007/package.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "name": "ERC5007",
- "dependencies": {
- "@openzeppelin/contracts": "^4.3.3",
- "@types/chai": "^4.3.0",
- "@types/mocha": "^9.1.0",
- "bignumber.js": "^9.0.1",
- "chai": "^4.3.6"
- }
-}
diff --git a/assets/eip-5007/test/test.js b/assets/eip-5007/test/test.js
deleted file mode 100644
index ecb87af..0000000
--- a/assets/eip-5007/test/test.js
+++ /dev/null
@@ -1,95 +0,0 @@
-const { assert } = require("chai");
-
-const { BigNumber } = require("bignumber.js")
-
-const ERC5007Demo = artifacts.require("ERC5007Demo");
-const ERC5007ComposableTest = artifacts.require("ERC5007ComposableTest");
-
-contract("test ERC5007", async accounts => {
-
- it("test ERC5007", async () => {
- const Alice = accounts[0];
-
- const instance = await ERC5007Demo.deployed("ERC5007Demo", "ERC5007Demo");
- const demo = instance;
-
- let now = Math.floor(new Date().getTime()/1000);
- let inputStartTime1 = new BigNumber(now - 10000);
- let inputEndTime1 = new BigNumber(now + 10000);
- let id1 = 1;
-
- await demo.mint(Alice, id1, inputStartTime1.toFixed(0), inputEndTime1.toFixed(0));
-
-
- let outputStartTime1 = await demo.startTime(id1);
- let outputEndTime1 = await demo.endTime(id1);
- assert.equal(inputStartTime1.comparedTo(outputStartTime1) == 0 && inputEndTime1.comparedTo(outputEndTime1) == 0, true, "wrong data");
-
-
- console.log("IERC5007 InterfaceId:", await demo.getInterfaceId())
- let isSupport = await demo.supportsInterface('0x7a0cdf92');
- assert.equal(isSupport, true , "supportsInterface error");
-
- });
-
- it("test ERC5007Composable", async () => {
- const Alice = accounts[0];
- const Bob = accounts[1];
- const Carl = accounts[2];
-
- const instance = await ERC5007ComposableTest.deployed("ERC5007ComposableTest", "ERC5007ComposableTest");
- const demo = instance;
-
- let now = Math.floor(new Date().getTime()/1000);
- let token1InputStartTime = new BigNumber(now - 10000);
- let token1InputEndTime = new BigNumber(now + 10000);
- let id1 = 1;
-
- await demo.mint(Alice, id1, token1InputStartTime.toFixed(0), token1InputEndTime.toFixed(0));
-
- let token1OutputStartTime = new BigNumber( await demo.startTime(id1));
- let token1OutputEndTime = new BigNumber( await demo.endTime(id1));
- assert.equal(token1InputStartTime.comparedTo(token1OutputStartTime) == 0
- && token1InputEndTime.comparedTo(token1OutputEndTime) == 0, true, "wrong data");
-
- let id2 = 2;
- let token2InputStartTime = token1InputStartTime.plus(5000);
- await demo.split(id1, id2, Bob, token2InputStartTime.toFixed(0));
-
- token1OutputStartTime = new BigNumber( await demo.startTime(id1));
- token1OutputEndTime = new BigNumber( await demo.endTime(id1));
-
- let token2OutputStartTime = new BigNumber( await demo.startTime(id2));
- let token2OutputEndTime = new BigNumber( await demo.endTime(id2));
-
- assert.equal(token1InputStartTime.comparedTo(token1OutputStartTime) == 0
- && token1OutputEndTime.comparedTo(token2InputStartTime.minus(1)) == 0, true, "wrong data");
-
- assert.equal(token2InputStartTime.comparedTo(token2OutputStartTime) == 0
- && token2OutputEndTime.comparedTo(token1InputEndTime) == 0, true, "wrong data");
-
- let token1RootId = await demo.rootTokenId(id1);
- let token2RootId = await demo.rootTokenId(id2);
- assert.equal(token1RootId == id1 && token2RootId == id1, true, 'wrong data');
-
- let id3 = 3;
- await demo.setApprovalForAll(Alice, true,{from: Bob});
- await demo.merge(id1, id2, Carl, id3);
-
- let token3OutputStartTime = new BigNumber( await demo.startTime(id3));
- let token3OutputEndTime = new BigNumber( await demo.endTime(id3));
- let token3RootId = await demo.rootTokenId(id3);
- let token3Owner = await demo.ownerOf(id3);
-
- assert.equal(token1InputStartTime.comparedTo(token3OutputStartTime) == 0
- && token3OutputEndTime.comparedTo(token1InputEndTime) == 0, true, "wrong start time or end time");
-
- assert.equal(token3RootId == id1, true, 'wrong rootId');
- assert.equal(token3Owner == Carl, true, 'wrong owner');
-
- console.log("IERC5007Composable InterfaceId:", await demo.getInterfaceId())
- let isSupport = await demo.supportsInterface('0x620063db');
- assert.equal(isSupport, true , "supportsInterface error");
- });
-
-});
diff --git a/assets/eip-5007/truffle-config.js b/assets/eip-5007/truffle-config.js
deleted file mode 100644
index ccc194a..0000000
--- a/assets/eip-5007/truffle-config.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * Use this file to configure your truffle project. It's seeded with some
- * common settings for different networks and features like migrations,
- * compilation and testing. Uncomment the ones you need or modify
- * them to suit your project as necessary.
- *
- * More information about configuration can be found at:
- *
- * trufflesuite.com/docs/advanced/configuration
- *
- * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
- * to sign your transactions before they're sent to a remote public node. Infura accounts
- * are available for free at: infura.io/register.
- *
- * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
- * public/private key pairs. If you're publishing your code to GitHub make sure you load this
- * phrase from a file you've .gitignored so it doesn't accidentally become public.
- *
- */
-
-// const HDWalletProvider = require('@truffle/hdwallet-provider');
-//
-// const fs = require('fs');
-// const mnemonic = fs.readFileSync(".secret").toString().trim();
-
-module.exports = {
- /**
- * Networks define how you connect to your ethereum client and let you set the
- * defaults web3 uses to send transactions. If you don't specify one truffle
- * will spin up a development blockchain for you on port 9545 when you
- * run `develop` or `test`. You can ask a truffle command to use a specific
- * network from the command line, e.g
- *
- * $ truffle test --network
- */
-
- networks: {
- // Useful for testing. The `development` name is special - truffle uses it by default
- // if it's defined here and no other network is specified at the command line.
- // You should run a client (like ganache-cli, geth or parity) in a separate terminal
- // tab if you use this network and you must also set the `host`, `port` and `network_id`
- // options below to some value.
- //
- // development: {
- // host: "127.0.0.1", // Localhost (default: none)
- // port: 8545, // Standard Ethereum port (default: none)
- // network_id: "*", // Any network (default: none)
- // },
- // Another network with more advanced options...
- // advanced: {
- // port: 8777, // Custom port
- // network_id: 1342, // Custom network
- // gas: 8500000, // Gas sent with each transaction (default: ~6700000)
- // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei)
- // from: , // Account to send txs from (default: accounts[0])
- // websocket: true // Enable EventEmitter interface for web3 (default: false)
- // },
- // Useful for deploying to a public network.
- // NB: It's important to wrap the provider as a function.
- // ropsten: {
- // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`),
- // network_id: 3, // Ropsten's id
- // gas: 5500000, // Ropsten has a lower block limit than mainnet
- // confirmations: 2, // # of confs to wait between deployments. (default: 0)
- // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50)
- // skipDryRun: true // Skip dry run before migrations? (default: false for public nets )
- // },
- // Useful for private networks
- // private: {
- // provider: () => new HDWalletProvider(mnemonic, `https://network.io`),
- // network_id: 2111, // This network is yours, in the cloud.
- // production: true // Treats this network as if it was a public net. (default: false)
- // }
- },
-
- // Set default mocha options here, use special reporters etc.
- mocha: {
- // timeout: 100000
- },
-
- // Configure your compilers
- compilers: {
- solc: {
- version: "0.8.10", // Fetch exact version from solc-bin (default: truffle's version)
- // docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
- settings: { // See the solidity docs for advice about optimization and evmVersion
- optimizer: {
- enabled: false,
- runs: 200
- }
- // ,
- // evmVersion: "byzantium"
- // }
- }
- },
-
- // Truffle DB is currently disabled by default; to enable it, change enabled:
- // false to enabled: true. The default storage location can also be
- // overridden by specifying the adapter settings, as shown in the commented code below.
- //
- // NOTE: It is not possible to migrate your contracts to truffle DB and you should
- // make a backup of your artifacts to a safe location before enabling this feature.
- //
- // After you backed up your artifacts you can utilize db by running migrate as follows:
- // $ truffle migrate --reset --compile-all
- //
- // db: {
- // enabled: false,
- // host: "127.0.0.1",
- // adapter: {
- // name: "sqlite",
- // settings: {
- // directory: ".db"
- // }
- // }
- }
-};
diff --git a/assets/eip-5008/.gitignore b/assets/eip-5008/.gitignore
deleted file mode 100644
index b55321b..0000000
--- a/assets/eip-5008/.gitignore
+++ /dev/null
@@ -1,5 +0,0 @@
-node_modules/
-package-lock.json
-typechain/
-cache/
-artifacts/
diff --git a/assets/eip-5008/contracts/ERC5008.sol b/assets/eip-5008/contracts/ERC5008.sol
deleted file mode 100644
index ccf251c..0000000
--- a/assets/eip-5008/contracts/ERC5008.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC5008.sol";
-
-contract ERC5008 is ERC721, IERC5008 {
- mapping(uint256 => uint256) private _tokenNonce;
-
- constructor(string memory name_, string memory symbol_)ERC721(name_, symbol_){
- }
-
- /// @notice Get the nonce of an NFT
- /// Throws if `tokenId` is not a valid NFT
- /// @param tokenId The NFT to get the nonce for
- /// @return The nonce of this NFT
- function nonce(uint256 tokenId) public virtual override view returns(uint256) {
- require(_exists(tokenId), "Error: query for nonexistent token");
-
- return _tokenNonce[tokenId];
- }
-
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override{
- super._beforeTokenTransfer(from, to, tokenId);
- _tokenNonce[tokenId]++;
- }
-
- /// @dev See {IERC165-supportsInterface}.
- function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- return interfaceId == type(IERC5008).interfaceId || super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5008/contracts/ERC5008Demo.sol b/assets/eip-5008/contracts/ERC5008Demo.sol
deleted file mode 100644
index 0e1c6fb..0000000
--- a/assets/eip-5008/contracts/ERC5008Demo.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC5008.sol";
-
-contract ERC5008Demo is ERC5008{
-
- constructor(string memory name_, string memory symbol_)ERC5008(name_, symbol_){
- }
-
- /// @notice mint a new NFT
- /// @param to The owner of the new token
- /// @param tokenId The id of the new token
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5008/contracts/IERC5008.sol b/assets/eip-5008/contracts/IERC5008.sol
deleted file mode 100644
index 2dff84c..0000000
--- a/assets/eip-5008/contracts/IERC5008.sol
+++ /dev/null
@@ -1,10 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC5008 /* is IERC165 */ {
- /// @notice Get the nonce of an NFT
- /// Throws if `tokenId` is not a valid NFT
- /// @param tokenId The id of the NFT
- /// @return The nonce of the NFT
- function nonce(uint256 tokenId) external view returns(uint256);
-}
diff --git a/assets/eip-5008/hardhat.config.ts b/assets/eip-5008/hardhat.config.ts
deleted file mode 100644
index 9b10629..0000000
--- a/assets/eip-5008/hardhat.config.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { HardhatUserConfig, task } from "hardhat/config";
-import "@nomiclabs/hardhat-waffle";
-import "@typechain/hardhat";
-
-// This is a sample Hardhat task. To learn how to create your own go to
-// https://hardhat.org/guides/create-task.html
-task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
- const accounts = await hre.ethers.getSigners();
-
- for (const account of accounts) {
- console.log(account.address);
- }
-});
-
-
-const config: HardhatUserConfig = {
- solidity: {
- version: "0.8.9",
- settings: {
- optimizer: {
- enabled: true,
- runs: 200
- }
- }
- },
-
-};
-
-
-
-export default config;
diff --git a/assets/eip-5008/package.json b/assets/eip-5008/package.json
deleted file mode 100644
index 4bdee48..0000000
--- a/assets/eip-5008/package.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "name": "EIP-5008",
- "dependencies": {
- "@openzeppelin/contracts": "^4.7.3",
- "@nomiclabs/hardhat-ethers": "^2.0.5",
- "@nomiclabs/hardhat-waffle": "^2.0.3",
- "@typechain/ethers-v5": "^7.2.0",
- "@typechain/hardhat": "^2.3.1",
- "@types/chai": "^4.3.0",
- "@types/mocha": "^9.1.0",
- "@types/node": "^12.20.47",
- "chai": "^4.3.6",
- "ethers": "^5.6.1",
- "hardhat": "^2.9.2",
- "solhint": "^3.3.7",
- "ts-node": "^10.8.1",
- "typechain": "^5.2.0",
- "typescript": "^4.6.3"
- }
-}
diff --git a/assets/eip-5008/test/test.ts b/assets/eip-5008/test/test.ts
deleted file mode 100644
index 22f272c..0000000
--- a/assets/eip-5008/test/test.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import { expect } from "chai";
-import { ethers } from "hardhat";
-
-describe("Test ERC5008 ", function () {
-
- it("test nonce", async function () {
- let [alice, bob] = await ethers.getSigners();
-
- const ERC5008Demo = await ethers.getContractFactory("ERC5008Demo");
-
- let contract = await ERC5008Demo.deploy("ERC5008Demo","ERC5008Demo");
-
- let tokenId = 1;
- await contract.mint(alice.address, tokenId);
-
- expect(await contract.nonce(tokenId)).equals(1);
-
- await contract.transferFrom(alice.address, bob.address, tokenId);
-
- expect(await contract.nonce(tokenId)).equals(2);
- });
-});
diff --git a/assets/eip-5008/tsconfig.json b/assets/eip-5008/tsconfig.json
deleted file mode 100644
index c458030..0000000
--- a/assets/eip-5008/tsconfig.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2018",
- "module": "commonjs",
- "strict": false,
- "esModuleInterop": true,
- "outDir": "dist",
- "declaration": true
- },
- "include": ["./test", "./typechain"],
- "files": ["./hardhat.config.ts"]
-}
diff --git a/assets/eip-5027/0001-unlimit-code-size.patch b/assets/eip-5027/0001-unlimit-code-size.patch
deleted file mode 100644
index 756bc32..0000000
--- a/assets/eip-5027/0001-unlimit-code-size.patch
+++ /dev/null
@@ -1,500 +0,0 @@
-From 7b8d4d1b8e00c0515ead0abb3f556e2b5a0617a7 Mon Sep 17 00:00:00 2001
-From: Qi Zhou
-Date: Thu, 21 Apr 2022 11:35:27 -0700
-Subject: [PATCH] unlimit code size with cold/warm storage
-
----
- core/rawdb/accessors_state.go | 18 +++++++
- core/rawdb/schema.go | 6 +++
- core/state/access_list.go | 32 +++++++++++-
- core/state/database.go | 6 +++
- core/state/journal.go | 11 ++++
- core/state/statedb.go | 23 ++++++--
- core/vm/eips.go | 20 +++++++
- core/vm/evm.go | 8 +--
- core/vm/interface.go | 2 +
- core/vm/operations_acl.go | 98 +++++++++++++++++++++++++++++++++++
- params/protocol_params.go | 10 ++--
- 11 files changed, 221 insertions(+), 13 deletions(-)
-
-diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go
-index 41e21b6ca..ad7fc150d 100644
---- a/core/rawdb/accessors_state.go
-+++ b/core/rawdb/accessors_state.go
-@@ -17,6 +17,8 @@
- package rawdb
-
- import (
-+ "encoding/binary"
-+
- "github.com/ethereum/go-ethereum/common"
- "github.com/ethereum/go-ethereum/ethdb"
- "github.com/ethereum/go-ethereum/log"
-@@ -48,6 +50,16 @@ func ReadCodeWithPrefix(db ethdb.KeyValueReader, hash common.Hash) []byte {
- return data
- }
-
-+// ReadCodeSize retrieves the contract code size of the provided code hash.
-+// Return 0 if not found
-+func ReadCodeSize(db ethdb.KeyValueReader, hash common.Hash) int {
-+ data, _ := db.Get(codeSizeKey(hash))
-+ if len(data) != 4 {
-+ return 0
-+ }
-+ return int(binary.BigEndian.Uint32(data))
-+}
-+
- // ReadTrieNode retrieves the trie node of the provided hash.
- func ReadTrieNode(db ethdb.KeyValueReader, hash common.Hash) []byte {
- data, _ := db.Get(hash.Bytes())
-@@ -96,6 +108,12 @@ func WriteCode(db ethdb.KeyValueWriter, hash common.Hash, code []byte) {
- if err := db.Put(codeKey(hash), code); err != nil {
- log.Crit("Failed to store contract code", "err", err)
- }
-+
-+ var sizeData [4]byte
-+ binary.BigEndian.PutUint32(sizeData[:], uint32(len(code)))
-+ if err := db.Put(codeSizeKey(hash), sizeData[:]); err != nil {
-+ log.Crit("Failed to store contract code size", "err", err)
-+ }
- }
-
- // WriteTrieNode writes the provided trie node database.
-diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go
-index 08f373488..cbf1dc40f 100644
---- a/core/rawdb/schema.go
-+++ b/core/rawdb/schema.go
-@@ -96,6 +96,7 @@ var (
- SnapshotStoragePrefix = []byte("o") // SnapshotStoragePrefix + account hash + storage hash -> storage trie value
- CodePrefix = []byte("c") // CodePrefix + code hash -> account code
- skeletonHeaderPrefix = []byte("S") // skeletonHeaderPrefix + num (uint64 big endian) -> header
-+ CodeSizePrefix = []byte("s") // CodePrefixSize
-
- PreimagePrefix = []byte("secure-key-") // PreimagePrefix + hash -> preimage
- configPrefix = []byte("ethereum-config-") // config prefix for the db
-@@ -230,6 +231,11 @@ func codeKey(hash common.Hash) []byte {
- return append(CodePrefix, hash.Bytes()...)
- }
-
-+// codeSizekey = CodeSizePreifx + hash
-+func codeSizeKey(hash common.Hash) []byte {
-+ return append(CodeSizePrefix, hash.Bytes()...)
-+}
-+
- // IsCodeKey reports whether the given byte slice is the key of contract code,
- // if so return the raw code hash as well.
- func IsCodeKey(key []byte) (bool, []byte) {
-diff --git a/core/state/access_list.go b/core/state/access_list.go
-index 419469134..22812a936 100644
---- a/core/state/access_list.go
-+++ b/core/state/access_list.go
-@@ -21,8 +21,9 @@ import (
- )
-
- type accessList struct {
-- addresses map[common.Address]int
-- slots []map[common.Hash]struct{}
-+ addresses map[common.Address]int
-+ codeInAddresses map[common.Address]bool
-+ slots []map[common.Hash]struct{}
- }
-
- // ContainsAddress returns true if the address is in the access list.
-@@ -31,6 +32,12 @@ func (al *accessList) ContainsAddress(address common.Address) bool {
- return ok
- }
-
-+// ContainsAddress returns true if the address is in the access list.
-+func (al *accessList) ContainsAddressCode(address common.Address) bool {
-+ _, ok := al.codeInAddresses[address]
-+ return ok
-+}
-+
- // Contains checks if a slot within an account is present in the access list, returning
- // separate flags for the presence of the account and the slot respectively.
- func (al *accessList) Contains(address common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
-@@ -60,6 +67,9 @@ func (a *accessList) Copy() *accessList {
- for k, v := range a.addresses {
- cp.addresses[k] = v
- }
-+ for k, v := range a.codeInAddresses {
-+ cp.codeInAddresses[k] = v
-+ }
- cp.slots = make([]map[common.Hash]struct{}, len(a.slots))
- for i, slotMap := range a.slots {
- newSlotmap := make(map[common.Hash]struct{}, len(slotMap))
-@@ -81,6 +91,16 @@ func (al *accessList) AddAddress(address common.Address) bool {
- return true
- }
-
-+// AddAddressCode adds the code of an address to the access list, and returns 'true' if the operation
-+// caused a change (addr was not previously in the list).
-+func (al *accessList) AddAddressCode(address common.Address) bool {
-+ if _, present := al.codeInAddresses[address]; present {
-+ return false
-+ }
-+ al.codeInAddresses[address] = true
-+ return true
-+}
-+
- // AddSlot adds the specified (addr, slot) combo to the access list.
- // Return values are:
- // - address added
-@@ -134,3 +154,11 @@ func (al *accessList) DeleteSlot(address common.Address, slot common.Hash) {
- func (al *accessList) DeleteAddress(address common.Address) {
- delete(al.addresses, address)
- }
-+
-+// DeleteAddressCode removes the code of an address from the access list. This operation
-+// needs to be performed in the same order as the addition happened.
-+// This method is meant to be used by the journal, which maintains ordering of
-+// operations.
-+func (al *accessList) DeleteAddressCode(address common.Address) {
-+ delete(al.codeInAddresses, address)
-+}
-diff --git a/core/state/database.go b/core/state/database.go
-index bbcd2358e..7445e627f 100644
---- a/core/state/database.go
-+++ b/core/state/database.go
-@@ -194,6 +194,12 @@ func (db *cachingDB) ContractCodeSize(addrHash, codeHash common.Hash) (int, erro
- if cached, ok := db.codeSizeCache.Get(codeHash); ok {
- return cached.(int), nil
- }
-+
-+ size := rawdb.ReadCodeSize(db.db.DiskDB(), codeHash)
-+ if size != 0 {
-+ return size, nil
-+ }
-+
- code, err := db.ContractCode(addrHash, codeHash)
- return len(code), err
- }
-diff --git a/core/state/journal.go b/core/state/journal.go
-index 57a692dc7..8e2250dde 100644
---- a/core/state/journal.go
-+++ b/core/state/journal.go
-@@ -134,6 +134,9 @@ type (
- accessListAddAccountChange struct {
- address *common.Address
- }
-+ accessListAddAccountCodeChange struct {
-+ address *common.Address
-+ }
- accessListAddSlotChange struct {
- address *common.Address
- slot *common.Hash
-@@ -260,6 +263,14 @@ func (ch accessListAddAccountChange) dirtied() *common.Address {
- return nil
- }
-
-+func (ch accessListAddAccountCodeChange) revert(s *StateDB) {
-+ s.accessList.DeleteAddressCode(*ch.address)
-+}
-+
-+func (ch accessListAddAccountCodeChange) dirtied() *common.Address {
-+ return nil
-+}
-+
- func (ch accessListAddSlotChange) revert(s *StateDB) {
- s.accessList.DeleteSlot(*ch.address, *ch.slot)
- }
-diff --git a/core/state/statedb.go b/core/state/statedb.go
-index 1d31cf470..d95dd79aa 100644
---- a/core/state/statedb.go
-+++ b/core/state/statedb.go
-@@ -984,11 +984,11 @@ func (s *StateDB) Commit(deleteEmptyObjects bool) (common.Hash, error) {
- }
-
- // PrepareAccessList handles the preparatory steps for executing a state transition with
--// regards to both EIP-2929 and EIP-2930:
-+// regards to both EIP-2929, EIP-2930, and EIP-5027:
- //
--// - Add sender to access list (2929)
--// - Add destination to access list (2929)
--// - Add precompiles to access list (2929)
-+// - Add sender to access list (2929, 5027)
-+// - Add destination to access list (2929, 5027)
-+// - Add precompiles to access list (2929, 5027)
- // - Add the contents of the optional tx access list (2930)
- //
- // This method should only be called if Berlin/2929+2930 is applicable at the current number.
-@@ -997,12 +997,15 @@ func (s *StateDB) PrepareAccessList(sender common.Address, dst *common.Address,
- s.accessList = newAccessList()
-
- s.AddAddressToAccessList(sender)
-+ s.AddAddressCodeToAccessList(sender)
- if dst != nil {
- s.AddAddressToAccessList(*dst)
-+ s.AddAddressCodeToAccessList(*dst)
- // If it's a create-tx, the destination will be added inside evm.create
- }
- for _, addr := range precompiles {
- s.AddAddressToAccessList(addr)
-+ s.AddAddressCodeToAccessList(addr)
- }
- for _, el := range list {
- s.AddAddressToAccessList(el.Address)
-@@ -1019,6 +1022,13 @@ func (s *StateDB) AddAddressToAccessList(addr common.Address) {
- }
- }
-
-+// AddAddressCodeToAccessList adds the given address to the access list
-+func (s *StateDB) AddAddressCodeToAccessList(addr common.Address) {
-+ if s.accessList.AddAddressCode(addr) {
-+ s.journal.append(accessListAddAccountCodeChange{&addr})
-+ }
-+}
-+
- // AddSlotToAccessList adds the given (address, slot)-tuple to the access list
- func (s *StateDB) AddSlotToAccessList(addr common.Address, slot common.Hash) {
- addrMod, slotMod := s.accessList.AddSlot(addr, slot)
-@@ -1042,6 +1052,11 @@ func (s *StateDB) AddressInAccessList(addr common.Address) bool {
- return s.accessList.ContainsAddress(addr)
- }
-
-+// AddressCodeInAccessList returns true if the given address's code is in the access list.
-+func (s *StateDB) AddressCodeInAccessList(addr common.Address) bool {
-+ return s.accessList.ContainsAddressCode(addr)
-+}
-+
- // SlotInAccessList returns true if the given (address, slot)-tuple is in the access list.
- func (s *StateDB) SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) {
- return s.accessList.Contains(addr, slot)
-diff --git a/core/vm/eips.go b/core/vm/eips.go
-index 4070a2db5..e9a8ee78c 100644
---- a/core/vm/eips.go
-+++ b/core/vm/eips.go
-@@ -31,6 +31,7 @@ var activators = map[int]func(*JumpTable){
- 2200: enable2200,
- 1884: enable1884,
- 1344: enable1344,
-+ 5027: enable5027,
- }
-
- // EnableEIP enables the given EIP on the config.
-@@ -147,6 +148,25 @@ func enable2929(jt *JumpTable) {
- jt[SELFDESTRUCT].dynamicGas = gasSelfdestructEIP2929
- }
-
-+// enable2929 enables "EIP-2929: Gas cost increases for state access opcodes"
-+// https://eips.ethereum.org/EIPS/eip-2929
-+func enable5027(jt *JumpTable) {
-+ jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929
-+ jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP5027
-+
-+ jt[CALL].constantGas = params.WarmStorageReadCostEIP2929
-+ jt[CALL].dynamicGas = gasCallEIP5027
-+
-+ jt[CALLCODE].constantGas = params.WarmStorageReadCostEIP2929
-+ jt[CALLCODE].dynamicGas = gasCallCodeEIP5027
-+
-+ jt[STATICCALL].constantGas = params.WarmStorageReadCostEIP2929
-+ jt[STATICCALL].dynamicGas = gasStaticCallEIP5027
-+
-+ jt[DELEGATECALL].constantGas = params.WarmStorageReadCostEIP2929
-+ jt[DELEGATECALL].dynamicGas = gasDelegateCallEIP5027
-+}
-+
- // enable3529 enabled "EIP-3529: Reduction in refunds":
- // - Removes refunds for selfdestructs
- // - Reduces refunds for SSTORE
-diff --git a/core/vm/evm.go b/core/vm/evm.go
-index dd55618bf..99e57c28e 100644
---- a/core/vm/evm.go
-+++ b/core/vm/evm.go
-@@ -421,6 +421,8 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
- // the access-list change should not be rolled back
- if evm.chainRules.IsBerlin {
- evm.StateDB.AddAddressToAccessList(address)
-+ // TODO: check shanghai
-+ evm.StateDB.AddAddressCodeToAccessList(address)
- }
- // Ensure there's no existing contract already at the designated address
- contractHash := evm.StateDB.GetCodeHash(address)
-@@ -453,9 +455,9 @@ func (evm *EVM) create(caller ContractRef, codeAndHash *codeAndHash, gas uint64,
- ret, err := evm.interpreter.Run(contract, nil, false)
-
- // Check whether the max code size has been exceeded, assign err if the case.
-- if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
-- err = ErrMaxCodeSizeExceeded
-- }
-+ // if err == nil && evm.chainRules.IsEIP158 && len(ret) > params.MaxCodeSize {
-+ // err = ErrMaxCodeSizeExceeded
-+ // }
-
- // Reject code starting with 0xEF if EIP-3541 is enabled.
- if err == nil && len(ret) >= 1 && ret[0] == 0xEF && evm.chainRules.IsLondon {
-diff --git a/core/vm/interface.go b/core/vm/interface.go
-index ad9b05d66..12660dd08 100644
---- a/core/vm/interface.go
-+++ b/core/vm/interface.go
-@@ -59,6 +59,7 @@ type StateDB interface {
-
- PrepareAccessList(sender common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList)
- AddressInAccessList(addr common.Address) bool
-+ AddressCodeInAccessList(addr common.Address) bool
- SlotInAccessList(addr common.Address, slot common.Hash) (addressOk bool, slotOk bool)
- // AddAddressToAccessList adds the given address to the access list. This operation is safe to perform
- // even if the feature/fork is not active yet
-@@ -66,6 +67,7 @@ type StateDB interface {
- // AddSlotToAccessList adds the given (address,slot) to the access list. This operation is safe to perform
- // even if the feature/fork is not active yet
- AddSlotToAccessList(addr common.Address, slot common.Hash)
-+ AddAddressCodeToAccessList(addr common.Address)
-
- RevertToSnapshot(int)
- Snapshot() int
-diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go
-index 551e1f5f1..cb76a4390 100644
---- a/core/vm/operations_acl.go
-+++ b/core/vm/operations_acl.go
-@@ -138,6 +138,41 @@ func gasExtCodeCopyEIP2929(evm *EVM, contract *Contract, stack *Stack, mem *Memo
- return gas, nil
- }
-
-+// gasExtCodeCopyEIP5027 implements extcodecopy according to EIP-5027
-+// EIP spec:
-+// > If the target is not in accessed_addresses,
-+// > charge COLD_ACCOUNT_ACCESS_COST * N_CODE_UNIT gas, and add the address to accessed_addresses and accessed_code_in_addresses.
-+// > Else if the target is not in accessed_code_in_addresses,
-+// > charge COLD_ACCOUNT_ACCESS_COST * (N_CODE_UNIT - 1) gas, and add the address to accessed_code_in_addresses.
-+// > Otherwise, charge WARM_STORAGE_READ_COST gas.
-+func gasExtCodeCopyEIP5027(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
-+ // memory expansion first (dynamic part of pre-5027 implementation)
-+ gas, err := gasExtCodeCopy(evm, contract, stack, mem, memorySize)
-+ if err != nil {
-+ return 0, err
-+ }
-+ addr := common.Address(stack.peek().Bytes20())
-+ // Check slot presence in the access list
-+ if !evm.StateDB.AddressInAccessList(addr) {
-+ evm.StateDB.AddAddressToAccessList(addr)
-+ var overflow bool
-+ // We charge (cold-warm), since 'warm' is already charged as constantGas
-+ if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929-params.WarmStorageReadCostEIP2929); overflow {
-+ return 0, ErrGasUintOverflow
-+ }
-+ }
-+ if !evm.StateDB.AddressCodeInAccessList(addr) {
-+ evm.StateDB.AddAddressCodeToAccessList(addr)
-+ var overflow bool
-+
-+ // We charge cold for extra code
-+ if gas, overflow = math.SafeAdd(gas, params.ColdAccountAccessCostEIP2929*getExtraCodeUnit(evm, addr)); overflow {
-+ return 0, ErrGasUintOverflow
-+ }
-+ }
-+ return gas, nil
-+}
-+
- // gasEip2929AccountCheck checks whether the first stack item (as address) is present in the access list.
- // If it is, this method returns '0', otherwise 'cold-warm' gas, presuming that the opcode using it
- // is also using 'warm' as constant factor.
-@@ -191,6 +226,64 @@ func makeCallVariantGasCallEIP2929(oldCalculator gasFunc) gasFunc {
- }
- }
-
-+func getExtraCodeUnit(evm *EVM, addr common.Address) uint64 {
-+ codeSize := evm.StateDB.GetCodeSize(addr)
-+ extraCodeUnit := uint64(0)
-+ if codeSize > params.CodeSizeUnit {
-+ extraCodeUnit = (uint64(codeSize - 1)) / params.CodeSizeUnit
-+ }
-+ return extraCodeUnit
-+}
-+
-+func makeCallVariantGasCallEIP5027(oldCalculator gasFunc) gasFunc {
-+ return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
-+ addr := common.Address(stack.Back(1).Bytes20())
-+ // Check slot presence in the access list
-+ warmAccess := evm.StateDB.AddressInAccessList(addr)
-+ warmCodeAccess := evm.StateDB.AddressCodeInAccessList(addr)
-+ // The WarmStorageReadCostEIP2929 (100) is already deducted in the form of a constant cost, so
-+ // the cost to charge for cold access, if any, is n * Cold - Warm
-+ coldCost := params.ColdAccountAccessCostEIP2929 - params.WarmStorageReadCostEIP2929
-+
-+ if !warmAccess {
-+ evm.StateDB.AddAddressToAccessList(addr)
-+ evm.StateDB.AddAddressCodeToAccessList(addr)
-+
-+ coldCost += getExtraCodeUnit(evm, addr) * params.ColdAccountCodeAccessCostEIP5027
-+
-+ // Charge the remaining difference here already, to correctly calculate available
-+ // gas for call
-+ if !contract.UseGas(coldCost) {
-+ return 0, ErrOutOfGas
-+ }
-+ } else if !warmCodeAccess {
-+ evm.StateDB.AddAddressCodeToAccessList(addr)
-+
-+ coldCost = getExtraCodeUnit(evm, addr) * params.ColdAccountCodeAccessCostEIP5027
-+ // Charge the remaining difference here already, to correctly calculate available
-+ // gas for call
-+ if !contract.UseGas(coldCost) {
-+ return 0, ErrOutOfGas
-+ }
-+ }
-+ // Now call the old calculator, which takes into account
-+ // - create new account
-+ // - transfer value
-+ // - memory expansion
-+ // - 63/64ths rule
-+ gas, err := oldCalculator(evm, contract, stack, mem, memorySize)
-+ if (warmAccess && warmCodeAccess) || err != nil {
-+ return gas, err
-+ }
-+ // In case of a cold access, we temporarily add the cold charge back, and also
-+ // add it to the returned gas. By adding it to the return, it will be charged
-+ // outside of this function, as part of the dynamic gas, and that will make it
-+ // also become correctly reported to tracers.
-+ contract.Gas += coldCost
-+ return gas + coldCost, nil
-+ }
-+}
-+
- var (
- gasCallEIP2929 = makeCallVariantGasCallEIP2929(gasCall)
- gasDelegateCallEIP2929 = makeCallVariantGasCallEIP2929(gasDelegateCall)
-@@ -200,6 +293,11 @@ var (
- // gasSelfdestructEIP3529 implements the changes in EIP-2539 (no refunds)
- gasSelfdestructEIP3529 = makeSelfdestructGasFn(false)
-
-+ gasCallEIP5027 = makeCallVariantGasCallEIP5027(gasCall)
-+ gasDelegateCallEIP5027 = makeCallVariantGasCallEIP5027(gasDelegateCall)
-+ gasStaticCallEIP5027 = makeCallVariantGasCallEIP5027(gasStaticCall)
-+ gasCallCodeEIP5027 = makeCallVariantGasCallEIP5027(gasCallCode)
-+
- // gasSStoreEIP2929 implements gas cost for SSTORE according to EIP-2929
- //
- // When calling SSTORE, check if the (address, storage_key) pair is in accessed_storage_keys.
-diff --git a/params/protocol_params.go b/params/protocol_params.go
-index 5f154597a..c3d5c66ce 100644
---- a/params/protocol_params.go
-+++ b/params/protocol_params.go
-@@ -58,9 +58,11 @@ const (
- SstoreResetGasEIP2200 uint64 = 5000 // Once per SSTORE operation from clean non-zero to something else
- SstoreClearsScheduleRefundEIP2200 uint64 = 15000 // Once per SSTORE operation for clearing an originally existing storage slot
-
-- ColdAccountAccessCostEIP2929 = uint64(2600) // COLD_ACCOUNT_ACCESS_COST
-- ColdSloadCostEIP2929 = uint64(2100) // COLD_SLOAD_COST
-- WarmStorageReadCostEIP2929 = uint64(100) // WARM_STORAGE_READ_COST
-+ ColdAccountAccessCostEIP2929 = uint64(2600) // COLD_ACCOUNT_ACCESS_COST
-+ ColdSloadCostEIP2929 = uint64(2100) // COLD_SLOAD_COST
-+ WarmStorageReadCostEIP2929 = uint64(100) // WARM_STORAGE_READ_COST
-+ ColdAccountCodeAccessCostEIP5027 = uint64(2600) // COLD_ACCOUNT_CODE_ACCESS_COST_PER_UNIT
-+ WarmAccountCodeAccessCostEIP5027 = uint64(2600) // WARM_ACCOUNT_CODE_ACCESS_COST_PER_UNIT
-
- // In EIP-2200: SstoreResetGas was 5000.
- // In EIP-2929: SstoreResetGas was changed to '5000 - COLD_SLOAD_COST'.
-@@ -123,7 +125,7 @@ const (
- ElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
- InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
-
-- MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
-+ CodeSizeUnit = 24576 // Code size unit for gas metering.
-
- // Precompiled contract gas prices
-
---
-2.30.1 (Apple Git-130)
-
diff --git a/assets/eip-5050/ActionsSet.sol b/assets/eip-5050/ActionsSet.sol
deleted file mode 100644
index 36be830..0000000
--- a/assets/eip-5050/ActionsSet.sol
+++ /dev/null
@@ -1,134 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Based on OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)
-
-pragma solidity ^0.8.0;
-
-library ActionsSet {
- struct Set {
- // Storage of action names
- string[] _names;
- // Storage of action selectors
- bytes4[] _selectors;
- // Position of the value in the `values` array, plus 1 because index 0
- // means a value is not in the set.
- mapping(bytes4 => uint256) _indexes;
- }
-
- /**
- * @dev Add a value to a set. O(1).
- *
- * Returns true if the value was added to the set, that is if it was not
- * already present.
- */
- function add(Set storage set, string memory name) internal returns (bool) {
- bytes4 selector = bytes4(keccak256(bytes(name)));
- if (!contains(set, selector)) {
- set._selectors.push(selector);
- set._names.push(name);
- // The value is stored at length-1, but we add 1 to all indexes
- // and use 0 as a sentinel value
- set._indexes[selector] = set._selectors.length;
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * @dev Removes a value from a set. O(1).
- *
- * Returns true if the value was removed from the set, that is if it was
- * present.
- */
- function remove(Set storage set, bytes4 value) internal returns (bool) {
- // We read and store the value's index to prevent multiple reads from the same storage slot
- uint256 valueIndex = set._indexes[value];
-
- if (valueIndex != 0) {
- // Equivalent to contains(set, value)
- // To delete an element from the _selectors array in O(1), we swap the element to delete with the last one in
- // the array, and then remove the last element (sometimes called as 'swap and pop').
- // This modifies the order of the array, as noted in {at}.
-
- uint256 toDeleteIndex = valueIndex - 1;
- uint256 lastIndex = set._selectors.length - 1;
-
- if (lastIndex != toDeleteIndex) {
- bytes4 lastValue = set._selectors[lastIndex];
-
- // Move the last value to the index where the value to delete is
- set._selectors[toDeleteIndex] = lastValue;
- // Update the index for the moved value
- set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
- }
-
- // Delete the slot where the moved value was stored
- set._selectors.pop();
-
- // Delete the index for the deleted slot
- delete set._indexes[value];
-
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * @dev Returns true if the value is in the set. O(1).
- */
- function contains(Set storage set, bytes4 value)
- internal
- view
- returns (bool)
- {
- return set._indexes[value] != 0;
- }
-
- /**
- * @dev Returns the number of values on the set. O(1).
- */
- function length(Set storage set) internal view returns (uint256) {
- return set._selectors.length;
- }
-
- /**
- * @dev Returns the value stored at position `index` in the set. O(1).
- *
- * Note that there are no guarantees on the ordering of values inside the
- * array, and it may change when more values are added or removed.
- *
- * Requirements:
- *
- * - `index` must be strictly less than {length}.
- */
- function at(Set storage set, uint256 index) internal view returns (bytes4) {
- return set._selectors[index];
- }
-
- /**
- * @dev Return the entire set of action names
- *
- * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
- * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
- * this function has an unbounded cost, and using it as part of a state-changing function may render the function
- * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
- */
- function names(Set storage set) internal view returns (string[] memory) {
- return set._names;
- }
-
- /**
- * @dev Return the entire set of action selectors
- *
- * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
- * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
- * this function has an unbounded cost, and using it as part of a state-changing function may render the function
- * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
- */
- function selectors(Set storage set) internal view returns (bytes4[] memory) {
- return set._selectors;
- }
-
-
-}
diff --git a/assets/eip-5050/ERC5050.sol b/assets/eip-5050/ERC5050.sol
deleted file mode 100644
index e2608d9..0000000
--- a/assets/eip-5050/ERC5050.sol
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./ERC5050Sender.sol";
-import "./ERC5050Receiver.sol";
-
-contract ERC5050 is ERC5050Sender, ERC5050Receiver {
- function _registerAction(bytes4 action) internal {
- _registerReceivable(action);
- _registerSendable(action);
- }
-}
diff --git a/assets/eip-5050/ERC5050Receiver.sol b/assets/eip-5050/ERC5050Receiver.sol
deleted file mode 100644
index 254d01d..0000000
--- a/assets/eip-5050/ERC5050Receiver.sol
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import {IERC5050Sender, IERC5050Receiver, Action} from "./IERC5050.sol";
-import {ActionsSet} from "./ActionsSet.sol";
-
-contract ERC5050Receiver is IERC5050Receiver {
- using ActionsSet for ActionsSet.Set;
-
- ActionsSet.Set _receivableActions;
-
- modifier onlyReceivableAction(Action calldata action, uint256 nonce) {
- require(
- action.to._address == address(this),
- "ERC5050: invalid receiver"
- );
- require(
- _receivableActions.contains(action.selector),
- "ERC5050: invalid action"
- );
- require(
- action.from._address == address(0) ||
- action.from._address == msg.sender,
- "ERC5050: invalid sender"
- );
- require(
- (action.from._address != address(0) && action.user == tx.origin) ||
- action.user == msg.sender,
- "ERC5050: invalid sender"
- );
- _;
- }
-
- function receivableActions() external view returns (string[] memory) {
- return _receivableActions.names();
- }
-
- function onActionReceived(Action calldata action, uint256 nonce)
- external
- payable
- virtual
- override
- onlyReceivableAction(action, nonce)
- {
- _onActionReceived(action, nonce);
- }
-
- function _onActionReceived(Action calldata action, uint256 nonce)
- internal
- virtual
- {
- if (action.state != address(0)) {
- require(action.state.isContract(), "ERC5050: invalid state");
- try
- IERC5050Receiver(action.state).onActionReceived{
- value: msg.value
- }(action, nonce)
- {} catch (bytes memory reason) {
- if (reason.length == 0) {
- revert("ERC5050: call to non ERC5050Receiver");
- } else {
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- }
- emit ActionReceived(
- action.selector,
- action.user,
- action.from._address,
- action.from._tokenId,
- action.to._address,
- action.to._tokenId,
- action.state,
- action.data
- );
- }
-
- function _registerReceivable(string memory action) internal {
- _receivableActions.add(action);
- }
-}
diff --git a/assets/eip-5050/ERC5050Sender.sol b/assets/eip-5050/ERC5050Sender.sol
deleted file mode 100644
index 3eb6730..0000000
--- a/assets/eip-5050/ERC5050Sender.sol
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import {IERC5050Sender, IERC5050Receiver, Action} from "./IERC5050.sol";
-import {ActionsSet} from "./ActionsSet.sol";
-
-contract ERC5050Sender is IERC5050Sender {
- using ActionsSet for ActionsSet.Set;
-
- ActionsSet.Set _sendableActions;
-
- uint256 private _nonce;
- bytes32 private _hash;
-
- mapping(address => mapping(bytes4 => address)) actionApprovals;
- mapping(address => mapping(address => bool)) operatorApprovals;
-
- function sendAction(Action memory action)
- external
- payable
- virtual
- override
- {
- _sendAction(action);
- }
-
- function isValid(bytes32 actionHash, uint256 nonce)
- external
- view
- returns (bool)
- {
- return actionHash == _hash && nonce == _nonce;
- }
-
- function sendableActions() external view returns (string[] memory) {
- return _sendableActions.names();
- }
-
- modifier onlySendableAction(Action memory action) {
- require(
- _sendableActions.contains(action.selector),
- "ERC5050: invalid action"
- );
- require(
- _isApprovedOrSelf(action.user, action.selector),
- "ERC5050: unapproved sender"
- );
- _;
- }
-
- function approveForAction(
- address _account,
- bytes4 _action,
- address _approved
- ) public virtual override returns (bool) {
- require(_approved != _account, "ERC5050: approve to caller");
-
- require(
- msg.sender == _account ||
- isApprovedForAllActions(_account, msg.sender),
- "ERC5050: approve caller is not account nor approved for all"
- );
-
- actionApprovals[_account][_action] = _approved;
- emit ApprovalForAction(_account, _action, _approved);
-
- return true;
- }
-
- function setApprovalForAllActions(address _operator, bool _approved)
- public
- virtual
- override
- {
- require(msg.sender != _operator, "ERC5050: approve to caller");
-
- operatorApprovals[msg.sender][_operator] = _approved;
-
- emit ApprovalForAllActions(msg.sender, _operator, _approved);
- }
-
- function getApprovedForAction(address _account, bytes4 _action)
- public
- view
- returns (address)
- {
- return actionApprovals[_account][_action];
- }
-
- function isApprovedForAllActions(address _account, address _operator)
- public
- view
- returns (bool)
- {
- return operatorApprovals[_account][_operator];
- }
-
- function _sendAction(Action memory action) internal {
- action.from._address = address(this);
- bool toIsContract = action.to._address.isContract();
- bool stateIsContract = action.state.isContract();
- address next;
- if (toIsContract) {
- next = action.to._address;
- } else if (stateIsContract) {
- next = action.state;
- }
- uint256 nonce;
- if (toIsContract && stateIsContract) {
- _validate(action);
- nonce = _nonce;
- }
- if (next.isContract()) {
- try
- IERC5050Receiver(next).onActionReceived{value: msg.value}(
- action,
- nonce
- )
- {} catch Error(string memory err) {
- revert(err);
- } catch (bytes memory returnData) {
- if (returnData.length > 0) {
- revert(string(returnData));
- }
- }
- }
- emit SendAction(
- action.selector,
- action.user,
- action.from._address,
- action.from._tokenId,
- action.to._address,
- action.to._tokenId,
- action.state,
- action.data
- );
- }
-
- function _validate(Action memory action) internal {
- ++_nonce;
- _hash = bytes32(
- keccak256(
- abi.encodePacked(
- action.selector,
- action.user,
- action.from._address,
- action.from._tokenId,
- action.to._address,
- action.to._tokenId,
- action.state,
- action.data,
- _nonce
- )
- )
- );
- }
-
- function _isApprovedOrSelf(address account, bytes4 action)
- internal
- view
- returns (bool)
- {
- return (msg.sender == account ||
- isApprovedForAllActions(account, msg.sender) ||
- getApprovedForAction(account, action) == msg.sender);
- }
-
- function _registerSendable(string memory action) internal {
- _sendableActions.add(action);
- }
-}
diff --git a/assets/eip-5050/ERC5050State.sol b/assets/eip-5050/ERC5050State.sol
deleted file mode 100644
index 55567a3..0000000
--- a/assets/eip-5050/ERC5050State.sol
+++ /dev/null
@@ -1,104 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import {IERC5050Sender, IERC5050Receiver, Action} from "./IERC5050.sol";
-import {ActionsSet} from "./ActionsSet.sol";
-
-contract ERC5050State is IERC5050Receiver {
- using ActionsSet for ActionsSet.Set;
-
- ActionsSet.Set private _receivableActions;
-
- function onActionReceived(Action calldata action, uint256 nonce)
- external
- payable
- virtual
- override
- onlyReceivableAction(action, nonce)
- {
- _onActionReceived(action, nonce);
- }
-
- function receivableActions() external view returns (string[] memory) {
- return _receivableActions.names();
- }
-
- modifier onlyReceivableAction(Action calldata action, uint256 nonce) {
- require(
- _receivableActions.contains(action.selector),
- "ERC5050: invalid action"
- );
- require(action.state == address(this), "ERC5050: invalid state");
- require(
- action.user == address(0) || action.user == tx.origin,
- "ERC5050: invalid user"
- );
-
- address expectedSender = action.to._address;
- if (expectedSender == address(0)) {
- if (action.from._address != address(0)) {
- expectedSender = action.from._address;
- } else {
- expectedSender = action.user;
- }
- }
- require(msg.sender == expectedSender, "ERC5050: invalid sender");
-
- // State contracts must validate the action with the `from` contract in
- // the case of a 3-contract chain (`from`, `to` and `state`) all set to
- // valid contract addresses.
- if (
- action.to._address.isContract() && action.from._address.isContract()
- ) {
- uint256 actionHash = uint256(
- keccak256(
- abi.encodePacked(
- action.selector,
- action.user,
- action.from._address,
- action.from._tokenId,
- action.to._address,
- action.to._tokenId,
- action.state,
- action.data,
- nonce
- )
- )
- );
- try
- IERC5050Sender(action.from._address).isValid(actionHash, nonce)
- returns (bool ok) {
- require(ok, "ERC5050: action not validated");
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert("ERC5050: call to non ERC5050Sender");
- } else {
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- }
- _;
- }
-
- function _onActionReceived(Action calldata action, uint256 nonce)
- internal
- virtual
- {
- emit ActionReceived(
- action.selector,
- action.user,
- action.from._address,
- action.from._tokenId,
- action.to._address,
- action.to._tokenId,
- action.state,
- action.data
- );
- }
-
- function _registerReceivable(string memory action) internal {
- _receivableActions.add(action);
- }
-}
diff --git a/assets/eip-5050/ExampleStateContract.sol b/assets/eip-5050/ExampleStateContract.sol
deleted file mode 100644
index a609bc9..0000000
--- a/assets/eip-5050/ExampleStateContract.sol
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import {ERC5050State, Action} from "./ERC5050State.sol";
-import {ERC5050, Action} from "./ERC5050.sol";
-
-struct TokenInfo {
- uint256 health;
- uint256 healthRemaining;
- uint256 power;
- uint256 blockedAt;
- uint256 blockPower;
- uint256 lockedUntilBlock;
- uint256 wins;
- bool hasRegistered;
-}
-
-interface IFightGame {
- function getStats(address _contract, uint256 _tokenId) external view returns (TokenInfo);
-}
-
-contract FightGame is IFightGame, ERC5050State {
-
- bytes4 constant LIGHT_ATTACK_SELECTOR = bytes4(keccak256("fg.light-attack"));
- bytes4 constant HEAVY_ATTACK_SELECTOR = bytes4(keccak256("fg.heavy-attack"));
- bytes4 constant BLOCK_SELECTOR = bytes4(keccak256("fg.block"));
-
- uint256 constant BLOCK_DECAY = 100;
- uint256 constant LIGHT_ATTACK_DECAY = 200;
- uint256 constant HEAVY_ATTACK_DECAY = 500;
-
- mapping(address => mapping(uint256 => TokenInfo)) state;
-
- constructor() {
- _registerReceivable("fg.light-attack");
- _registerReceivable("fg.heavy-attack");
- _registerReceivable("fg.block");
- }
-
- function register(address _contract, uint256 _tokenId) external {
- require(msg.sender == ownerOf(_contract, _tokenId), "sender not token owner");
- require(!state[_contract][_tokenId].hasRegistered, "token already registered");
- state[_contract][_tokenId] = TokenInfo(100, 100, 5, 0, 0, 0, true);
- }
-
- function getStats(address _contract, uint256 _tokenId) external view returns (TokenInfo){
- return state[_contract][_tokenId];
- }
-
- function onActionReceived(Action calldata action, uint256 _nonce)
- external
- payable
- override
- onlyReceivableAction(action, _nonce)
- {
- TokenInfo storage from = state[action.from._address][action.from._tokenId];
- require(from.healthRemaining > 0, "health 0");
- require(block.number > from.lockedUntilBlock, "token locked");
- if (action.selector == BLOCK_SELECTOR) {
- from.blockPower = from.power * 3;
- from.blockedAt = block.number;
- from.lockedUntilBlock = block.number + BLOCK_DECAY;
- return;
- }
-
- TokenInfo storage to = state[action.to._address][action.to._tokenId];
- require(to.healthRemaining > 0, "target health 0");
-
- uint256 damage;
- if (action.selector == LIGHT_ATTACK_SELECTOR ) {
- damage = from.power;
- from.lockedUntilBlock = block.number + LIGHT_ATTACK_DECAY;
- }
-
- if (action.selector == HEAVY_ATTACK_SELECTOR) {
- damage = from.power * 3;
- from.lockedUntilBlock = block.number + HEAVY_ATTACK_DECAY;
- }
- if(to.blockedAt + BLOCK_DECAY > block.number) {
- if(to.blockPower >= damage){
- to.blockPower -= damage;
- return;
- }
- damage -= to.blockPower;
- }
- if(to.healthRemaining > damage){
- to.healthRemaining -= damage;
- return;
- }
-
- // Winner gains loser's power and some health
- from.power += to.power;
- from.healthRemaining += to.power;
- from.wins++;
- to.healthRemaining = 0;
- }
-}
-
-contract Fighter is ERC5050, ERC721 {
-
- IFightGame stateContract;
-
- constructor(address _stateContract) {
- _registerAction("fg.light-attack");
- _registerAction("fg.heavy-attack");
- _registerSendable("fg.block");
- stateContract = IFightGame(_stateContract);
- }
-
- // Update NFT render / metadata based on game stats
- function tokenURICharacterEmoji(uint256 tokenId)
- public
- view
- override
- returns (string memory)
- {
- TokenInfo memory stats = stateContract.getStats(address(this), tokenId);
- if(stats.healthRemaining == 0){
- return unicode"😵";
- }
- if(stats.power > 100){
- return unicode"🦾";
- }
- if(stats.power > 50){
- return unicode"💪";
- }
- if(stats.power > 20){
- return unicode"🤩";
- }
- if(stats.power > 5){
- return unicode"😃";
- }
- return unicode"😀";
- }
-}
\ No newline at end of file
diff --git a/assets/eip-5050/ExampleToken2Token.sol b/assets/eip-5050/ExampleToken2Token.sol
deleted file mode 100644
index 53e0b02..0000000
--- a/assets/eip-5050/ExampleToken2Token.sol
+++ /dev/null
@@ -1,105 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import {ERC5050, Action} from "./ERC5050.sol";
-
-contract Spells is ERC5050, ERC721 {
-
- bytes4 constant CAST_SELECTOR = bytes4(keccak256("cast"));
- bytes4 constant ATTUNE_SELECTOR = bytes4(keccak256("attune"));
-
- mapping(uint256 => uint256) spellDust;
- mapping(uint256 => string) attunement;
-
- constructor() ERC721("Spells", unicode"🔮") {
- _registerSendable("cast");
- _registerReceivable("attune");
- }
-
- function sendAction(Action memory action)
- external
- payable
- override
- onlySendableAction(action)
- {
- require(
- msg.sender == ownerOf(action.from._tokenId),
- "Spells: invalid sender"
- );
- _sendAction(action);
- }
-
- function onActionReceived(Action calldata action, uint256 _nonce)
- external
- payable
- override
- onlyReceivableAction(action, _nonce)
- {
- if (action.selector == ATTUNE_SELECTOR) {
- string memory unicodeChar;
- bytes memory _data = action.data;
- assembly {
- // Read unicode character from first 6 bytes (\u5050)
- unicodeChar := shr(208, _data)
- }
- attunement[action.to._tokenId] = unicodeChar;
- }
- // Pass action to state receiver if specified
- _onActionReceived(action, _nonce);
- }
-
- string[12] private dust = [
- unicode"․",
- unicode"∴",
- unicode"`"
- ];
-
- string[5] private spells = [
- "Conjuring",
- "Divining",
- "Transforming",
- "Hexing",
- "Banishing"
- ];
-
- function tokenURI(uint256 tokenId)
- public
- view
- override
- returns (string memory)
- {
- string
- memory out = '';
-
- out = string.concat(
- out,
- string.concat(spells[_spellType(tokenId)], " Spell"),
- ' ',
- attunement[tokenId]
- );
- out = string.concat(out, " ");
- string memory json = Base64.encode(
- bytes(
- string(
- abi.encodePacked(
- '{"name": "Spell #',
- Strings.toString(tokenId),
- '", "description": "Cast spells, attune spells.", "image": "data:image/svg+xml;base64,',
- Base64.encode(bytes(out)),
- '"}'
- )
- )
- )
- );
- return string(abi.encodePacked("data:application/json;base64,", json));
- }
-
- function _spellType(uint256 tokenId) internal pure returns (uint256) {
- uint256 rand = _random(Strings.toString(tokenId));
- return rand % 6;
- }
-
- function _random(string memory input) internal pure returns (uint256) {
- return uint256(keccak256(abi.encodePacked(input)));
- }
-}
\ No newline at end of file
diff --git a/assets/eip-5050/IERC5050.sol b/assets/eip-5050/IERC5050.sol
deleted file mode 100644
index 95cf778..0000000
--- a/assets/eip-5050/IERC5050.sol
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-/// @title ERC-xxxx Token Interaction Standard
-/// @dev See https://eips.ethereum.org/EIPS/eip-xxx
-interface IERC5050Sender {
- /// @notice Send an action to the target address
- /// @dev The action's `fromContract` is automatically set to `address(this)`,
- /// and the `from` parameter is set to `msg.sender`.
- /// @param action The action to send
- function sendAction(Action memory action) external payable;
-
- /// @notice Check if an action is valid based on its hash and nonce
- /// @dev When an action passes through all three possible contracts
- /// (`fromContract`, `to`, and `state`) the `state` contract validates the
- /// action with the initiating `fromContract` using a nonced action hash.
- /// This hash is calculated and saved to storage on the `fromContract` before
- /// action handling is initiated. The `state` contract calculates the hash
- /// and verifies it and nonce with the `fromContract`.
- /// @param _hash The hash to validate
- /// @param _nonce The nonce to validate
- function isValid(bytes32 _hash, uint256 _nonce) external returns (bool);
-
- /// @notice Retrieve list of actions that can be sent.
- /// @dev Intended for use by off-chain applications to query compatible contracts.
- function sendableActions() external view returns (string[] memory);
-
- /// @notice Change or reaffirm the approved address for an action
- /// @dev The zero address indicates there is no approved address.
- /// Throws unless `msg.sender` is the `_account`, or an authorized
- /// operator of the `_account`.
- /// @param _account The account of the account-action pair to approve
- /// @param _action The action of the account-action pair to approve
- /// @param _approved The new approved account-action controller
- function approveForAction(
- address _account,
- bytes4 _action,
- address _approved
- ) external returns (bool);
-
- /// @notice Enable or disable approval for a third party ("operator") to conduct
- /// all actions on behalf of `msg.sender`
- /// @dev Emits the ApprovalForAll event. The contract MUST allow
- /// multiple operators per owner.
- /// @param _operator Address to add to the set of authorized operators
- /// @param _approved True if the operator is approved, false to revoke approval
- function setApprovalForAllActions(address _operator, bool _approved)
- external;
-
- /// @notice Get the approved address for an account-action pair
- /// @dev Throws if `_tokenId` is not a valid NFT.
- /// @param _account The account of the account-action to find the approved address for
- /// @param _action The action of the account-action to find the approved address for
- /// @return The approved address for this account-action, or the zero address if
- /// there is none
- function getApprovedForAction(address _account, bytes4 _action)
- external
- view
- returns (address);
-
- /// @notice Query if an address is an authorized operator for another address
- /// @param _account The address on whose behalf actions are performed
- /// @param _operator The address that acts on behalf of the account
- /// @return True if `_operator` is an approved operator for `_account`, false otherwise
- function isApprovedForAllActions(address _account, address _operator)
- external
- view
- returns (bool);
-
- /// @dev This emits when an action is sent (`sendAction()`)
- event SendAction(
- bytes4 indexed name,
- address _from,
- address indexed _fromContract,
- uint256 _tokenId,
- address indexed _to,
- uint256 _toTokenId,
- address _state,
- bytes _data
- );
-
- /// @dev This emits when the approved address for an account-action pair
- /// is changed or reaffirmed. The zero address indicates there is no
- /// approved address.
- event ApprovalForAction(
- address indexed _account,
- bytes4 indexed _action,
- address indexed _approved
- );
-
- /// @dev This emits when an operator is enabled or disabled for an account.
- /// The operator can conduct all actions on behalf of the account.
- event ApprovalForAllActions(
- address indexed _account,
- address indexed _operator,
- bool _approved
- );
-}
-
-interface IERC5050Receiver {
- /// @notice Handle an action
- /// @dev Both the `to` contract and `state` contract are called via
- /// `onActionReceived()`.
- /// @param action The action to handle
- function onActionReceived(Action calldata action, uint256 _nonce)
- external
- payable;
-
- /// @notice Retrieve list of actions that can be received.
- /// @dev Intended for use by off-chain applications to query compatible contracts.
- function receivableActions() external view returns (string[] memory);
-
- /// @dev This emits when a valid action is received.
- event ActionReceived(
- bytes4 indexed name,
- address _from,
- address indexed _fromContract,
- uint256 _tokenId,
- address indexed _to,
- uint256 _toTokenId,
- address _state,
- bytes _data
- );
-}
-
-/// @param _address The address of the interactive object
-/// @param tokenId The token that is interacting (optional)
-struct Object {
- address _address;
- uint256 _tokenId;
-}
-
-/// @param name The name of the action
-/// @param user The address of the sender
-/// @param from The initiating object
-/// @param to The receiving object
-/// @param state The state contract
-/// @param data Additional data with no specified format
-struct Action {
- bytes4 selector;
- address user;
- Object from;
- Object to;
- address state;
- bytes data;
-}
diff --git a/assets/eip-5058/ERC5058.sol b/assets/eip-5058/ERC5058.sol
deleted file mode 100644
index 90fc3ef..0000000
--- a/assets/eip-5058/ERC5058.sol
+++ /dev/null
@@ -1,275 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC5058.sol";
-
-/**
- * @dev Implementation ERC721 Lockable Token
- */
-abstract contract ERC5058 is ERC721, IERC5058 {
- // Mapping from token ID to unlock time
- mapping(uint256 => uint256) public lockedTokens;
-
- // Mapping from token ID to lock approved address
- mapping(uint256 => address) private _lockApprovals;
-
- // Mapping from owner to lock operator approvals
- mapping(address => mapping(address => bool)) private _lockOperatorApprovals;
-
- /**
- * @dev See {IERC5058-lockApprove}.
- */
- function lockApprove(address to, uint256 tokenId) public virtual override {
- require(!isLocked(tokenId), "ERC5058: token is locked");
- address owner = ERC721.ownerOf(tokenId);
- require(to != owner, "ERC5058: lock approval to current owner");
-
- require(
- _msgSender() == owner || isLockApprovedForAll(owner, _msgSender()),
- "ERC5058: lock approve caller is not owner nor approved for all"
- );
-
- _lockApprove(owner, to, tokenId);
- }
-
- /**
- * @dev See {IERC5058-getLockApproved}.
- */
- function getLockApproved(uint256 tokenId) public view virtual override returns (address) {
- require(_exists(tokenId), "ERC5058: lock approved query for nonexistent token");
-
- return _lockApprovals[tokenId];
- }
-
- /**
- * @dev See {IERC5058-lockerOf}.
- */
- function lockerOf(uint256 tokenId) public view virtual override returns (address) {
- require(_exists(tokenId), "ERC5058: locker query for nonexistent token");
- require(isLocked(tokenId), "ERC5058: locker query for non-locked token");
-
- return _lockApprovals[tokenId];
- }
-
- /**
- * @dev See {IERC5058-setLockApprovalForAll}.
- */
- function setLockApprovalForAll(address operator, bool approved) public virtual override {
- _setLockApprovalForAll(_msgSender(), operator, approved);
- }
-
- /**
- * @dev See {IERC5058-isLockApprovedForAll}.
- */
- function isLockApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
- return _lockOperatorApprovals[owner][operator];
- }
-
- /**
- * @dev See {IERC5058-isLocked}.
- */
- function isLocked(uint256 tokenId) public view virtual override returns (bool) {
- return lockedTokens[tokenId] > block.number;
- }
-
- /**
- * @dev See {IERC5058-lockExpiredTime}.
- */
- function lockExpiredTime(uint256 tokenId) public view virtual override returns (uint256) {
- return lockedTokens[tokenId];
- }
-
- /**
- * @dev See {IERC5058-lock}.
- */
- function lock(uint256 tokenId, uint256 expired) public virtual override {
- //solhint-disable-next-line max-line-length
- require(_isLockApprovedOrOwner(_msgSender(), tokenId), "ERC5058: lock caller is not owner nor approved");
- require(expired > block.number, "ERC5058: expired time must be greater than current block number");
- require(!isLocked(tokenId), "ERC5058: token is locked");
-
- _lock(_msgSender(), tokenId, expired);
- }
-
- /**
- * @dev See {IERC5058-unlock}.
- */
- function unlock(uint256 tokenId) public virtual override {
- require(lockerOf(tokenId) == _msgSender(), "ERC5058: unlock caller is not lock operator");
-
- address from = ERC721.ownerOf(tokenId);
-
- _beforeTokenLock(_msgSender(), from, tokenId, 0);
-
- delete lockedTokens[tokenId];
-
- emit Unlocked(_msgSender(), from, tokenId);
-
- _afterTokenLock(_msgSender(), from, tokenId, 0);
- }
-
- /**
- * @dev Locks `tokenId` from `from` until `expired`.
- *
- * Requirements:
- *
- * - `tokenId` token must be owned by `from`.
- *
- * Emits a {Locked} event.
- */
- function _lock(
- address operator,
- uint256 tokenId,
- uint256 expired
- ) internal virtual {
- address owner = ERC721.ownerOf(tokenId);
-
- _beforeTokenLock(operator, owner, tokenId, expired);
-
- lockedTokens[tokenId] = expired;
- _lockApprovals[tokenId] = operator;
-
- emit Locked(operator, owner, tokenId, expired);
-
- _afterTokenLock(operator, owner, tokenId, expired);
- }
-
- /**
- * @dev Safely mints `tokenId` and transfers it to `to`, but the `tokenId` is locked and cannot be transferred.
- *
- * Requirements:
- *
- * - `tokenId` must not exist.
- *
- * Emits {Locked} and {Transfer} event.
- */
- function _safeLockMint(
- address to,
- uint256 tokenId,
- uint256 expired,
- bytes memory _data
- ) internal virtual {
- require(expired > block.number, "ERC5058: lock mint for invalid lock block number");
-
- _safeMint(to, tokenId, _data);
-
- _lock(_msgSender(), tokenId, expired);
- }
-
- /**
- * @dev See {ERC721-_burn}. This override additionally clears the lock approvals for the token.
- */
- function _burn(uint256 tokenId) internal virtual override {
- address owner = ERC721.ownerOf(tokenId);
- super._burn(tokenId);
-
- _beforeTokenLock(_msgSender(), owner, tokenId, 0);
-
- // clear lock approvals
- delete lockedTokens[tokenId];
- delete _lockApprovals[tokenId];
-
- _afterTokenLock(_msgSender(), owner, tokenId, 0);
- }
-
- /**
- * @dev Approve `to` to lock operate on `tokenId`
- *
- * Emits a {LockApproval} event.
- */
- function _lockApprove(
- address owner,
- address to,
- uint256 tokenId
- ) internal virtual {
- _lockApprovals[tokenId] = to;
- emit LockApproval(owner, to, tokenId);
- }
-
- /**
- * @dev Approve `operator` to lock operate on all of `owner` tokens
- *
- * Emits a {LockApprovalForAll} event.
- */
- function _setLockApprovalForAll(
- address owner,
- address operator,
- bool approved
- ) internal virtual {
- require(owner != operator, "ERC5058: lock approve to caller");
- _lockOperatorApprovals[owner][operator] = approved;
- emit LockApprovalForAll(owner, operator, approved);
- }
-
- /**
- * @dev Returns whether `spender` is allowed to lock `tokenId`.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function _isLockApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
- require(_exists(tokenId), "ERC5058: lock operator query for nonexistent token");
- address owner = ERC721.ownerOf(tokenId);
- return (spender == owner || isLockApprovedForAll(owner, spender) || getLockApproved(tokenId) == spender);
- }
-
- /**
- * @dev See {ERC721-_beforeTokenTransfer}.
- *
- * Requirements:
- *
- * - the `tokenId` must not be locked.
- */
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override {
- super._beforeTokenTransfer(from, to, tokenId);
-
- require(!isLocked(tokenId), "ERC5058: token transfer while locked");
- }
-
- /**
- * @dev Hook that is called before any token lock/unlock.
- *
- * Calling conditions:
- *
- * - `owner` is non-zero.
- * - When `expired` is zero, `tokenId` will be unlock for `from`.
- * - When `expired` is non-zero, ``from``'s `tokenId` will be locked.
- *
- */
- function _beforeTokenLock(
- address operator,
- address owner,
- uint256 tokenId,
- uint256 expired
- ) internal virtual {}
-
- /**
- * @dev Hook that is called after any lock/unlock of tokens.
- *
- * Calling conditions:
- *
- * - `owner` is non-zero.
- * - When `expired` is zero, `tokenId` will be unlock for `from`.
- * - When `expired` is non-zero, ``from``'s `tokenId` will be locked.
- *
- */
- function _afterTokenLock(
- address operator,
- address owner,
- uint256 tokenId,
- uint256 expired
- ) internal virtual {}
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
- return interfaceId == type(IERC5058).interfaceId || super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5058/IERC5058.sol b/assets/eip-5058/IERC5058.sol
deleted file mode 100644
index 4f8846e..0000000
--- a/assets/eip-5058/IERC5058.sol
+++ /dev/null
@@ -1,119 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/**
- * @dev ERC-721 Non-Fungible Token Standard, optional lockable extension
- * ERC721 Token that can be locked for a certain period and cannot be transferred.
- * This is designed for a non-escrow staking contract that comes later to lock a user's NFT
- * while still letting them keep it in their wallet.
- * This extension can ensure the security of user tokens during the staking period.
- * If the nft lending protocol is compatible with this extension, the trouble caused by the NFT
- * airdrop can be avoided, because the airdrop is still in the user's wallet
- */
-interface IERC5058 is IERC721 {
- /**
- * @dev Emitted when `tokenId` token is locked by `operator` from `owner`.
- */
- event Locked(address indexed operator, address indexed owner, uint256 indexed tokenId, uint256 expired);
-
- /**
- * @dev Emitted when `tokenId` token is unlocked by `operator` from `owner`.
- */
- event Unlocked(address indexed operator, address indexed owner, uint256 indexed tokenId);
-
- /**
- * @dev Emitted when `owner` enables `approved` to lock the `tokenId` token.
- */
- event LockApproval(address indexed owner, address indexed approved, uint256 indexed tokenId);
-
- /**
- * @dev Emitted when `owner` enables or disables (`approved`) `operator` to lock all of its tokens.
- */
- event LockApprovalForAll(address indexed owner, address indexed operator, bool approved);
-
- /**
- * @dev Returns the locker who is locking the `tokenId` token.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function lockerOf(uint256 tokenId) external view returns (address locker);
-
- /**
- * @dev Lock `tokenId` token until the block number is greater than `expired` to be unlocked.
- *
- * Requirements:
- *
- * - `tokenId` token must be owned by `owner`.
- * - `expired` must be greater than block.number
- * - If the caller is not `from`, it must be approved to lock this token
- * by either {lockApprove} or {setLockApprovalForAll}.
- *
- * Emits a {Locked} event.
- */
- function lock(uint256 tokenId, uint256 expired) external;
-
- /**
- * @dev Unlock `tokenId` token.
- *
- * Requirements:
- *
- * - `tokenId` token must be owned by `from`.
- * - the caller must be the operator who locks the token by {lock}
- *
- * Emits a {Unlocked} event.
- */
- function unlock(uint256 tokenId) external;
-
- /**
- * @dev Gives permission to `to` to lock `tokenId` token.
- *
- * Requirements:
- *
- * - The caller must own the token or be an approved lock operator.
- * - `tokenId` must exist.
- *
- * Emits an {LockApproval} event.
- */
- function lockApprove(address to, uint256 tokenId) external;
-
- /**
- * @dev Approve or remove `operator` as an lock operator for the caller.
- * Operators can call {lock} for any token owned by the caller.
- *
- * Requirements:
- *
- * - The `operator` cannot be the caller.
- *
- * Emits an {LockApprovalForAll} event.
- */
- function setLockApprovalForAll(address operator, bool approved) external;
-
- /**
- * @dev Returns the account lock approved for `tokenId` token.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function getLockApproved(uint256 tokenId) external view returns (address operator);
-
- /**
- * @dev Returns if the `operator` is allowed to lock all of the assets of `owner`.
- *
- * See {setLockApprovalForAll}
- */
- function isLockApprovedForAll(address owner, address operator) external view returns (bool);
-
- /**
- * @dev Returns if the `tokenId` token is locked.
- */
- function isLocked(uint256 tokenId) external view returns (bool);
-
- /**
- * @dev Returns the `tokenId` token lock expired time.
- */
- function lockExpiredTime(uint256 tokenId) external view returns (uint256);
-}
diff --git a/assets/eip-5058/extensions/ERC5058Bound.sol b/assets/eip-5058/extensions/ERC5058Bound.sol
deleted file mode 100644
index e0eebb6..0000000
--- a/assets/eip-5058/extensions/ERC5058Bound.sol
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../factory/IERC5058Factory.sol";
-import "../factory/IERC721Bound.sol";
-import "../ERC5058.sol";
-
-abstract contract ERC5058Bound is ERC5058 {
- address public bound;
-
- function _setFactory(address _factory) internal {
- bound = IERC5058Factory(_factory).boundOf(address(this));
- }
-
- function _setBoundBaseTokenURI(string memory uri) internal {
- IERC721Bound(bound).setBaseTokenURI(uri);
- }
-
- function _setBoundContractURI(string memory uri) internal {
- IERC721Bound(bound).setContractURI(uri);
- }
-
- function burnBound(uint256 tokenId) external {
- IERC721Bound(bound).burn(tokenId);
- }
-
- // NOTE:
- //
- // this will be called when `lock` or `unlock`
- function _afterTokenLock(
- address operator,
- address from,
- uint256 tokenId,
- uint256 expired
- ) internal virtual override {
- super._afterTokenLock(operator, from, tokenId, expired);
-
- if (bound != address(0)) {
- if (expired != 0) {
- // lock mint
- if (operator != address(0)) {
- IERC721Bound(bound).safeMint(msg.sender, tokenId, "");
- }
- } else {
- // unlock
- if (IERC721Bound(bound).exists(tokenId)) {
- IERC721Bound(bound).burn(tokenId);
- }
- }
- }
- }
-}
diff --git a/assets/eip-5058/factory/ERC5058Factory.sol b/assets/eip-5058/factory/ERC5058Factory.sol
deleted file mode 100644
index 3fda931..0000000
--- a/assets/eip-5058/factory/ERC5058Factory.sol
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC721Bound.sol";
-import "./IERC5058Factory.sol";
-
-contract ERC5058Factory is IERC5058Factory {
- address[] private _allBounds;
-
- // Mapping from preimage to bound
- mapping(address => address) private _bounds;
-
- function allBoundsLength() public view virtual override returns (uint256) {
- return _allBounds.length;
- }
-
- function boundByIndex(uint256 index) public view virtual override returns (address) {
- require(index < _allBounds.length, "ERC5058Factory: index out of bounds");
-
- return _allBounds[index];
- }
-
- function existBound(address preimage) public view virtual override returns (bool) {
- return _bounds[preimage] != address(0);
- }
-
- function boundOf(address preimage) public view virtual override returns (address) {
- require(existBound(preimage), "ERC5058Factory: query for nonexistent bound");
- return _bounds[preimage];
- }
-
- function boundDeploy(address preimage) public virtual override returns (address) {
- require(!existBound(preimage), "ERC5058Factory: bound nft is already deployed");
-
- return _deploy(preimage, keccak256(abi.encode(preimage)), "Bound");
- }
-
- function _deploy(
- address preimage,
- bytes32 salt,
- bytes memory prefix
- ) internal returns (address) {
- IERC721Metadata collection = IERC721Metadata(preimage);
- bytes memory code = type(ERC721Bound).creationCode;
- bytes memory bytecode = abi.encodePacked(
- code,
- abi.encode(
- preimage,
- abi.encodePacked(prefix, " ", collection.name()),
- abi.encodePacked(prefix, collection.symbol())
- )
- );
-
- address addr;
- assembly {
- addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
- }
-
- emit DeployedBound(preimage, addr);
-
- _bounds[preimage] = addr;
- _allBounds.push(addr);
-
- return addr;
- }
-}
diff --git a/assets/eip-5058/factory/ERC721Bound.sol b/assets/eip-5058/factory/ERC721Bound.sol
deleted file mode 100644
index 28e9f17..0000000
--- a/assets/eip-5058/factory/ERC721Bound.sol
+++ /dev/null
@@ -1,178 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./IERC721Bound.sol";
-
-interface IPreimage {
- /**
- * @dev Returns if the `tokenId` token of preimage is locked. [MUST]
- */
- function isLocked(uint256 tokenId) external view returns (bool);
-
- /**
- * @dev Opensea-contract-level metadata. [OPTIONAL]
- * Details: https://docs.opensea.io/docs/contract-level-metadata
- */
- function contractURI() external view returns (string memory);
-}
-
-/**
- * @dev This implements an optional extension of {ERC5058} defined in the EIP.
- * The bound token is exactly the same as the locked token metadata, the bound token can be transferred,
- * but it is guaranteed that only one bound token and the original token can be traded in the market at
- * the same time. When the original token lock expires, the bound token must be destroyed.
- */
-contract ERC721Bound is ERC721Enumerable, IERC2981, IERC721Bound {
- address private _preimage;
-
- string private _contractURI;
-
- string private _baseTokenURI;
-
- constructor(
- address preimage_,
- string memory name_,
- string memory symbol_
- ) ERC721(name_, symbol_) {
- _preimage = preimage_;
- }
-
- /**
- * @dev Throws if called by any account other than the preimage.
- */
- modifier onlyPreimage() {
- require(_preimage == msg.sender, "ERC721Bound: caller is not the preimage");
- _;
- }
-
- function preimage() public view virtual override returns (address) {
- return _preimage;
- }
-
- /**
- * @dev See {ERC721-_baseURI}.
- */
- function _baseURI() internal view virtual override returns (string memory) {
- return _baseTokenURI;
- }
-
- /**
- * @dev See {IERC721Metadata-tokenURI}.
- */
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
- if (bytes(_baseTokenURI).length > 0) {
- return super.tokenURI(tokenId);
- }
-
- return IERC721Metadata(_preimage).tokenURI(tokenId);
- }
-
- /**
- * @dev See {IERC2981-royaltyInfo}.
- */
- function royaltyInfo(uint256 tokenId, uint256 salePrice) public view virtual override returns (address, uint256) {
- return IERC2981(_preimage).royaltyInfo(tokenId, salePrice);
- }
-
- /**
- * @dev See {IPreimage-contractURI}.
- */
- function contractURI() public view returns (string memory) {
- if (bytes(_contractURI).length > 0) {
- return _contractURI;
- }
-
- if (IERC165(_preimage).supportsInterface(IPreimage.contractURI.selector)) {
- return IPreimage(_preimage).contractURI();
- }
-
- return "";
- }
-
- /**
- * @dev Returns whether `tokenId` exists.
- */
- function exists(uint256 tokenId) public view returns (bool) {
- return _exists(tokenId);
- }
-
- // @dev Sets the base token URI prefix.
- function setBaseTokenURI(string memory baseTokenURI) public virtual override onlyPreimage {
- _baseTokenURI = baseTokenURI;
- }
-
- // @dev Sets the contract URI.
- function setContractURI(string memory uri) public virtual override onlyPreimage {
- _contractURI = uri;
- }
-
- /**
- * @dev Mints bound `tokenId` and transfers it to `to`.
- *
- * Requirements:
- *
- * - `tokenId` must not exist.
- * - `to` cannot be the zero address.
- * caller must be preimage contract.
- *
- * Emits a {Transfer} event.
- */
- function safeMint(
- address to,
- uint256 tokenId,
- bytes memory data
- ) public virtual override onlyPreimage {
- _safeMint(to, tokenId, data);
- }
-
- /**
- * @dev Destroys `tokenId`.
- * The approval is cleared when the token is burned.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- * caller must be preimage contract.
- *
- * Emits a {Transfer} event.
- */
- function burn(uint256 tokenId) public virtual override onlyPreimage {
- _burn(tokenId);
- }
-
- /**
- * @dev See {ERC721-_beforeTokenTransfer}.
- */
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override {
- super._beforeTokenTransfer(from, to, tokenId);
-
- if (from == address(0)) {
- require(IPreimage(_preimage).isLocked(tokenId), "ERC721Bound: token mint while preimage not locked");
- }
- if (to == address(0)) {
- require(!IPreimage(_preimage).isLocked(tokenId), "ERC721Bound: token burn while preimage locked");
- }
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(IERC165, ERC721Enumerable)
- returns (bool)
- {
- return
- interfaceId == type(IERC721Bound).interfaceId ||
- interfaceId == type(IERC2981).interfaceId ||
- interfaceId == IPreimage.contractURI.selector ||
- super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5058/factory/IERC5058Factory.sol b/assets/eip-5058/factory/IERC5058Factory.sol
deleted file mode 100644
index 61ecb19..0000000
--- a/assets/eip-5058/factory/IERC5058Factory.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5058Factory {
- event DeployedBound(address indexed preimage, address bound);
-
- function allBoundsLength() external view returns (uint256);
-
- function boundByIndex(uint256 index) external view returns (address);
-
- function existBound(address preimage) external view returns (bool);
-
- function boundOf(address preimage) external view returns (address);
-
- function boundDeploy(address preimage) external returns (address);
-}
diff --git a/assets/eip-5058/factory/IERC721Bound.sol b/assets/eip-5058/factory/IERC721Bound.sol
deleted file mode 100644
index c8b86a9..0000000
--- a/assets/eip-5058/factory/IERC721Bound.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC721Bound is IERC721 {
- function preimage() external view returns (address);
-
- function contractURI() external view returns (string memory);
-
- function exists(uint256 tokenId) external view returns (bool);
-
- function setBaseTokenURI(string memory _baseTokenURI) external;
-
- function setContractURI(string memory uri) external;
-
- function safeMint(
- address to,
- uint256 tokenId,
- bytes memory data
- ) external;
-
- function burn(uint256 tokenId) external;
-}
diff --git a/assets/eip-5058/mock/EIP5058Mock.sol b/assets/eip-5058/mock/EIP5058Mock.sol
deleted file mode 100644
index 0d02a74..0000000
--- a/assets/eip-5058/mock/EIP5058Mock.sol
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5058.sol";
-
-contract EIP5058Mock is ERC721Enumerable, ERC5058 {
- constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
-
- function exists(uint256 tokenId) public view returns (bool) {
- return _exists(tokenId);
- }
-
- function lockMint(
- address to,
- uint256 tokenId,
- uint256 expired
- ) external {
- _safeLockMint(to, tokenId, expired, "");
- }
-
- function mint(address to, uint256 tokenId) external {
- _mint(to, tokenId);
- }
-
- function burn(uint256 tokenId) external {
- require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not owner nor approved");
-
- _burn(tokenId);
- }
-
- function _burn(uint256 tokenId) internal virtual override(ERC721, ERC5058) {
- super._burn(tokenId);
- }
-
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override(ERC721Enumerable, ERC5058) {
- super._beforeTokenTransfer(from, to, tokenId);
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(ERC721Enumerable, ERC5058)
- returns (bool)
- {
- return super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5058/test/test.ts b/assets/eip-5058/test/test.ts
deleted file mode 100644
index 4b72864..0000000
--- a/assets/eip-5058/test/test.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import "@nomiclabs/hardhat-ethers";
-import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { EIP5058Mock } from "typechain-types";
-
-describe("ERC5058 contract", function() {
- let owner: SignerWithAddress;
- let alice: SignerWithAddress;
- let EIP5058: EIP5058Mock;
-
- beforeEach(async () => {
- [owner, alice] = await ethers.getSigners();
-
- const ERC5058Factory = await ethers.getContractFactory("EIP5058Mock");
-
- EIP5058 = await ERC5058Factory.deploy("ERC5058Mock", "ERC5058");
- });
-
- it("Deployment should assign the total supply of tokens to the owner", async function() {
- const ownerBalance = await EIP5058.balanceOf(owner.address);
- expect(await EIP5058.totalSupply()).to.equal(ownerBalance);
- });
-
- it("lockMint works", async function() {
- const NFTId = 0;
- const block = await ethers.provider.getBlockNumber();
- await EIP5058.lockMint(alice.address, NFTId, block + 2);
-
- expect(await EIP5058.lockExpiredTime(NFTId)).eq(block + 2);
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- expect(await EIP5058.lockerOf(NFTId)).eq(owner.address);
- });
-
- it("Can not transfer when token is locked", async function() {
- const NFTId = 0;
- const block = await ethers.provider.getBlockNumber();
- await EIP5058.lockMint(owner.address, NFTId, block + 3);
-
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- // can not transfer when token is locked
- await expect(EIP5058.transferFrom(owner.address, alice.address, NFTId)).to.be.revertedWith(
- "ERC5058: token transfer while locked",
- );
-
- // can transfer when token is unlocked
- await ethers.provider.send("evm_mine", []);
-
- expect(await EIP5058.isLocked(NFTId)).eq(false);
- await EIP5058.transferFrom(owner.address, alice.address, NFTId);
- expect(await EIP5058.ownerOf(NFTId)).eq(alice.address);
- });
-
- it("isLocked works", async function() {
- const NFTId = 0;
- const block = await ethers.provider.getBlockNumber();
- await EIP5058.lockMint(owner.address, NFTId, block + 2);
-
- // isLocked works
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- await ethers.provider.send("evm_mine", []);
- expect(await EIP5058.isLocked(NFTId)).eq(false);
- });
-
- it("lock works", async function() {
- const NFTId = 0;
- let block = await ethers.provider.getBlockNumber();
- await EIP5058.lockMint(owner.address, NFTId, block + 3);
-
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- await expect(EIP5058.lock(NFTId, block + 5)).to.be.revertedWith(
- "ERC5058: token is locked",
- );
-
- await ethers.provider.send("evm_mine", []);
- expect(await EIP5058.isLocked(NFTId)).eq(false);
- await EIP5058.lock(NFTId, block + 5);
- });
-
- it("unlock works with lockMint", async function() {
- const NFTId = 0;
- const block = await ethers.provider.getBlockNumber();
- await EIP5058.lockMint(owner.address, NFTId, block + 3);
-
- // unlock works
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- expect(await EIP5058.lockerOf(NFTId)).eq(owner.address);
- await EIP5058.unlock(NFTId);
- expect(await EIP5058.isLocked(NFTId)).eq(false);
- });
-
- it("unlock works", async function() {
- const NFTId = 0;
-
- await EIP5058.mint(owner.address, NFTId);
- await expect(EIP5058.unlock(NFTId)).to.be.revertedWith(
- "ERC5058: locker query for non-locked token",
- );
- const block = await ethers.provider.getBlockNumber();
- await EIP5058.lock(NFTId, block + 3);
- expect(await EIP5058.isLocked(NFTId)).eq(true);
- await EIP5058.unlock(NFTId);
- expect(await EIP5058.isLocked(NFTId)).eq(false);
- });
-
- it("lockApprove works", async function() {
- const NFTId = 0;
- await EIP5058.mint(alice.address, NFTId);
- let block = await ethers.provider.getBlockNumber();
-
- await expect(EIP5058.lock(NFTId, block + 4)).to.be.revertedWith(
- "ERC5058: lock caller is not owner nor approved",
- );
- await EIP5058.connect(alice).lockApprove(owner.address, NFTId);
- expect(await EIP5058.getLockApproved(NFTId)).eq(owner.address);
-
- await EIP5058.lock(NFTId, block + 8);
- expect(await EIP5058.isLocked(NFTId)).eq(true);
-
- await expect(EIP5058.lockApprove(alice.address, NFTId)).to.be.revertedWith(
- "ERC5058: token is locked",
- );
- });
-
- it("setLockApproveForAll works", async function() {
- const NFTId = 0;
-
- await EIP5058.mint(alice.address, NFTId);
- const block = await ethers.provider.getBlockNumber();
- await expect(EIP5058.lock(NFTId, block + 2)).to.be.revertedWith(
- "ERC5058: lock caller is not owner nor approved",
- );
-
- await EIP5058.connect(alice).setLockApprovalForAll(owner.address, true);
- expect(await EIP5058.isLockApprovedForAll(alice.address, owner.address)).eq(true);
-
- await EIP5058.lock(NFTId, block + 6);
-
- await EIP5058.connect(alice).setLockApprovalForAll(owner.address, false);
- expect(await EIP5058.isLockApprovedForAll(alice.address, owner.address)).eq(false);
- });
-});
diff --git a/assets/eip-5139/AUTHORS.md b/assets/eip-5139/AUTHORS.md
deleted file mode 100644
index 24cf6a2..0000000
--- a/assets/eip-5139/AUTHORS.md
+++ /dev/null
@@ -1,37 +0,0 @@
-SemVer Authors
-==============
-
-The following people have modified the Semantic Versioning 2.0.0 specification:
-
- - Tom Preston-Werner
- - Phil Haack
- - Haacked
- - isaacs
- - Thijs Schreijer
- - jeffhandley
- - Alexandr Tovmach
- - Adam Ralph
- - Eddie Garmon
- - Jeff Handley
- - Krzysztof Piasecki
- - Doug Beck
- - Gert de Pagter
- - Guillermo Calvo
- - Iulian Onofrei
- - Ivan Bessarabov
- - Jo Liss
- - Johanan Liebermann
- - Joseph Donahue
- - Konstantin
- - Kristian Glass
- - Mark Amery
- - OGINO Masanori
- - Oguz Bilgic
- - Slipp Douglas
- - Thomas Schraitle
- - Tim Vergenz
- - Todd Reed
- - Tristram Oaten
- - Wincent Colaiuta
- - alexandrtovmach
- - wolf99
diff --git a/assets/eip-5139/semver.md b/assets/eip-5139/semver.md
deleted file mode 100644
index 95cf203..0000000
--- a/assets/eip-5139/semver.md
+++ /dev/null
@@ -1,373 +0,0 @@
-Semantic Versioning 2.0.0
-==============================
-
-Summary
--------
-
-Given a version number MAJOR.MINOR.PATCH, increment the:
-
-1. MAJOR version when you make incompatible API changes,
-1. MINOR version when you add functionality in a backwards compatible
- manner, and
-1. PATCH version when you make backwards compatible bug fixes.
-
-Additional labels for pre-release and build metadata are available as extensions
-to the MAJOR.MINOR.PATCH format.
-
-Introduction
-------------
-
-In the world of software management there exists a dreaded place called
-"dependency hell." The bigger your system grows and the more packages you
-integrate into your software, the more likely you are to find yourself, one
-day, in this pit of despair.
-
-In systems with many dependencies, releasing new package versions can quickly
-become a nightmare. If the dependency specifications are too tight, you are in
-danger of version lock (the inability to upgrade a package without having to
-release new versions of every dependent package). If dependencies are
-specified too loosely, you will inevitably be bitten by version promiscuity
-(assuming compatibility with more future versions than is reasonable).
-Dependency hell is where you are when version lock and/or version promiscuity
-prevent you from easily and safely moving your project forward.
-
-As a solution to this problem, we propose a simple set of rules and
-requirements that dictate how version numbers are assigned and incremented.
-These rules are based on but not necessarily limited to pre-existing
-widespread common practices in use in both closed and open-source software.
-For this system to work, you first need to declare a public API. This may
-consist of documentation or be enforced by the code itself. Regardless, it is
-important that this API be clear and precise. Once you identify your public
-API, you communicate changes to it with specific increments to your version
-number. Consider a version format of X.Y.Z (Major.Minor.Patch). Bug fixes not
-affecting the API increment the patch version, backwards compatible API
-additions/changes increment the minor version, and backwards incompatible API
-changes increment the major version.
-
-We call this system "Semantic Versioning." Under this scheme, version numbers
-and the way they change convey meaning about the underlying code and what has
-been modified from one version to the next.
-
-Semantic Versioning Specification (SemVer)
-------------------------------------------
-
-The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
-"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
-interpreted as described in [RFC 2119](https://tools.ietf.org/html/rfc2119).
-
-1. Software using Semantic Versioning MUST declare a public API. This API
-could be declared in the code itself or exist strictly in documentation.
-However it is done, it SHOULD be precise and comprehensive.
-
-1. A normal version number MUST take the form X.Y.Z where X, Y, and Z are
-non-negative integers, and MUST NOT contain leading zeroes. X is the
-major version, Y is the minor version, and Z is the patch version.
-Each element MUST increase numerically. For instance: 1.9.0 -> 1.10.0 -> 1.11.0.
-
-1. Once a versioned package has been released, the contents of that version
-MUST NOT be modified. Any modifications MUST be released as a new version.
-
-1. Major version zero (0.y.z) is for initial development. Anything MAY change
-at any time. The public API SHOULD NOT be considered stable.
-
-1. Version 1.0.0 defines the public API. The way in which the version number
-is incremented after this release is dependent on this public API and how it
-changes.
-
-1. Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards
-compatible bug fixes are introduced. A bug fix is defined as an internal
-change that fixes incorrect behavior.
-
-1. Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards
-compatible functionality is introduced to the public API. It MUST be
-incremented if any public API functionality is marked as deprecated. It MAY be
-incremented if substantial new functionality or improvements are introduced
-within the private code. It MAY include patch level changes. Patch version
-MUST be reset to 0 when minor version is incremented.
-
-1. Major version X (X.y.z | X > 0) MUST be incremented if any backwards
-incompatible changes are introduced to the public API. It MAY also include minor
-and patch level changes. Patch and minor versions MUST be reset to 0 when major
-version is incremented.
-
-1. A pre-release version MAY be denoted by appending a hyphen and a
-series of dot separated identifiers immediately following the patch
-version. Identifiers MUST comprise only ASCII alphanumerics and hyphens
-[0-9A-Za-z-]. Identifiers MUST NOT be empty. Numeric identifiers MUST
-NOT include leading zeroes. Pre-release versions have a lower
-precedence than the associated normal version. A pre-release version
-indicates that the version is unstable and might not satisfy the
-intended compatibility requirements as denoted by its associated
-normal version. Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7,
-1.0.0-x.7.z.92, 1.0.0-x-y-z.--.
-
-1. Build metadata MAY be denoted by appending a plus sign and a series of dot
-separated identifiers immediately following the patch or pre-release version.
-Identifiers MUST comprise only ASCII alphanumerics and hyphens [0-9A-Za-z-].
-Identifiers MUST NOT be empty. Build metadata MUST be ignored when determining
-version precedence. Thus two versions that differ only in the build metadata,
-have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700,
-1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD.
-
-1. Precedence refers to how versions are compared to each other when ordered.
-
- 1. Precedence MUST be calculated by separating the version into major,
- minor, patch and pre-release identifiers in that order (Build metadata
- does not figure into precedence).
-
- 1. Precedence is determined by the first difference when comparing each of
- these identifiers from left to right as follows: Major, minor, and patch
- versions are always compared numerically.
-
- Example: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.
-
- 1. When major, minor, and patch are equal, a pre-release version has lower
- precedence than a normal version:
-
- Example: 1.0.0-alpha < 1.0.0.
-
- 1. Precedence for two pre-release versions with the same major, minor, and
- patch version MUST be determined by comparing each dot separated identifier
- from left to right until a difference is found as follows:
-
- 1. Identifiers consisting of only digits are compared numerically.
-
- 1. Identifiers with letters or hyphens are compared lexically in ASCII
- sort order.
-
- 1. Numeric identifiers always have lower precedence than non-numeric
- identifiers.
-
- 1. A larger set of pre-release fields has a higher precedence than a
- smaller set, if all of the preceding identifiers are equal.
-
- Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta <
- 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.
-
-Backus–Naur Form Grammar for Valid SemVer Versions
---------------------------------------------------
-```
- ::=
- | "-"
- | "+"
- | "-" "+"
-
- ::= "." "."
-
- ::=
-
- ::=
-
- ::=
-
- ::=
-
- ::=
- | "."
-
- ::=
-
- ::=
- | "."
-
- ::=
- |
-
- ::=
- |
-
- ::=
- |
- |
- |
-
- ::= "0"
- |
- |
-
- ::=
- |
-
- ::=
- |
-
- ::=
- | "-"
-
- ::=
- |
-
- ::= "0"
- |
-
- ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
-
- ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J"
- | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T"
- | "U" | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" | "c" | "d"
- | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n"
- | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x"
- | "y" | "z"
-```
-
-Why Use Semantic Versioning?
-----------------------------
-
-This is not a new or revolutionary idea. In fact, you probably do something
-close to this already. The problem is that "close" isn't good enough. Without
-compliance to some sort of formal specification, version numbers are
-essentially useless for dependency management. By giving a name and clear
-definition to the above ideas, it becomes easy to communicate your intentions
-to the users of your software. Once these intentions are clear, flexible (but
-not too flexible) dependency specifications can finally be made.
-
-A simple example will demonstrate how Semantic Versioning can make dependency
-hell a thing of the past. Consider a library called "Firetruck." It requires a
-Semantically Versioned package named "Ladder." At the time that Firetruck is
-created, Ladder is at version 3.1.0. Since Firetruck uses some functionality
-that was first introduced in 3.1.0, you can safely specify the Ladder
-dependency as greater than or equal to 3.1.0 but less than 4.0.0. Now, when
-Ladder version 3.1.1 and 3.2.0 become available, you can release them to your
-package management system and know that they will be compatible with existing
-dependent software.
-
-As a responsible developer you will, of course, want to verify that any
-package upgrades function as advertised. The real world is a messy place;
-there's nothing we can do about that but be vigilant. What you can do is let
-Semantic Versioning provide you with a sane way to release and upgrade
-packages without having to roll new versions of dependent packages, saving you
-time and hassle.
-
-If all of this sounds desirable, all you need to do to start using Semantic
-Versioning is to declare that you are doing so and then follow the rules. Link
-to this website from your README so others know the rules and can benefit from
-them.
-
-FAQ
----
-
-### How should I deal with revisions in the 0.y.z initial development phase?
-
-The simplest thing to do is start your initial development release at 0.1.0
-and then increment the minor version for each subsequent release.
-
-### How do I know when to release 1.0.0?
-
-If your software is being used in production, it should probably already be
-1.0.0. If you have a stable API on which users have come to depend, you should
-be 1.0.0. If you're worrying a lot about backwards compatibility, you should
-probably already be 1.0.0.
-
-### Doesn't this discourage rapid development and fast iteration?
-
-Major version zero is all about rapid development. If you're changing the API
-every day you should either still be in version 0.y.z or on a separate
-development branch working on the next major version.
-
-### If even the tiniest backwards incompatible changes to the public API require a major version bump, won't I end up at version 42.0.0 very rapidly?
-
-This is a question of responsible development and foresight. Incompatible
-changes should not be introduced lightly to software that has a lot of
-dependent code. The cost that must be incurred to upgrade can be significant.
-Having to bump major versions to release incompatible changes means you'll
-think through the impact of your changes, and evaluate the cost/benefit ratio
-involved.
-
-### Documenting the entire public API is too much work!
-
-It is your responsibility as a professional developer to properly document
-software that is intended for use by others. Managing software complexity is a
-hugely important part of keeping a project efficient, and that's hard to do if
-nobody knows how to use your software, or what methods are safe to call. In
-the long run, Semantic Versioning, and the insistence on a well defined public
-API can keep everyone and everything running smoothly.
-
-### What do I do if I accidentally release a backwards incompatible change as a minor version?
-
-As soon as you realize that you've broken the Semantic Versioning spec, fix
-the problem and release a new minor version that corrects the problem and
-restores backwards compatibility. Even under this circumstance, it is
-unacceptable to modify versioned releases. If it's appropriate,
-document the offending version and inform your users of the problem so that
-they are aware of the offending version.
-
-### What should I do if I update my own dependencies without changing the public API?
-
-That would be considered compatible since it does not affect the public API.
-Software that explicitly depends on the same dependencies as your package
-should have their own dependency specifications and the author will notice any
-conflicts. Determining whether the change is a patch level or minor level
-modification depends on whether you updated your dependencies in order to fix
-a bug or introduce new functionality. We would usually expect additional code
-for the latter instance, in which case it's obviously a minor level increment.
-
-### What if I inadvertently alter the public API in a way that is not compliant with the version number change (i.e. the code incorrectly introduces a major breaking change in a patch release)?
-
-Use your best judgment. If you have a huge audience that will be drastically
-impacted by changing the behavior back to what the public API intended, then
-it may be best to perform a major version release, even though the fix could
-strictly be considered a patch release. Remember, Semantic Versioning is all
-about conveying meaning by how the version number changes. If these changes
-are important to your users, use the version number to inform them.
-
-### How should I handle deprecating functionality?
-
-Deprecating existing functionality is a normal part of software development and
-is often required to make forward progress. When you deprecate part of your
-public API, you should do two things: (1) update your documentation to let
-users know about the change, (2) issue a new minor release with the deprecation
-in place. Before you completely remove the functionality in a new major release
-there should be at least one minor release that contains the deprecation so
-that users can smoothly transition to the new API.
-
-### Does SemVer have a size limit on the version string?
-
-No, but use good judgment. A 255 character version string is probably overkill,
-for example. Also, specific systems may impose their own limits on the size of
-the string.
-
-### Is "v1.2.3" a semantic version?
-
-No, "v1.2.3" is not a semantic version. However, prefixing a semantic version
-with a "v" is a common way (in English) to indicate it is a version number.
-Abbreviating "version" as "v" is often seen with version control. Example:
-`git tag v1.2.3 -m "Release version 1.2.3"`, in which case "v1.2.3" is a tag
-name and the semantic version is "1.2.3".
-
-### Is there a suggested regular expression (RegEx) to check a SemVer string?
-
-There are two. One with named groups for those systems that support them
-(PCRE [Perl Compatible Regular Expressions, i.e. Perl, PHP and R], Python
-and Go).
-
-See:
-
-```
-^(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)\.(?P0|[1-9]\d*)(?:-(?P(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+(?P[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
-```
-
-And one with numbered capture groups instead (so cg1 = major, cg2 = minor,
-cg3 = patch, cg4 = prerelease and cg5 = buildmetadata) that is compatible
-with ECMA Script (JavaScript), PCRE (Perl Compatible Regular Expressions,
-i.e. Perl, PHP and R), Python and Go.
-
-See:
-
-```
-^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
-```
-
-About
------
-
-The Semantic Versioning specification was originally authored by [Tom
-Preston-Werner](https://tom.preston-werner.com), inventor of Gravatar and
-cofounder of GitHub.
-
-If you'd like to leave feedback, please [open an issue on
-GitHub](https://github.com/semver/semver/issues).
-
-License
--------
-
-[Creative Commons ― CC BY 3.0](https://creativecommons.org/licenses/by/3.0/)
diff --git a/assets/eip-5169/contract/ExampleContract.sol b/assets/eip-5169/contract/ExampleContract.sol
deleted file mode 100644
index 298c1c2..0000000
--- a/assets/eip-5169/contract/ExampleContract.sol
+++ /dev/null
@@ -1,180 +0,0 @@
-// SPDX-License-Identifier: MIT
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-import "@openzeppelin/contracts/utils/Context.sol";
-import "@openzeppelin/contracts/utils/Strings.sol";
-import "@openzeppelin/contracts/utils/Counters.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-
-library AddressUtil {
- /**
- * @dev Returns true if `account` is a contract.
- *
- * [IMPORTANT]
- * ====
- * It is unsafe to assume that an address for which this function returns
- * false is an externally-owned account (EOA) and not a contract.
- *
- * Among others, `isContract` will return false for the following
- * types of addresses:
- *
- * - an externally-owned account
- * - a contract in construction
- * - an address where a contract will be created
- * - an address where a contract lived, but was destroyed
- * ====
- */
- function isContract(address account) internal view returns (bool) {
- // This method relies on extcodesize, which returns 0 for contracts in
- // construction, since the code is only stored at the end of the
- // constructor execution.
-
- uint256 size;
- // solhint-disable-next-line no-inline-assembly
- assembly { size := extcodesize(account) }
- return size > 0;
- }
-}
-
-abstract contract MultiOwnable is Ownable {
- mapping(address => bool) private _admins;
-
- /**
- * @dev Initializes the contract setting the deployer as the initial owner.
- */
- constructor() Ownable() {
- _admins[_msgSender()] = true;
- }
-
- function addAdmin(address newAdmin) public onlyOwner {
- _admins[newAdmin] = true;
- }
-
- function revokeAdmin(address currentAdmin) public onlyOwner {
- delete _admins[currentAdmin];
- }
-
- function isAdmin(address sender) public view returns(bool) {
- return _admins[sender];
- }
-
- /**
- * @dev Throws if called by a non-admin
- */
- modifier onlyAdmins() {
- require(_admins[_msgSender()] == true, "Ownable: caller is not an admin");
- _;
- }
-}
-
-interface IERC5169 {
- /// @dev This event emits when the scriptURI is updated,
- /// so wallets implementing this interface can update a cached script
- event ScriptUpdate(string newScriptURI);
-
- /// @notice Get the scriptURI for the contract
- /// @return The scriptURI
- function scriptURI() external view returns(string memory);
-
- /// @notice Update the scriptURI
- /// emits event ScriptUpdate(string memory newScriptURI);
- function updateScriptURI(string memory newScriptURI) external;
-}
-
-contract STLDoor is ERC721, MultiOwnable, IERC5169 {
- using AddressUtil for address;
- using Strings for uint256;
- using Counters for Counters.Counter;
-
- Counters.Counter public _tokenIdCounter;
- Counters.Counter public _topTokenIdCounter;
- Counters.Counter public _stlTokenIdCounter;
-
- uint256 private constant _topTokenId = 10000;
-
- string private _scriptURI;
-
- constructor() ERC721("STL HQ Door", "OFFICE") {
- _tokenIdCounter.increment();
- _scriptURI = "ipfs://QmXXLFBeSjXAwAhbo1344wJSjLgoUrfUK9LE57oVubaRRp";
- mintUsingSequentialTokenId();
- }
-
- function contractURI() public pure returns (string memory) {
- return "ipfs://QmUgdLvPvjuHGfMsuK1H2jFpg5r1QNc8JeWyXyRwKP8pTf";
- }
-
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
- require(_exists(tokenId), "tokenURI: URI query for nonexistent token");
- if (tokenId < _topTokenId) {
- return "ipfs://QmW948aN4Tjh4eLkAAo8os1AcM2FJjA46qtaEfFAnyNYzY";
- } else if (tokenId < _topTokenId * 2) {
- return "ipfs://QmR31f2AUokC5QyLXzDYUjy5tVibkjbW4voVuMBZfrNVU8";
- } else {
- return "ipfs://QmdaSTaF6WXpYWiL5ck7csmTy5EWHzYVGykJZN7TR95dSS";
- }
- }
-
- function scriptURI() public view override returns (string memory) {
- return _scriptURI;
- }
-
- function updateScriptURI(string memory newScriptURI) public override onlyAdmins {
- _scriptURI = newScriptURI;
- emit ScriptUpdate(newScriptURI);
- }
-
- function mintUsingSequentialTokenId() public onlyAdmins returns (uint256 tokenId) {
- tokenId = _tokenIdCounter.current();
- require(tokenId < _topTokenId, "Hit upper mint limit");
- _mint(msg.sender, tokenId);
- _tokenIdCounter.increment();
- }
-
- function topMintUsingSequentialTokenId() public onlyAdmins returns (uint256 tokenId) {
- tokenId = _topTokenIdCounter.current() + _topTokenId;
- require(tokenId < _topTokenId*2, "Hit upper mint limit");
- _mint(msg.sender, tokenId);
- _topTokenIdCounter.increment();
- }
-
- function stlMintUsingSequentialTokenId() public onlyAdmins returns (uint256 tokenId) {
- tokenId = _stlTokenIdCounter.current() + _topTokenId*2;
- _mint(msg.sender, tokenId);
- _stlTokenIdCounter.increment();
- }
-
- function burnToken(uint256 tokenId) public onlyAdmins {
- require(_exists(tokenId), "burn: nonexistent token");
- _burn(tokenId);
- }
-
- // Only allow owners to transfer tokens
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId,
- bytes memory _data
- ) public override onlyAdmins {
- require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
- _safeTransfer(from, to, tokenId, _data);
- }
-
- function transferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public override onlyAdmins {
- //solhint-disable-next-line max-line-length
- require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
-
- _transfer(from, to, tokenId);
- }
-
- function selfDestruct() public payable onlyOwner {
- selfdestruct(payable(owner()));
- }
-}
diff --git a/assets/eip-5169/tokenscript/ExampleScript.xml b/assets/eip-5169/tokenscript/ExampleScript.xml
deleted file mode 100644
index 5fb54cc..0000000
--- a/assets/eip-5169/tokenscript/ExampleScript.xml
+++ /dev/null
@@ -1,421 +0,0 @@
-
-
-
-
- STL Office Token
- STL Office Tokens
-
-
- Boleto de admisión
- Boleto de admisiónes
-
-
- 入場券
- 入場券
-
-
-
- 0xB424e50674a38e83c7Eca39945fe5B45B4cd3705
-
-
-
-
-
-
-
-
-
-
- Unlock
- 开锁
- Abrir
-
-
-
-
-
-
-
-
-
- Lock
- 关锁
- Cerrar
-
-
-
-
-
-
-
-
-
- Mint Ape 1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mint Ape 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Mint STL Token
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/eip-5173/Arithmetic_Sequence_FR_Payout_Distribution.png b/assets/eip-5173/Arithmetic_Sequence_FR_Payout_Distribution.png
deleted file mode 100644
index 5ebce00..0000000
Binary files a/assets/eip-5173/Arithmetic_Sequence_FR_Payout_Distribution.png and /dev/null differ
diff --git a/assets/eip-5173/Implementation/InFR.sol b/assets/eip-5173/Implementation/InFR.sol
deleted file mode 100644
index 18fa1e5..0000000
--- a/assets/eip-5173/Implementation/InFR.sol
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-/*
- *
- * @dev Interface for the Future Rewards Token Standard.
- *
- * A standardized way to receive future rewards for non-fungible tokens (NFTs.)
- *
- */
-interface InFR is IERC165 {
-
- event FRClaimed(address indexed account, uint256 indexed amount);
-
- event FRDistributed(uint256 indexed tokenId, uint256 indexed soldPrice, uint256 indexed allocatedFR);
-
- function list(uint256 tokenId, uint256 salePrice) external;
-
- function unlist(uint256 tokenId) external;
-
- function buy(uint256 tokenId) payable external;
-
- function releaseFR(address payable account) external;
-
- function retrieveFRInfo(uint256 tokenId) external returns(uint8, uint256, uint256, uint256, uint256, address[] memory);
-
- function retrieveAllottedFR(address account) external returns(uint256);
-
- function retrieveListInfo(uint256 tokenId) external returns(uint256, address, bool);
-
-}
diff --git a/assets/eip-5173/Implementation/nFR.sol b/assets/eip-5173/Implementation/nFR.sol
deleted file mode 100644
index b02a483..0000000
--- a/assets/eip-5173/Implementation/nFR.sol
+++ /dev/null
@@ -1,247 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./InFR.sol";
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/utils/math/Math.sol";
-import "@openzeppelin/contracts/utils/math/SafeMath.sol";
-import "@prb/math/contracts/PRBMathUD60x18.sol";
-import "@prb/math/contracts/PRBMathSD59x18.sol";
-
-import "hardhat/console.sol";
-
-abstract contract nFR is InFR, ERC721 {
-
- using Address for address;
-
- using PRBMathUD60x18 for uint256;
- using PRBMathSD59x18 for int256;
-
- struct FRInfo {
- uint8 numGenerations; // Number of generations corresponding to that Token ID
- uint256 percentOfProfit; // Percent of profit allocated for FR, scaled by 1e18
- uint256 successiveRatio; // The common ratio of successive in the geometric sequence, used for distribution calculation
- uint256 lastSoldPrice; // Last sale price in ETH mantissa
- uint256 ownerAmount; // Amount of owners the Token ID has seen
- bool isValid; // Updated by contract and signifies if an FR Info for a given Token ID is valid
- }
-
- struct ListInfo {
- uint256 salePrice; // ETH mantissa of the listed selling price
- address lister; // Owner/Lister of the Token
- bool isListed; // Boolean indicating whether the Token is listed or not
- }
-
- FRInfo private _defaultFRInfo;
-
- // Takes Token ID and returns corresponding FR Info
- mapping(uint256 => FRInfo) private _tokenFRInfo;
-
- // Takes Token ID and returns the addresses currently in the FR cycle
- mapping(uint256 => address[]) private _addressesInFR;
-
- // Takes Address and returns amount of ether available to address from FR payments
- mapping(address => uint256) private _allottedFR;
-
- // Takes Token ID and returns corresponding ListInfo
- mapping(uint256 => ListInfo) private _tokenListInfo;
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
- return interfaceId == type(InFR).interfaceId || super.supportsInterface(interfaceId);
- }
-
- function retrieveFRInfo(uint256 tokenId) public view virtual override returns(uint8 numGenerations, uint256 percentOfProfit, uint256 successiveRatio, uint256 lastSoldPrice, uint256 ownerAmount, address[] memory addressesInFR) {
- return (_tokenFRInfo[tokenId].numGenerations, _tokenFRInfo[tokenId].percentOfProfit, _tokenFRInfo[tokenId].successiveRatio, _tokenFRInfo[tokenId].lastSoldPrice, _tokenFRInfo[tokenId].ownerAmount, _addressesInFR[tokenId]);
- }
-
- function retrieveListInfo(uint256 tokenId) public view virtual override returns(uint256, address, bool) {
- return (_tokenListInfo[tokenId].salePrice, _tokenListInfo[tokenId].lister, _tokenListInfo[tokenId].isListed);
- }
-
- function retrieveAllottedFR(address account) public view virtual override returns(uint256) {
- return _allottedFR[account];
- }
-
- function _transferFrom(address from, address to, uint256 tokenId, uint256 soldPrice) internal virtual {
- ERC721._transfer(from, to, tokenId);
- require(_checkERC721Received(from, to, tokenId, ""), "ERC721: transfer to non ERC721Receiver implementer");
-
- if (soldPrice <= _tokenFRInfo[tokenId].lastSoldPrice) { // NFT sold for a loss, meaning no FR distribution, but we still shift generations, and update price. We return ALL of the received ETH to the msg.sender as no FR chunk was needed.
- _tokenFRInfo[tokenId].lastSoldPrice = soldPrice;
- _tokenFRInfo[tokenId].ownerAmount++;
- _shiftGenerations(to, tokenId);
- (bool sent, ) = payable(_tokenListInfo[tokenId].lister).call{value: soldPrice}("");
- require(sent, "ERC5173: Failed to send msg.value to lister");
- } else {
- _distributeFR(tokenId, soldPrice);
- _tokenFRInfo[tokenId].lastSoldPrice = soldPrice;
- _tokenFRInfo[tokenId].ownerAmount++;
- _shiftGenerations(to, tokenId);
- }
-
- delete _tokenListInfo[tokenId];
- }
-
- function list(uint256 tokenId, uint256 salePrice) public virtual override {
- require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC5173: list caller is not owner nor approved");
-
- _tokenListInfo[tokenId] = ListInfo(salePrice, _msgSender(), true);
- }
-
- function unlist(uint256 tokenId) public virtual override {
- require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC5173: unlist caller is not owner nor approved");
-
- delete _tokenListInfo[tokenId];
- }
-
- function buy(uint256 tokenId) public virtual override payable {
- require(_tokenListInfo[tokenId].isListed == true, "Token is not listed");
- require(_tokenListInfo[tokenId].salePrice == msg.value, "salePrice and msg.value mismatch");
-
- _transferFrom(_tokenListInfo[tokenId].lister, _msgSender(), tokenId, _tokenListInfo[tokenId].salePrice);
- }
-
- function _transfer(address from, address to, uint256 tokenId) internal virtual override {
- super._transfer(from, to, tokenId);
-
- if (_tokenListInfo[tokenId].isListed == true) {
- delete _tokenListInfo[tokenId];
- }
-
- _tokenFRInfo[tokenId].lastSoldPrice = 0;
- _tokenFRInfo[tokenId].ownerAmount++;
- _shiftGenerations(to, tokenId);
- }
-
- function _mint(address to, uint256 tokenId) internal virtual override {
- require(_defaultFRInfo.isValid, "No Default FR Info has been set");
-
- super._mint(to, tokenId);
-
- _tokenFRInfo[tokenId] = FRInfo(_defaultFRInfo.numGenerations, _defaultFRInfo.percentOfProfit, _defaultFRInfo.successiveRatio, 0, 1, true);
-
- _addressesInFR[tokenId].push(to);
- }
-
- function _burn(uint256 tokenId) internal virtual override {
- super._burn(tokenId);
-
- delete _tokenFRInfo[tokenId];
- delete _addressesInFR[tokenId];
- delete _tokenListInfo[tokenId];
- }
-
- function _mint(address to, uint256 tokenId, uint8 numGenerations, uint256 percentOfProfit, uint256 successiveRatio) internal virtual {
- require(numGenerations > 0 && percentOfProfit > 0 && percentOfProfit <= 1e18 && successiveRatio > 0, "Invalid Data Passed");
-
- ERC721._mint(to, tokenId);
- require(_checkERC721Received(address(0), to, tokenId, ""), "ERC721: transfer to non ERC721Receiver implementer");
-
- _tokenFRInfo[tokenId] = FRInfo(numGenerations, percentOfProfit, successiveRatio, 0, 1, true);
-
- _addressesInFR[tokenId].push(to);
- }
-
- function _distributeFR(uint256 tokenId, uint256 soldPrice) internal virtual {
- uint256 profit = soldPrice - _tokenFRInfo[tokenId].lastSoldPrice;
- uint256[] memory FR = _calculateFR(profit, _tokenFRInfo[tokenId].percentOfProfit, _tokenFRInfo[tokenId].successiveRatio, _tokenFRInfo[tokenId].ownerAmount, _tokenFRInfo[tokenId].numGenerations);
-
- for (uint owner = 0; owner < FR.length; owner++) {
- _allottedFR[_addressesInFR[tokenId][owner]] += FR[owner];
- }
-
- uint256 allocatedFR = 0;
-
- for (uint reward = 0; reward < FR.length; reward++) {
- allocatedFR += FR[reward];
- }
-
- (bool sent, ) = payable(_tokenListInfo[tokenId].lister).call{value: soldPrice - allocatedFR}("");
- require(sent, "Failed to send ETH after FR distribution to lister");
-
- emit FRDistributed(tokenId, soldPrice, allocatedFR);
- }
-
- function _shiftGenerations(address to, uint256 tokenId) internal virtual {
- if (_addressesInFR[tokenId].length < _tokenFRInfo[tokenId].numGenerations) { // We just want to push to the array
- _addressesInFR[tokenId].push(to);
- } else { // We want to remove the first element in the array and then push to the end of the array
- for (uint i = 0; i < _addressesInFR[tokenId].length-1; i++) {
- _addressesInFR[tokenId][i] = _addressesInFR[tokenId][i+1];
- }
-
- _addressesInFR[tokenId].pop();
-
- _addressesInFR[tokenId].push(to);
- }
- }
-
- function _setDefaultFRInfo(uint8 numGenerations, uint256 percentOfProfit, uint256 successiveRatio) internal virtual {
- require(numGenerations > 0 && percentOfProfit > 0 && percentOfProfit <= 1e18 && successiveRatio > 0, "Invalid Data Passed");
-
- _defaultFRInfo.numGenerations = numGenerations;
- _defaultFRInfo.percentOfProfit = percentOfProfit;
- _defaultFRInfo.successiveRatio = successiveRatio;
- _defaultFRInfo.isValid = true;
- }
-
- function releaseFR(address payable account) public virtual override {
- require(_allottedFR[account] > 0, "No FR Payment due");
-
- uint256 FRAmount = _allottedFR[account];
-
- _allottedFR[account] = 0;
-
- (bool sent, ) = account.call{value: FRAmount}("");
- require(sent, "Failed to release FR");
-
- emit FRClaimed(account, FRAmount);
- }
-
- function _calculateFR(uint256 totalProfit, uint256 buyerReward, uint256 successiveRatio, uint256 ownerAmount, uint256 windowSize) pure internal virtual returns(uint256[] memory) {
- uint256 n = Math.min(ownerAmount, windowSize);
- uint256[] memory FR = new uint256[](n);
-
- for (uint256 i = 1; i < n + 1; i++) {
- uint256 pi = 0;
-
- if (successiveRatio != 1e18) {
- int256 v1 = 1e18 - int256(successiveRatio).powu(n);
- int256 v2 = int256(successiveRatio).powu(i - 1);
- int256 v3 = int256(totalProfit).mul(int256(buyerReward));
- int256 v4 = v3.mul(1e18 - int256(successiveRatio));
- pi = uint256(v4 * v2 / v1);
- } else {
- pi = totalProfit.mul(buyerReward).div(n);
- }
-
- FR[n - i] = pi;
- }
-
- return FR;
- }
-
- function _checkERC721Received(
- address from,
- address to,
- uint256 tokenId,
- bytes memory _data
- ) private returns (bool) {
- if (to.isContract()) {
- try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
- return retval == IERC721Receiver.onERC721Received.selector;
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert("ERC721: transfer to non ERC721Receiver implementer");
- } else {
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- } else {
- return true;
- }
- }
-
-}
\ No newline at end of file
diff --git a/assets/eip-5173/Implementation/nFRImplementation.sol b/assets/eip-5173/Implementation/nFRImplementation.sol
deleted file mode 100644
index 5605121..0000000
--- a/assets/eip-5173/Implementation/nFRImplementation.sol
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/utils/Counters.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
-import "./nFR.sol";
-
-contract MyNFT is ERC721URIStorage, Ownable, nFR {
- using Counters for Counters.Counter;
- Counters.Counter private _tokenIds;
-
- constructor() ERC721("MyNFT", "NFT") {}
-
- function mintNFT(address recipient, uint8 numGenerations, uint256 percentOfProfit, uint256 successiveRatio, string memory tokenURI)
- public onlyOwner
- returns (uint256)
- {
- _tokenIds.increment();
-
- uint256 newItemId = _tokenIds.current();
- _mint(recipient, newItemId, numGenerations, percentOfProfit, successiveRatio);
- _setTokenURI(newItemId, tokenURI);
-
- return newItemId;
- }
-
- function mintERC721(address recipient, string memory tokenURI) public onlyOwner {
- _tokenIds.increment();
-
- uint256 newItemId = _tokenIds.current();
- _mint(recipient, newItemId);
- _setTokenURI(newItemId, tokenURI);
- }
-
- function setDefaultFRInfo(uint8 numGenerations, uint256 percentOfProfit, uint256 successiveRatio) public onlyOwner {
- _setDefaultFRInfo(numGenerations, percentOfProfit, successiveRatio);
- }
-
- function burnNFT(uint256 tokenId) public onlyOwner {
- _burn(tokenId);
- }
-
- function _burn(uint256 tokenId) internal override(nFR, ERC721URIStorage) {
- super._burn(tokenId);
- }
-
- function _transfer(address from, address to, uint256 tokenId) internal override(ERC721, nFR) {
- super._transfer(from, to, tokenId);
- }
-
- function _mint(address to, uint256 tokenId) internal virtual override(ERC721, nFR) {
- super._mint(to, tokenId);
- }
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, nFR) returns (bool) {
- return super.supportsInterface(interfaceId);
- }
-
- function tokenURI(uint256 tokenId)
- public
- view
- override(ERC721, ERC721URIStorage)
- returns (string memory)
- {
- return super.tokenURI(tokenId);
- }
-}
diff --git a/assets/eip-5173/Losing_owners.jpeg b/assets/eip-5173/Losing_owners.jpeg
deleted file mode 100644
index 26878c1..0000000
Binary files a/assets/eip-5173/Losing_owners.jpeg and /dev/null differ
diff --git a/assets/eip-5173/Same_owner_using_different_wallets.jpeg b/assets/eip-5173/Same_owner_using_different_wallets.jpeg
deleted file mode 100644
index 7cca2da..0000000
Binary files a/assets/eip-5173/Same_owner_using_different_wallets.jpeg and /dev/null differ
diff --git a/assets/eip-5173/Total_FR_Payout_Distribution-flat.png b/assets/eip-5173/Total_FR_Payout_Distribution-flat.png
deleted file mode 100644
index 8756b13..0000000
Binary files a/assets/eip-5173/Total_FR_Payout_Distribution-flat.png and /dev/null differ
diff --git a/assets/eip-5173/Total_FR_Payout_Distribution-geo.png b/assets/eip-5173/Total_FR_Payout_Distribution-geo.png
deleted file mode 100644
index e0b618b..0000000
Binary files a/assets/eip-5173/Total_FR_Payout_Distribution-geo.png and /dev/null differ
diff --git a/assets/eip-5173/animate-1920x1080-1750-frames.gif b/assets/eip-5173/animate-1920x1080-1750-frames.gif
deleted file mode 100644
index b6a7a88..0000000
Binary files a/assets/eip-5173/animate-1920x1080-1750-frames.gif and /dev/null differ
diff --git a/assets/eip-5173/nFR_Standard_Outline.jpeg b/assets/eip-5173/nFR_Standard_Outline.jpeg
deleted file mode 100644
index 1d0fc2a..0000000
Binary files a/assets/eip-5173/nFR_Standard_Outline.jpeg and /dev/null differ
diff --git a/assets/eip-5173/nFR_distribution_formula.png b/assets/eip-5173/nFR_distribution_formula.png
deleted file mode 100644
index b4f42ac..0000000
Binary files a/assets/eip-5173/nFR_distribution_formula.png and /dev/null differ
diff --git a/assets/eip-5216/ERC1155ApprovalByAmount.sol b/assets/eip-5216/ERC1155ApprovalByAmount.sol
deleted file mode 100644
index ee94e35..0000000
--- a/assets/eip-5216/ERC1155ApprovalByAmount.sol
+++ /dev/null
@@ -1,146 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.15;
-
-import "IERC1155.sol";
-import "ERC1155.sol";
-
-/**
- * @title ERC-1155 Approval By Amount Extension
- * Note: the ERC-165 identifier for this interface is 0x1be07d74
- */
-interface IERC1155ApprovalByAmount is IERC1155 {
-
- /**
- * @notice Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
- * `id` and with an amount: `amount`.
- */
- event ApprovalByAmount(address indexed account, address indexed operator, uint256 id, uint256 amount);
-
- /**
- * @notice Grants permission to `operator` to transfer the caller's tokens, according to `id`, and an amount: `amount`.
- * Emits an {ApprovalByAmount} event.
- *
- * Requirements:
- * - `operator` cannot be the caller.
- */
- function approve(address operator, uint256 id, uint256 amount) external;
-
- /**
- * @notice Returns the amount allocated to `operator` approved to transfer `account`'s tokens, according to `id`.
- */
- function allowance(address account, address operator, uint256 id) external view returns (uint256);
-
-}
-
-/**
- * @dev Extension of {ERC1155} that allows you to approve your tokens by amount and id.
- */
-abstract contract ERC1155ApprovalByAmount is ERC1155, IERC1155ApprovalByAmount {
-
- // Mapping from account to operator approvals by id and amount.
- mapping(address => mapping(address => mapping(uint256 => uint256))) internal _allowances;
-
- /**
- * @dev See {IERC1155ApprovalByAmount}
- */
- function approve(address operator, uint256 id, uint256 amount) public virtual {
- _approve(msg.sender, operator, id, amount);
- }
-
- /**
- * @dev See {IERC1155ApprovalByAmount}
- */
- function allowance(address account, address operator, uint256 id) public view virtual returns (uint256) {
- return _allowances[account][operator][id];
- }
-
- /**
- * @dev safeTransferFrom implementation for using ApprovalByAmount extension
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) public override(IERC1155, ERC1155) {
- require(
- from == msg.sender || isApprovedForAll(from, msg.sender) || allowance(from, msg.sender, id) >= amount,
- "ERC1155: caller is not owner nor approved nor approved for amount"
- );
- unchecked {
- _allowances[from][msg.sender][id] -= amount;
- }
- _safeTransferFrom(from, to, id, amount, data);
- }
-
- /**
- * @dev safeBatchTransferFrom implementation for using ApprovalByAmount extension
- */
- function safeBatchTransferFrom(
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) public virtual override(IERC1155, ERC1155) {
- require(
- from == msg.sender || isApprovedForAll(from, msg.sender) || _checkApprovalForBatch(from, msg.sender, ids, amounts),
- "ERC1155: transfer caller is not owner nor approved nor approved for some amount"
- );
- _safeBatchTransferFrom(from, to, ids, amounts, data);
- }
-
- /**
- * @dev Checks if all ids and amounts are permissioned for `to`.
- *
- * Requirements:
- * - `ids` and `amounts` length should be equal.
- */
- function _checkApprovalForBatch(
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts
- ) internal virtual returns (bool) {
- uint256 idsLength = ids.length;
- uint256 amountsLength = amounts.length;
-
- require(idsLength == amountsLength, "ERC1155ApprovalByAmount: ids and amounts length mismatch");
- for (uint256 i = 0; i < idsLength;) {
- require(allowance(from, to, ids[i]) >= amounts[i], "ERC1155ApprovalByAmount: operator is not approved for that id or amount");
- unchecked {
- _allowances[from][to][ids[i]] -= amounts[i];
- ++i;
- }
- }
- return true;
- }
-
- /**
- * @dev Approve `operator` to operate on all of `owner` tokens by id and amount.
- * Emits a {ApprovalByAmount} event.
- */
- function _approve(
- address owner,
- address operator,
- uint256 id,
- uint256 amount
- ) internal virtual {
- require(owner != operator, "ERC1155ApprovalByAmount: setting approval status for self");
- _allowances[owner][operator][id] = amount;
- emit ApprovalByAmount(owner, operator, id, amount);
- }
-}
-
-contract ExampleToken is ERC1155ApprovalByAmount {
- constructor() ERC1155("") {}
-
- function mint(address account, uint256 id, uint256 amount, bytes memory data) public {
- _mint(account, id, amount, data);
- }
-
- function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) public {
- _mintBatch(to, ids, amounts, data);
- }
-}
diff --git a/assets/eip-5218/contracts/README.md b/assets/eip-5218/contracts/README.md
deleted file mode 100644
index 705973c..0000000
--- a/assets/eip-5218/contracts/README.md
+++ /dev/null
@@ -1,12 +0,0 @@
-# EIP-5218 Reference Implementations
-
-This is the source code for a reference implementation of EIP-5218.
-
-## Build and Test
-
-The repo expects a [Foundry](https://github.com/foundry-rs/foundry/tree/master/forge) build system, optionally using visual studio code for editing. You can run the test suite with:
-
-```bash
-forge test -vvvvv
-```
-
diff --git a/assets/eip-5218/contracts/foundry.toml b/assets/eip-5218/contracts/foundry.toml
deleted file mode 100644
index d7dd144..0000000
--- a/assets/eip-5218/contracts/foundry.toml
+++ /dev/null
@@ -1,6 +0,0 @@
-[default]
-src = 'src'
-out = 'out'
-libs = ['lib']
-
-# See more config options https://github.com/foundry-rs/foundry/tree/master/config
\ No newline at end of file
diff --git a/assets/eip-5218/contracts/remappings.txt b/assets/eip-5218/contracts/remappings.txt
deleted file mode 100644
index 1e11e4d..0000000
--- a/assets/eip-5218/contracts/remappings.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-forge-std/=lib/forge-std/src/
-ds-test/=lib/forge-std/lib/ds-test/src/
-@openzeppelin/=lib/openzeppelin-contracts/
\ No newline at end of file
diff --git a/assets/eip-5218/contracts/src/IERC5218.sol b/assets/eip-5218/contracts/src/IERC5218.sol
deleted file mode 100644
index 334f235..0000000
--- a/assets/eip-5218/contracts/src/IERC5218.sol
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-
-/// @title EIP-5218: NFT Rights Management
-interface IERC5218 is IERC721 {
-
- /// @dev This emits when a new license is created by any mechanism.
- event CreateLicense(uint256 _licenseId, uint256 _tokenId, uint256 _parentLicenseId, address _licenseHolder, string _uri, address _revoker);
-
- /// @dev This emits when a license is revoked. Note that under some
- /// license terms, the sublicenses may be `implicitly` revoked following the
- /// revocation of some ancestral license. In that case, your smart contract
- /// may only emit this event once for the ancestral license, and the revocation
- /// of all its sublicenses can be implied without consuming additional gas.
- event RevokeLicense(uint256 _licenseId);
-
- /// @dev This emits when the a license is transferred to a new holder. The
- /// root license of an NFT should be transferred with the NFT in an ERC721
- /// `transfer` function call.
- event TransferLicense(uint256 _licenseId, address _licenseHolder);
-
- /// @notice Check if a license is active.
- /// @dev A non-existing or revoked license is inactive and this function must
- /// return `false` upon it. Under some license terms, a license may become
- /// inactive because some ancestral license has been revoked. In that case,
- /// this function should return `false`.
- /// @param _licenseId The identifier for the queried license
- /// @return Whether the queried license is active
- function isLicenseActive(uint256 _licenseId) external view returns (bool);
-
- /// @notice Retrieve the token identifier a license was issued upon.
- /// @dev Throws unless the license is active.
- /// @param _licenseId The identifier for the queried license
- /// @return The token identifier the queried license was issued upon
- function getLicenseTokenId(uint256 _licenseId) external view returns (uint256);
-
- /// @notice Retrieve the parent license identifier of a license.
- /// @dev Throws unless the license is active. If a license doesn't have a
- /// parent license, return a special identifier not referring to any license
- /// (such as 0).
- /// @param _licenseId The identifier for the queried license
- /// @return The parent license identifier of the queried license
- function getParentLicenseId(uint256 _licenseId) external view returns (uint256);
-
- /// @notice Retrieve the holder of a license.
- /// @dev Throws unless the license is active.
- /// @param _licenseId The identifier for the queried license
- /// @return The holder address of the queried license
- function getLicenseHolder(uint256 _licenseId) external view returns (address);
-
- /// @notice Retrieve the URI of a license.
- /// @dev Throws unless the license is active.
- /// @param _licenseId The identifier for the queried license
- /// @return The URI of the queried license
- function getLicenseURI(uint256 _licenseId) external view returns (string memory);
-
- /// @notice Retrieve the revoker address of a license.
- /// @dev Throws unless the license is active.
- /// @param _licenseId The identifier for the queried license
- /// @return The revoker address of the queried license
- function getLicenseRevoker(uint256 _licenseId) external view returns (address);
-
- /// @notice Retrieve the root license identifier of an NFT.
- /// @dev Throws unless the queried NFT exists. If the NFT doesn't have a root
- /// license tethered to it, return a special identifier not referring to any
- /// license (such as 0).
- /// @param _tokenId The identifier for the queried NFT
- /// @return The root license identifier of the queried NFT
- function getLicenseIdByTokenId(uint256 _tokenId) external view returns (uint256);
-
- /// @notice Create a new license.
- /// @dev Throws unless the NFT `_tokenId` exists. Throws unless the parent
- /// license `_parentLicenseId` is active, or `_parentLicenseId` is a special
- /// identifier not referring to any license (such as 0) and the NFT
- /// `_tokenId` doesn't have a root license tethered to it. Throws unless the
- /// message sender is eligible to create the license, i.e., either the
- /// license to be created is a root license and `msg.sender` is the NFT owner,
- /// or the license to be created is a sublicense and `msg.sender` is the holder
- /// of the parent license.
- /// @param _tokenId The identifier for the NFT the license is issued upon
- /// @param _parentLicenseId The identifier for the parent license
- /// @param _licenseHolder The address of the license holder
- /// @param _uri The URI of the license terms
- /// @param _revoker The revoker address
- /// @return The identifier of the created license
- function createLicense(uint256 _tokenId, uint256 _parentLicenseId, address _licenseHolder, string memory _uri, address _revoker) external returns (uint256);
-
- /// @notice Revoke a license.
- /// @dev Throws unless the license is active and the message sender is the
- /// eligible revoker. This function should be used for revoking both root
- /// licenses and sublicenses. Note that if a root license is revoked, the
- /// NFT should be transferred back to its creator.
- /// @param _licenseId The identifier for the queried license
- function revokeLicense(uint256 _licenseId) external;
-
- /// @notice Transfer a sublicense.
- /// @dev Throws unless the sublicense is active and `msg.sender` is the license
- /// holder. Note that the root license of an NFT should be tethered to and
- /// transferred with the NFT. Whenever an NFT is transferred by calling the
- /// ERC721 `transfer` function, the holder of the root license should be
- /// changed to the new NFT owner.
- /// @param _licenseId The identifier for the queried license
- /// @param _licenseHolder The new license holder
- function transferSublicense(uint256 _licenseId, address _licenseHolder) external;
-}
-
diff --git a/assets/eip-5218/contracts/src/RightsManagement.sol b/assets/eip-5218/contracts/src/RightsManagement.sol
deleted file mode 100644
index 179b1cd..0000000
--- a/assets/eip-5218/contracts/src/RightsManagement.sol
+++ /dev/null
@@ -1,234 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC5218.sol";
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/utils/Counters.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
-
-
-contract RightsManagement is IERC5218, ERC721URIStorage, Ownable {
- struct License {
- bool active; // whether the current license is active
- uint256 tokenId;
- uint256 parentLicenseId;
- address licenseHolder;
- string uri;
- address revoker;
- }
- mapping(uint256 => License) private _licenses;
- mapping(uint256 => uint256) private _licenseIds;
-
- using Counters for Counters.Counter;
- Counters.Counter private _tokenCounter;
- Counters.Counter private _licenseCounter;
-
- constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) {}
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
- return
- interfaceId == type(IERC5218).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- function isLicenseActive(uint256 licenseId) public view virtual override(IERC5218) returns (bool) {
- if (licenseId == 0) return false;
- while (licenseId != 0) {
- if (!_licenses[licenseId].active) return false;
- licenseId = _licenses[licenseId].parentLicenseId;
- }
- return true;
- }
-
- modifier isActiveLicense(uint256 licenseId) {
- require(isLicenseActive(licenseId), "The queried license is not active");
- _;
- }
-
- function getLicenseTokenId(uint256 licenseId) public view virtual override(IERC5218) isActiveLicense(licenseId) returns (uint256) {
- return _licenses[licenseId].tokenId;
- }
-
- function getParentLicenseId(uint256 licenseId) public view virtual override(IERC5218) isActiveLicense(licenseId) returns (uint256) {
- return _licenses[licenseId].parentLicenseId;
- }
-
- function getLicenseHolder(uint256 licenseId) public view virtual override(IERC5218) isActiveLicense(licenseId) returns (address) {
- return _licenses[licenseId].licenseHolder;
- }
-
- function getLicenseURI(uint256 licenseId) public view virtual override(IERC5218) isActiveLicense(licenseId) returns (string memory) {
- return _licenses[licenseId].uri;
- }
-
- function getLicenseRevoker(uint256 licenseId) public view virtual override(IERC5218) isActiveLicense(licenseId) returns (address) {
- return _licenses[licenseId].revoker;
- }
-
- function getLicenseIdByTokenId(uint256 tokenId) public view virtual override(IERC5218) returns (uint256) {
- require (_exists(tokenId), "The token doesn't exist");
- return _licenseIds[tokenId];
- }
-
- function safeMint(
- address recipient,
- string memory tokenURI,
- string memory licenseURI,
- address licenseRevoker
- )
- public virtual onlyOwner
- returns (uint256)
- {
- return safeMint(recipient, tokenURI, licenseURI, licenseRevoker, "");
- }
-
- function safeMint(
- address recipient,
- string memory tokenURI,
- string memory licenseURI,
- address licenseRevoker,
- bytes memory _data
- )
- public virtual onlyOwner
- returns (uint256)
- {
- _tokenCounter.increment();
- uint256 newItemId = _tokenCounter.current();
-
- _safeMint(recipient, newItemId, _data);
- _setTokenURI(newItemId, tokenURI);
- _createLicense(newItemId, 0, recipient, licenseURI, licenseRevoker);
-
- return newItemId;
- }
-
- function safeIssue(
- address recipient,
- uint256 tokenId,
- string memory licenseURI,
- address licenseRevoker
- )
- public virtual
- returns (uint256)
- {
- return safeIssue(recipient, tokenId, licenseURI, licenseRevoker, "");
- }
-
- function safeIssue(
- address recipient,
- uint256 tokenId,
- string memory licenseURI,
- address licenseRevoker,
- bytes memory data
- )
- public virtual
- returns (uint256)
- {
- require(_licenseIds[tokenId] == 0, "The token has an active license");
- require(ownerOf(tokenId) == owner(), "The creator doesn't own the NFT");
-
- uint256 licenseId = createLicense(tokenId, 0, owner(), licenseURI, licenseRevoker);
- safeTransferFrom(owner(), recipient, tokenId, data);
-
- return licenseId;
- }
-
- function createLicense(
- uint256 tokenId,
- uint256 parentLicenseId,
- address licenseHolder,
- string memory uri,
- address revoker
- )
- public virtual override(IERC5218)
- returns (uint256)
- {
- require(_exists(tokenId), "The NFT doesn't exists");
- require(parentLicenseId == 0 || isLicenseActive(parentLicenseId), "The parent license is not active");
- require(parentLicenseId != 0 || getLicenseIdByTokenId(tokenId) == 0, "The NFT already has a root license");
- require(
- (parentLicenseId == 0 && msg.sender == owner()) ||
- (parentLicenseId != 0 && msg.sender == _licenses[parentLicenseId].licenseHolder),
- "Sender is not eligible to grant a new license"
- );
-
- return _createLicense(tokenId, parentLicenseId, licenseHolder, uri, revoker);
- }
-
- function revokeLicense(uint256 licenseId) public virtual override(IERC5218) {
- require(isLicenseActive(licenseId), "The license is not active");
- require(msg.sender == _licenses[licenseId].revoker, "The msg sender is not an eligible revoker");
-
- if (_licenses[licenseId].parentLicenseId == 0) {
- _transfer(ownerOf(_licenses[licenseId].tokenId), owner(), _licenses[licenseId].tokenId);
- }
-
- _revokeLicense(licenseId);
- }
-
- function transferSublicense(uint256 licenseId, address licenseHolder) public virtual override(IERC5218) {
- require(isLicenseActive(licenseId), "The license is not active");
- require(_licenses[licenseId].parentLicenseId != 0, "The license is a root license");
- require(msg.sender == _licenses[licenseId].licenseHolder, "The msg sender is not the license holder");
-
- _updateLicenseHolder(licenseId, licenseHolder);
- }
-
- function _transfer(address from, address to, uint256 tokenId) internal virtual override(ERC721) {
- require(_licenseIds[tokenId] != 0 && isLicenseActive(_licenseIds[tokenId]), "The token has no active license tethered to it");
- require(_licenses[_licenseIds[tokenId]].licenseHolder == ownerOf(tokenId), "The license holder and the NFT owner are inconsistent");
-
- super._transfer(from, to, tokenId);
- _updateLicenseHolder(_licenseIds[tokenId], to);
- }
-
- function _updateLicenseHolder(uint256 licenseId, address licenseHolder) internal virtual {
- _licenses[licenseId].licenseHolder = licenseHolder;
- emit TransferLicense(licenseId, licenseHolder);
- }
-
- function _createLicense(
- uint256 tokenId,
- uint256 parentLicenseId,
- address licenseHolder,
- string memory uri,
- address revoker
- )
- internal virtual
- returns (uint256)
- {
- _licenseCounter.increment();
- uint256 licenseId = _licenseCounter.current();
-
- _licenses[licenseId].active = true;
- _licenses[licenseId].tokenId = tokenId;
- _licenses[licenseId].parentLicenseId = parentLicenseId; // tyler: it seems like a security problem that children are able to overwrite their parents
- _licenses[licenseId].licenseHolder = licenseHolder;
- _licenses[licenseId].uri = uri;
- _licenses[licenseId].revoker = revoker;
-
- if (parentLicenseId == 0) {
- _licenseIds[tokenId] = licenseId;
- }
-
- emit CreateLicense(licenseId, tokenId, parentLicenseId, licenseHolder, uri, revoker);
- return licenseId;
- }
-
- function _revokeLicense(uint256 licenseId) internal virtual {
- if (_licenses[licenseId].parentLicenseId == 0) {
- _licenseIds[_licenses[licenseId].tokenId] = 0;
- }
-
- delete _licenses[licenseId];
-
- emit RevokeLicense(licenseId);
- }
-}
-
-
-
diff --git a/assets/eip-5218/contracts/test/Contract.t.sol b/assets/eip-5218/contracts/test/Contract.t.sol
deleted file mode 100644
index 84a2e6c..0000000
--- a/assets/eip-5218/contracts/test/Contract.t.sol
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.13;
-
-import "forge-std/Test.sol";
-import "../src/RightsManagement.sol";
-
-contract ContractTest is Test {
-
- event CreateLicense(
- uint256 licenseId,
- uint256 tokenId,
- uint256 parentLicenseId,
- address licenseHolder,
- string uri,
- address revoker
- );
- event RevokeLicense(uint256 licenseId);
- event TransferLicense(uint256 licenseId, address licenseHolder);
-
- //Vm vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
- RightsManagement rm;
-
- address add1 = address(0xadd1);
- address add2 = address(0xadd2);
- address add3 = address(0xadd3);
- string tokenURI = "tokenURI";
- string licenseURI = "licenseURI";
- string sublicenseURI = "sublicenseURI";
-
- function setUp() public {
- vm.deal(add1, 12 ether);
- vm.deal(add2, 12 ether);
- vm.deal(add3, 12 ether);
-
- rm = new RightsManagement("MyNFT", "NFT");
- }
-
- function testMint() public {
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit CreateLicense(1, 1, 0, add1, licenseURI, add3); // the expected log you expect to see emitted
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
- address tokenOwner = rm.ownerOf(tokenId);
- assertEq(add1, tokenOwner, "tokenOwner should match");
- uint256 licenseId = rm.getLicenseIdByTokenId(tokenId);
- assertEq(rm.isLicenseActive(0), false, "License 0 should be inactive");
- assertEq(rm.isLicenseActive(licenseId), true, "License should be active");
- assertEq(rm.getLicenseURI(licenseId), licenseURI, "License should match");
- assertEq(rm.getLicenseHolder(licenseId), add1, "LicenseHolder should match");
- assertEq(rm.getLicenseTokenId(licenseId), 1, "TokenId should match");
- assertEq(rm.getParentLicenseId(licenseId), 0, "Parent License Id should match");
- assertEq(rm.getLicenseRevoker(licenseId), add3, "License revoker should match");
- }
-
- function testCreateLicense() public {
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
- uint parentLicenseId = rm.getLicenseIdByTokenId(tokenId);
-
- vm.startPrank(add1);
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit CreateLicense(2, 1, 1, add2, sublicenseURI, add3); // the expected log you expect to see emitted
- uint licenseId = rm.createLicense(tokenId, parentLicenseId, add2, sublicenseURI, add3);
- vm.stopPrank();
-
- vm.expectRevert("Sender is not eligible to grant a new license");
- licenseId = rm.createLicense(tokenId, parentLicenseId, add2, sublicenseURI, add3);
- }
-
- function testRevokeLicense() public {
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
- uint parentLicenseId = rm.getLicenseIdByTokenId(tokenId);
-
- vm.startPrank(add1);
- uint licenseId = rm.createLicense(tokenId, parentLicenseId, add2, sublicenseURI, add3);
- vm.stopPrank();
-
- vm.startPrank(add2);
- licenseId = rm.createLicense(tokenId, licenseId, add3, sublicenseURI, add3);
- vm.stopPrank();
-
- vm.startPrank(add3);
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit RevokeLicense(2); // the expected log you expect to see emitted
- rm.revokeLicense(2);
- vm.stopPrank();
-
- vm.startPrank(add3);
- vm.expectRevert("The license is not active");
- rm.revokeLicense(3);
- vm.stopPrank();
-
-
- vm.startPrank(add1);
- vm.expectRevert("The msg sender is not an eligible revoker");
- rm.revokeLicense(1);
- vm.stopPrank();
-
- vm.startPrank(add3);
- rm.revokeLicense(1);
- vm.stopPrank();
- assertEq(rm.ownerOf(1), address(this), "The token should be returned to creator after revoking its license");
-
- assertEq(rm.getLicenseIdByTokenId(1), 0, "The token should not have an active license");
- }
-
- function testTransfer() public {
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
-
- vm.startPrank(add3);
- rm.revokeLicense(1);
- vm.stopPrank();
-
- vm.expectRevert("The token has no active license tethered to it");
- rm.safeTransferFrom(address(this), add1, 1);
-
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit CreateLicense(2, 1, 0, address(this), licenseURI, add3); // the expected log you expect to see emitted
- rm.createLicense(tokenId, 0, address(this), licenseURI, add3);
-
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit TransferLicense(2, add2); // the expected log you expect to see emitted
- rm.safeTransferFrom(address(this), add2, 1);
- assertEq(rm.getLicenseIdByTokenId(1), 2, "License Id linked to tokenId");
- assertEq(rm.getLicenseHolder(2), add2, "License holder updated");
- }
-
- function testIssue() public {
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
-
- vm.startPrank(add3);
- rm.revokeLicense(1);
- vm.stopPrank();
-
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit CreateLicense(2, 1, 0, address(this), licenseURI, add3); // the expected log you expect to see emitted
- emit TransferLicense(2, add2); // the expected log you expect to see emitted
- rm.safeIssue(add2, tokenId, licenseURI, add3);
- assertEq(rm.getLicenseIdByTokenId(1), 2, "License Id linked to tokenId");
- assertEq(rm.getLicenseHolder(2), add2, "License holder updated");
- }
-
- function testTransferSublicense() public {
- uint tokenId = rm.safeMint(add1, tokenURI, licenseURI, add3);
-
- vm.startPrank(add3);
- rm.revokeLicense(1);
- vm.stopPrank();
-
- vm.expectRevert("The license is not active");
- rm.transferSublicense(1, add2);
-
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit CreateLicense(2, 1, 0, add1, licenseURI, add3); // the expected log you expect to see emitted
- rm.createLicense(tokenId, 0, add1, licenseURI, add3);
-
- vm.expectRevert("The license is a root license");
- rm.transferSublicense(2, add2);
-
- vm.startPrank(add1);
- rm.createLicense(tokenId, 2, add2, licenseURI, add3);
- vm.stopPrank();
-
- vm.expectRevert("The msg sender is not the license holder");
- rm.transferSublicense(3, add1);
-
- vm.startPrank(add2);
- vm.expectEmit(true,true,true,true); // put this two lines before you actually call the function
- emit TransferLicense(3, add1); // the expected log you expect to see emitted
- rm.transferSublicense(3, add1);
- vm.stopPrank();
- }
-}
diff --git a/assets/eip-5218/ic3license/ic3license.pdf b/assets/eip-5218/ic3license/ic3license.pdf
deleted file mode 100644
index 351a73f..0000000
Binary files a/assets/eip-5218/ic3license/ic3license.pdf and /dev/null differ
diff --git a/assets/eip-5218/ic3license/ic3license.tex b/assets/eip-5218/ic3license/ic3license.tex
deleted file mode 100644
index 2c665dd..0000000
--- a/assets/eip-5218/ic3license/ic3license.tex
+++ /dev/null
@@ -1,355 +0,0 @@
-\documentclass{article}
-
-\usepackage[hidelinks]{hyperref}
-\usepackage{libertine}
-\usepackage{authblk}
-
-\title{The \iccclicense\\}
-\author{The Institute for Cryptocurrencies and Contracts (IC3) \and The Coalition of Automated Legal Applications (COALA)}
-\date{Version 1.0\\\today}
-
-\usepackage{xspace}
-
-\newcommand{\eiplicense}{EIP-5218\xspace}
-\newcommand{\iccclicense}{Token-Bound NFT License\xspace}
-
-\newcommand{\keyword}[1]{\textbf{#1}\xspace}
-
-\newcommand{\publiclicense}{\keyword{Public-License}}
-\newcommand{\nopubliclicense}{\keyword{No-Public-License}}
-
-\newcommand{\commercial}{\keyword{Commercial}}
-\newcommand{\noncommercial}{\keyword{Non-Commercial}}
-
-\newcommand{\noderivative}{\keyword{No-Derivatives}}
-\newcommand{\derivative}{\keyword{Derivatives}}
-\newcommand{\derivativetracking}{\keyword{Derivatives-NFT}}
-\newcommand{\sharealike}{\keyword{Derivatives-NFT-Share-Alike}}
-
-\newcommand{\ledger}{\keyword{Ledger-Authoritative}}
-\newcommand{\legal}{\keyword{Legal-Authoritative}}
-
-\newcommand{\personal}{\keyword{Personal}}
-\newcommand{\conditional}{\keyword{Conditional}}
-
-
-\usepackage{semantic-markup}
-
-\newcommand{\sect}[1]{\vspace{12pt}\noindent{\strong{#1}}}
-\newcommand{\subsect}[1]{\vspace{12pt}\noindent{\em{#1}}}
-
-
-\usepackage{xcolor}
-
-\definecolor{light-gray}{gray}{0.9}
-
-\renewcommand{\code}[1]{\colorbox{light-gray}{\texttt{#1}}}
-
-\newcommand{\iflicenseoption}[2]{[\colorbox{light-gray}{If #1:} #2]}
-\newcommand{\ifnotlicenseoption}[2]{[\colorbox{light-gray}{Unless #1:} #2]}
-
-\begin{document}
-
-\maketitle
-
-\tableofcontents
-
-\section{Introduction}
-
-The \iccclicense is a copyright license specifically designed for use with NFTs. It links a creative work to an NFT so that when the NFT is transferred, so is the license. It is intended to be compatible with the NFT licensing standard defined in \eiplicense.
-
-The \iccclicense has four optional features that a licensor can use or not when choosing a license:
-\begin{itemize}
-\item The license can be \commercial (C) or \noncommercial (NC). A \commercial license allows the user to make money from merchandise and other uses of the work; a \noncommercial license does not.
-\item The license can be \derivative (D), \derivativetracking (DT), \sharealike (DTSA), or \noderivative (ND). A \derivative license allows the user to make derivative works and adaptations (like remixes and videos) without restriction. A \derivativetracking license allows derivative works but requires them to be registered and tracked as NFTs themselves. A \sharealike license is like \derivativetracking but also requires that the derivative works be relicensed under the same license. And a \noderivative license prohibits derivative works entirely. (These options are ordered from least restrictive to most restrictive.)
-\item The license can be \publiclicense (PL) or \nopubliclicense (NPL). A \publiclicense license, in addition to the specific rights granted to the user, grants to the public a broad copyright license to reproduce the work (but not to make derivative works). A \nopubliclicense license grants only the specific rights to the user.
-\item The license can be \ledger (Ledger) or \legal (Legal). A \ledger license means that the current state of the blockchain ledger is always authoritative for who owns the NFT and has rights under the license, even if the NFT is stolen or transferred by mistake. A \legal license gives the courts flexibility to correct ownership of the license in clear cases of theft and fraud.
-\end{itemize}
-All four options are independent, so that they can be set for a choice of thirty-two total licenses, e.g. NC-D-NPL-Ledger means the license version that allows only Non-Commercial uses, allows Derivative works, includes No Public License, and makes the Ledger authoritative for the state of the license. Once an \iccclicense has been used on an NFT, that license stays with it. The licensor should not expect to be able to choose a different license after the initial release.
-
-The simplest combination of license options is C-D-NPL-Ledger, which provides a straightforward license that gives the current owner of the NFT (as defined by the blockchain) full rights over the associated work. This is the default \iccclicense; the other license options can be thought of as variations on it.
-
-The rest of this document describes the design choices of the \iccclicense. Appendix \ref{sec:human} provides a short human-readable summary of the license terms. Appendix \ref{sec:text} contains the actual text of the license family.
-
-
-\section{Design Goals}
-
-
-The \iccclicense has been specifically designed to work with blockchain-based NFTs, e.g. with smart contracts that implement the standard defined in \href{https://eips.ethereum.org/EIPS/eip-721}{EIP-721}. But it is not restricted to blockchain-based NFTs. The license uses the technology-neutral term ``Ledger'' to refer to the system that records information about NFTs and their owners. This could be a present-day blockchain, or another chain or system that could be created in the future. The license can be used with any underlying technology as long as it:
-\begin{enumerate}
-\item Supports NFTs based on persistent unique identifiers,
-\item Associates those NFTs with specific owners,
-\item Allows the owner of an NFT to control it with a cryptographic key, and
-\item Allows an NFT to be linked to a creative work.
-\end{enumerate}
-This system can be widely distributed (like a public blockchain), moderately distributed (like a private blockchain), or fully centralized (like a database with a single administrator). Use of the \iccclicense for other kinds of licensing is strongly discouraged.
-
-The \iccclicense has also been specifically designed to work with NFTs that implement the interface defined in \eiplicense. This is a general smart-contract interface that provides modular support for common features in copyright licensing, including transfer, sublicensing, and revocation. The \iccclicense can also be used with NFTs that implement the generic NFT interface defined in EIP-721, or with other NFTs, but the \eiplicense interface is recommended to reduce ambiguity about when there has been a transfer, sublicense, or revocation.
-
-
-\section{Taking Effect}
-
-The \iccclicense is structured as a license, rather than a contract. The licensor unilaterally grants a copyright license to the current owner of the NFT. The owner does not need to do anything to accept the license; they receive it automatically. If the owner transfers the NFT to someone else, the license transfers with it. The old owner is no longer licensed; the new owner receives a license on exactly the same terms. This too is automatic, the new owner does not need to do anything to accept the license.
-
-Standard techniques used by lawyers to create binding terms of use for websites do not work for NFTs on blockchains. Consider the clickthrough agreements used by websites: when you create an account, you must check a box indicating that you agree to the website's terms of use. This works because you have taken an action (checking the box) that is clearly and specifically linked to the legal terms and nothing else. There is no question about whether you meant to agree when you checked the box, because there is no other reason to check the box.
-
-But a blockchain does not have a checkbox or even a website. Someone who receives an EIP-721 NFT need not have done anything at all. They may never have visited the NFT sponsor's website, or even know that there is a website. An NFT could migrate from one resale platform to another; someone who has agreed to one platform's terms might not have agreed to the other's. This means that any promises by the \emph{licensee} in an NFT license contract are illusory. The licensor has no guarantee that a downstream NFT owner has actually agreed to the license terms. Thus, the \iccclicense does not give the licensee any duties, so there is no need for them to agree to anything.
-
-On the other hand, the \iccclicense does attempt to ensure that the \emph{licensor} has clearly indicated their intent to be bound by the license terms. It does so by saying that the license becomes effective when the licensor ``Invokes'' it through a ``Licensing Process,'' i.e., uses a technical process to connect an NFT with the \iccclicense. This definition includes (but is not limited to) the \eiplicense interface.
-
-The essential idea of \eiplicense is to make it explicit when a licensor intends to create a copyright license. This signal is clearest when the licensor takes an act that (a) says that it creates a license, and (b) does not do anything else. Signing a licensing contract on paper meets this test, because the paper says that it creates a license and the only reason to sign it is to create the license. \eiplicense is intended to be a smart-contract version of that piece of paper.
-
-The \iccclicense can be used with any smart contract or other technical process that meets the definition of a Licensing Process. It is not intended to be used on a website or in other off-chain settings where on-chain transactions do not link out to the license. It is not recommended to use the \iccclicense as part of a larger multi-step architecture unless there is some individual step in the system that meets the definition of a Licensing Process in which the licensor clearly indicates their intent to create a license.
-
-
-\section{License Terms}
-
-We have tried in \iccclicense to capture the most common and important use cases in light of the NFT community's responses to previous licenses. But our goal has been simplicity rather than perfection. We hope and expect that over time, others will build on and remix the ideas in the license to terms for more advanced use cases.
-
-The \iccclicense applies to ``Licensed Material'' that is ``Linked'' to an NFT. The definition of Licensed Material is deliberately broad: it can include highly creative works like images or videos, but it also includes ``other material'' to include datasets, software, or other works that are not primarily artistic. The definition of Linked is also broad: it can be by hyperlink, by description, by IPFS CID, by hash value, by an on-chain reference, etc. What is important is that the NFT must be connected to specific licensed material in a way that cannot change over time. We do not attempt to solve the (very difficult) problems of creating a technical standard or a license for an NFT whose contents can change over time.
-
-The core license grant in the \iccclicense is that the NFT owner can ``Use'' the licensed material, i.e. exercise all of the usual rights under copyright to make copies of the work and share them with the public. This is an unlimited grant: it covers all media, digital and analog, on-chain and off-chain.
-
-The license grant is non-exclusive. It is not currently possible to guarantee that only one NFT has been made of a work, or that there are no other off-chain uses of the work.
-
-Drawing on the success of the Creative Commons license suite, the \iccclicense can be customized in four ways:
-\begin{enumerate}
-\item To be either \commercial or \noncommercial.
-\item To allow \derivative works, to allow them but require that they be \derivativetracking on chain, to allow them but require that they be relicensed under \sharealike terms, or to specify that \noderivative works are allowed at all.
-\item To grant a \publiclicense to members of the public besides the NFT owner, or to grant \nopubliclicense.
-\item To track ownership of the NFT entirely on-chain (\ledger) or to follow the legal system's rules on ownership (\legal). (This option is discussed in section~\ref{sec:trans}.)
-\end{enumerate}
-These four options can be set independently, for a total of 32 theoertically possible license variations. However, it does not generally make sense to use both \noderivative and \publiclicense options, because then the NFT owner doesn't receive any useful rights beyond what everyone receives under the public license grant.
-
-Regardless of which license options are used, all versions of the \iccclicense include two specific uses that are always allowed. First, the material can be used to sell the NFT, e.g. on an online NFT marketplace listing. This is an essential part of truth in advertising; someone considering buying the NFT typically needs to be able to see what creative work they will actually be getting. A similar clause is present in many other NFT licenses, although we have attempted to generalize it so that it is less tied to the specifics of how any particular NFT marketplace works. Second, the \iccclicense generally allows free use of the material to identify the NFT owner publicly, e.g. in a social-media profile. This too is widespread in the NFT community and widely allowed by other NFT licenses.
-
-
-\subsection{Commercial Uses}
-
-If the license is \noncommercial, it excludes any uses directed to ``commercial advantage or monetary compensation,'' which includes any cases in which people are required to pay to get a copy of the work. The definition of the \noncommercial license option specifically \emph{allows} the sale of the NFT itself. The resale of NFTs, like the resale of unique works of fine art, is a recognized and important use case. What the \noncommercial license option prohibits is the commercialization of the work by making and selling \emph{other} copies of the work, such as selling posters of an image attached to an NFT, or creating a video series based on a character depicted in a work associated with an NFT.
-
-Whether the license is \commercial or \noncommercial, no royalties are required. Under the \commercial license option, the NFT owner is allowed to keep all of their revenues from commercializing the work. Under the \noncommercial license option, such commercialization is not allowed at all, and constitutes a breach of the license allowing the licensor to sue for infringement. Royalties pose complicated computation and drafting problems, which we have not attempted to solve. If a platform charges a fee for an NFT listing or sale, this is neither required nor prohibited by the \iccclicense; it is an issue between the NFT owner and the platform, not between the NFT owner and the licensor.
-
-Similarly, if the NFT owner sells the NFT, this is not an event that entitles the NFT owner to any royalties under this license. This does not prevent the \iccclicense from being used with a smart contract that requires royalty payments. We merely have not attempted to make payment of royalties part of the copyright license. For example, a smart contract could tie invocation of NFT transfer functions to payment of required royalties. (But see \href{https://eips.ethereum.org/EIPS/eip-2981}{EIP-2981} (NFT Royalty Standard) for discussion of the reasons why such requirements may not be effective in practice.)
-
-\subsection{Derivative Works}
-
-If the licensor chooses to allow derivative works with \derivative, \derivativetracking, or \sharealike, the license grant also allows the NFT owner to use ``Adapted Material,'' which uses language from the Creative Commons license suite to define what counts as a derivative work. To reflect the customs of the NFT community, we added language to make clear that simply reproducing the work in a different medium -- e.g., printing T-shirts of a JPEG -- doesn't count as making a derivative work. Only new projects -- such as modifying artwork, remixing a song, or making a TV series based on a character -- are derivative works.
-
-The options to enable derivative works are cumulative: \derivative enables the creation of derivative works in all circumstances, \derivativetracking includes the derivative conditions, and introduces additional requirements concerning the technical properties of the NFT associated with the derivative work; and \sharealike includes all of the above conditions, and introduces an additional requirement concerning the legal licensing terms of the derivative work.
-
-When the license requires \derivativetracking, the grant of permission to make derivative works is conditional on creating an NFT for the derivative work that (1) subsists on the same ledger as the original NFT; (2) has materially the same properties and functionality as the original NFT; (3) causes the derivative NFT to reference the original NFT in such a way as to ensure that for each NFT, it is technically straightforward to identify all of its derivative NFTs. This option implements a \emph{technical} compatibility condition, one that aims to keep derivative works on the \emph{same technical standard} and on the \emph{same ledger} as the original NFT.
-
-When the license requires Share-Alike, the requirement of using the same technical mechanism (as prescribed by \derivativetracking) is supplemented with the further requirement that the derivative work be licensed using the same licensing terms. This is a \emph{legal compatibility} condition; it closely corresponds to the Share-Alike license option in the Creative Commons license suite. Note that \sharealike implies \derivativetracking because in the context of NFTs, the point of a Share-Alike license could be defeated by tying the license to a derivative-work NFT whose technical implementation departed too significantly from the implementation of the underlying NFT. This means that not only must the NFT associated with the derivative work implement the same technical standards, but it must also adopt the same properties and parameters as the original-work NFT in order to comply with the terms of the legal license.
-
-\subsection{Public Licenses}
-
-One common use case for NFTs is to reserve a few privileges for the NFT owner while giving the public a license to use the creative work associated with the NFT. This could be accomplished through dual licensing, in which the creator explicitly uses one license for the NFT owner and another for the public. But this approach is unsatisfactory; dual licensing gives up some of the convenience and clarity of having all of the relevant license terms clearly located in one place. Nor is it appropriate to include a public license in every version of the NFT license. The public-license model for NFTs is not universal; many NFTs give rights in the creative work only to the NFT owner.
-
-Thus, the \iccclicense includes a public license as a license option. When \publiclicense is selected, the license grants described above, which give specific broad rights to the NFT owner, are accompanied by a public license grant (specifically, a Creative Commons Attribution-NoDerivatives license) that gives the public the right to use the work, but not to make derivative works.
-
-
-
-\section{Transfer}
-\label{sec:trans}
-
-The \iccclicense tries to deal sensibly with the many complications that can arise due to the unrestricted transferability of NFTs. Most existing NFT licenses have not taken this possibility seriously, even though it is arguably the defining characteristic of NFTs and the one that makes them most appealing to users.
-
-The first major issue is that NFTs can be, and frequently are, stolen. A hacker or phisher gains access to an NFT owner's private key and uses it to transfer the NFT to themselves, frequently turning around and immediately reselling it. Under these circumstances, should the \emph{copyright} license go to the new NFT owner or stay with the previous NFT owner?
-\begin{itemize}
-\item Many blockchain technologists believe that the first answer is obviously correct. The license follows whoever is the owner of the NFT according to the blockchain. The previous NFT owner's license terminates, and the new NFT owner receives a license. This approach makes the blockchain reliable, but it also makes it difficult for NFT owners to commercialize derivative works of their NFTs unless they take extreme security measures.
-\item Many lawyers believe that the second answer is obviously correct. The license stays with the true owner of the NFT according to property law. The previous NFT owner retains their copyright license, and the thief takes nothing. This approach protects NFT owners against theft, fraud, and duress, and makes the NFT copyright licensing more consistent with the rest of the legal system, but it makes the blockchain non-authoritative and can require additional investigation on the part of buyers and licensees.
-\end{itemize}
-
-This is an irreconcilable difference of views about how ledgers ought to operate, and a copyright license cannot resolve this deeper split of opinion within the NFT community. Instead, the \iccclicense provides both options, and the licensor can choose which one to use by choosing an appropriate variant of the license. The first option is called \ledger because it makes the ledger authoritative as to ownership. The second option is called called \legal because it makes the legal system authoritative as to ownership.
-
-To keep the distinction clear, the license uses the term ``Controller'' for the person who has control of an NFT via a private key, and ``Owner'' for the person who is legally entitled to the license. The \ledger option is implemented by defining the Owner to be the Controller (so the two concepts are the same), and the \legal option by defining the Owner to be the ``person or entity who is legally entitled to be its Controller.'' (In theory, it would be possible for a license to fine-tune the circumstances under which it does and does not transfer by stating its own rules, but at the cost of decreased compatibility with both the blockchain and with the legal system. The \iccclicense does not attempt this task.)
-
-The licensor may optionally provide a ``Grace Period'' as part of the smart contract for the NFT. If present, it allows a NFT owner to continue using the work (but not to create new derivatives of it) for a period of time following the transfer of the NFT. The Grace Period is defined in terms of a ``Grace Period Process,'' e.g. a smart-contract method that indicates whether the grace period has expired or not. In our view, this is the most general solution to the question of how long a grace period should be, if any. The licensor is not locked in to any particular choice, and putting this function in the smart-contract logic avoids any difficulties translating human-readable terms like ``two days'' into computation-friendly form.
-
-\section{Revocation}
-
-The \iccclicense can be revoked, but it does not define the conditions of revocation. This may seem paradoxical, but it reflects the design goal of making the license itself simple and modular. Instead, the license \emph{defers} to the smart contract that invoked it in the first place. If that contract says that the license has been revoked, it has been.
-
-The reasoning for this design choice can be illustrated by considering the \eiplicense interface, which defines a generic \code{revokeLicense()} method that can be called by a \code{\_revoker} address designated by the creator of the license. Thus, the following are all possible:
-\begin{itemize}
-\item The \code{\_revoker} is the licensor. The license can only be revoked with the consent of the licensor.
-\item The \code{\_revoker} is the licensee. The license can only be revoked with the consent of the licensee.
-\item The \code{\_revoker} is the zero address. The license is irrevocable.
-\item The \code{\_revoker} is a smart contract which can be invoked by anyone to call the \eiplicense \code{revokeLicense()} method after the passage of 30 days from the time the license is issued. The license is for a limited time.
-\item The \code{\_revoker} is a smart contract which can be invoked to call the \eiplicense \code{revokeLicense()} method upon the payment of a specified amount to the licensee. The licensor has an option to buy out the licensee.
-\end{itemize}
-In other words, the \eiplicense is completely generic in supporting arbitrary licensing logic, and because the \iccclicense defers to the Licensing Process (e.g., smart contract), it is also completely generic. Once again, the license is designed to work with the \eiplicense interface, but it is drafted so that any technical process serving the same function can be used instead.
-
-\section{Sublicensing}
-
-The \iccclicense takes a similarly broad and deferential attitude toward sublicensing. In practice, sublicensing is likely to be particularly useful in two scenarios. First, the owner may wish to contract with others to produce goods embodying the work, like T-shirts or song downloads. Here, a sublicense is practically necessary in a world where people don't personally print T-shirts and host downloads, but instead hire professionals to do it for them. Second, sublicensing is necessary for many derivative works: producing an animated video series, for example, will require a sublicense to a production company. Thus, the license generally allows for the free sublicensing of any of the rights held by the NFT owner.
-
-The \iccclicense does not attempt to enforce the requirement that a sublicense be compatible with the license it is issued under. The sublicense need not be the \iccclicense; indeed, it usually will not be. It is up to the sublicensor to choose license terms that are appropriate and are within the scope of their own license. What the \eiplicense standard can do is ensure that a party checking the licensing status of an NFT can see all of the licenses and sublicenses in force. But in general, the sublicenses may be arbitrary human-readable documents, rather than standardized machine-readable ones; it is up to the human reading them to understand their terms. (Future licenses and technical standards may fill in more sublicensing options and provide technical mechanisms to describe them; we have not attempted to solve these problems here and now.)
-
-As with revocation, the \iccclicense allows for a sublicense to be recorded on the blockchain, and as with revocation, these sublicenses are specifically supported by the \eiplicense interface. Again, the support is generic; the sublicense must include a link to its terms, and the \eiplicense interface does not attempt to verify that the sublicense's terms are compatible with the license's terms. Indeed, the license does not require that all sublicenses be explicitly recorded in the smart contract; for a T-shirt vendor or a web host, this is overkill.
-
-Instead, the advantage of recording a sublicense on the blockchain is that it makes the sublicense transfer with the NFT. The \iccclicense provides that all sublicenses that have been recorded this way carry over and remain as sublicenses from the new owner of the NFT. Someone who wants to make a substantial investment in an NFT -- e.g., a filmmaker creating a movie based on an NFT-licensed work -- can record this license using an \eiplicense smart contract. This puts everyone in the world (including potential buyers of the NFT) on notice of their sublicense and that it will carry over. (This is similar to how recording systems for copyrights and real property work, and the \eiplicense interface has been designed to make this notice straightforward.) Sublicenses do not themselves need to be NFTs and typically will not be, although it is possible to tokenize one if desired.
-
-
-
-\section{Boilerplate}
-
-The \iccclicense includes a section advising courts on how to interpret it in the event of a dispute. Although the license itself does not always force the copyright license to keep in sync with ownership on the blockchain, it advises courts that maintaining the reliability of blockchain records is an important goal, encouraging them to pick interpretations that make the blockchain a useful and authoritative source for understanding the status of a copyright license. In addition, the interpretation clause encourages courts to promote other common legal policies, such as fairness, uniformity, and predictability.
-
-The severability clause and the disclaimer of warranties and limitation of liability are based on the text of the Creative Commons license suite. These licenses are also intended to create licenses in members of the public (including people who may be unknown to the licensor), so their use cases are broadly similar. Several other clauses and definitions, including the disclaimer at the start of the license text, are also adapted from language used in the Creative Commons licenses.
-
-\appendix
-
-\section{Human-Readable Summary}
-\label{sec:human}
-
-This is a human-readable summary of the Token-Bound NFT [\commercial{} | \noncommercial{}] [\derivative{} | \derivativetracking{} | \sharealike{} | \noderivative{}] [\publiclicense{} | \nopubliclicense{}] [\ledger{} | \legal{}] License. It is not a substitute for the license, and you should carefully review the license to understand its terms and how they may apply to you.
-
-This license gives you the following rights to use a creative work associated with an NFT on a ledger (such as a blockchain):
-
-\begin{itemize}
-\item \textbf{Use and Share}: You can make copies of the work, use them personally, and share them with others \iflicenseoption{\noncommercial}{, but not for commercial purposes}.
-\item \ifnotlicenseoption{\noderivative}{\textbf{Derivatives}: you can make new works that include and build on the work, use them, and share them with others \iflicenseoption{\noncommercial}{, but not for commercial purposes} \iflicenseoption{\derivativetracking}{, provided that you also release them as NFTs using the same technical standard and on the same ledger as the original NFT \iflicenseoption{\sharealike}{under the same license}}.}
-\item \textbf{Ownership}: You can use the work to show that you own the NFT.
-\item \textbf{Sale}: If you sell the NFT, you can use the work to show people what the NFT is.
-\end{itemize}
-
-You have these rights as long as you own the NFT, but when you sell or transfer the NFT, your rights will end and the new owner will have these rights instead. \iflicenseoption{\ledger}{For purposes of this license, the owner of the NFT is whoever the ledger says owns it. This means that if the NFT is stolen, your rights under this license will pass to the new owner.} \iflicenseoption{\legal}{For purposes of this license, the owner of the NFT is whoever the legal system says owns it. This means that if the NFT is stolen, you will retain your rights under this license.}
-
-Your rights to the work are not guaranteed to be exclusive. The copyright owner who made an NFT of the work may have the right to allow others to use the work, as well.
-
-\iflicenseoption{\publiclicense}{In addition, the copyright owner has given everyone the right to use and share the work, regardless of whether they own the NFT.}
-
-This license terminates if the technical process that created it says that it has been terminated. You should check that process to see whether the license is still in effect and how it can be terminated. If this license does terminate, your rights under it will end, and you must stop using the work.
-
-
-\section{License Text}
-\label{sec:text}
-
-\begin{sffamily}
-
-\emph{The Initiative for Cryptocurrencies and Contracts (IC3) and Coalition of Automated Legal Applications (COALA) are not law firms and do not provide legal services or legal advice. Publication of the text of the \iccclicense does not create a lawyer-client or other relationship. IC3 and COALA make this text and related information available on an ``as-is'' basis. IC3 and COALA give no warranties regarding this license, any material licensed under its terms and conditions, or any related information. IC3 and COALA disclaim all liability for damages resulting from their use to the fullest extent possible.}\\\\
-The \iccclicense (the ``License'') grants you certain intellectual property rights with respect to Licensed Material associated with an NFT. When you acquire the NFT, you own the personal property rights to the token underlying the NFT (e.g., the right to freely sell, transfer, or otherwise dispose of that NFT), but you do not own the associated Licensed Material. Instead, the Licensor grants you a specified limited license to use the Licensed Material, as set forth below:
-
-\sect{Definitions}
-
-\subsect{Ledgers and NFTs}
-
-
- \begin{itemize}
- \item A ``Unique Identifier'' is information that is sufficient to distinguish one digital record from other digital records.
-
- \item A ``Ledger'' is a blockchain, database, or other digital system that records information about Unique Identifiers.
-
- \item An ``NFT'' is a Unique Identifier recorded in a Ledger.
-
- \item A ``Private Key'' is a cryptographic key, the use of which is necessary to modify the information about a Unique Identifier recorded in a Ledger.
-
- \item An NFT is ``Associated'' with a person or entity when that person or entity has substantially exclusive control over the Private Key necessary to modify the information about that Unique Identifier in that Ledger.
-
- \item The ``Controller'' of an NFT is the person or entity with whom the NFT is Associated.
-
- \end{itemize}
-
- \subsect{Licensing}
-
- \begin{itemize}
- \item ``Copyright and Similar Rights'' means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and sui generis database rights, without regard to how the rights are labeled or categorized.
-
- \item ``License'' means the intellectual property license granted under the terms of this document.
-
- \item ``Licensed Rights'' means the rights granted to You subject to the terms and conditions of this License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
-
- \item A ``Licensing Process'' is a technical process (including a smart contract that implements \eiplicense or any update, revision, new version, or successor thereof) designed to allow authorized parties to specify the current status of intellectual property license terms associated with an NFT and any related material, including the text of a license. A Licensing Process can (but need not) specify whether the license has been sublicensed, transferred, and/or revoked.
-
- \item An NFT ``Invokes'' this License when the NFT refers to the verbatim text of this License by means of a Licensing Process.
-
- \item The ``Licensor'' means the individual or entity that causes an NFT to Invoke this License.
-
- \item The ``License NFT'' is the NFT that Invokes this License. If more than one NFT Invokes this License, each such NFT is a separate License NFT resulting in a separate and distinct license grant with respect to the Licensed Material respectively associated with each such NFT.
-
- \end{itemize}
-
- \subsect{Licensed and Adapted Material}
-
- \begin{itemize}
-
- \item An NFT is ``Linked'' to material when the NFT contains a description of or hyperlink to that material, and that description or hyperlink is substantially immutable in the ordinary course of operation of the Ledger,
-
- \item ``Licensed Material'' means the creative work or other material to which the License NFT is Linked.
-
- \item ``Adapted Material'' means material subject to copyright and similar rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the copyright and similar rights held by the Licensor. For purposes of this License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. For purposes of this License, the exact reproduction of the Licensed Material in a different medium in a manner not requiring original creative effort (such as printing a photographic or pictorial work on paper) does not produce Adapted Material.
-
- \item ``Commercial'' means primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this License, activity is Commercial if direct or indirect payment is required as a condition of access to the Licensed Material or Adapted Material. For purposes of this License, the sale and advertising for sale of the License NFT (including the accompanying rights granted under this License) is not Commercial.
-
- \item ``Non-Commercial'' means not Commercial.
-
- \item To ``Use'' material is to copy, display, distribute, make available to the public, or perform it.
-
- \end{itemize}
-
- \subsect{Ownership and Transfers}
-
- \begin{itemize}
-
- \item The ``Owner'' of an NFT is \iflicenseoption{\legal}{the person or entity who is legally entitled to be its Controller} \iflicenseoption{\ledger}{its Controller}.
-
- \item ``You'' and ``Your'' refer to the person receiving rights under this License as the Owner of the License NFT.
-
- \item An NFT ``Revokes'' this License when the NFT indicates that it has been revoked by means of a Licensing Process.
-
- \item An NFT is ``Sublicensed'' when the NFT indicates that it has been sublicensed by means of a Licensing Process.
-
- \item \iflicenseoption{\derivativetracking}{Adapted Material is ``Derivative Tracked'' from an NFT (the ``Parent NFT'') when the Parent NFT is Sublicensed by means of a Licensing Process that (1) creates another NFT (the ``Child NFT'') on the same Ledger as the Parent NFT, (2) causes the Child NFT to be Linked to Adapted Material, and (3) causes the Child NFT and Parent NFT to have materially the same properties and functionality, except for the identity of the parties they are Associated with and the identity of the material they are Linked to.}
-
- \item \iflicenseoption{\sharealike}{Adapted Material is ``Share-Alike Sublicensed'' from an NFT (the ``Parent NFT'') when the Parent NFT is Sublicensed by means of a Licensing Process that (1) creates another NFT (the ``Child NFT'') on the same Ledger as the Parent NFT, (2) causes the Child NFT to be Linked to Adapted Material, (3) causes the Child NFT and Parent NFT to have materially the same properties and functionality, except for the identity of the parties they are Associated with and the identity of the material they are Linked to, and (4) causes the Child NFT to Invoke this license.}
-
- \item To ``Transfer'' an NFT is to change, modify, or update the Ledger such that the identity of the Owner of that NFT changes, by any legally sufficient means, including sale, barter, gift, bequest, or operation of law.
-
- \item ``Grace Period Process'' means an interface, function, method, or similar technical process that is part of a Licensing Process and which, when invoked, indicates whether a specified limited duration following the Transfer of an NFT has elapsed.
-
- \item ``Grace Period'' means the time following the Transfer of an NFT during which the Grace Period Process indicates that the specified limited duration has not yet elapsed.
-
- \end{itemize}
-
-
-\sect{Public License Grant}
-
-\iflicenseoption{\publiclicense}{The Licensed Material is made available to the public under the terms of the Creative Commons Attribution-NoDerivatives 4.0 International Public License at \href{https://creativecommons.org/licenses/by-nd/4.0/legalcode}{https://creativecommons.org/licenses/by-nd/4.0/legalcode}.}
-
-\sect{NFT License Grant}
-
-Subject to the terms and conditions of this License, and on the condition that You are the Owner of the License NFT, the Licensor hereby grants to You a worldwide, royalty-free, sublicensable, non-exclusive, license to exercise the Licensed Rights to:
-\begin{itemize}
-\item Use the Licensed Material \iflicenseoption{\noncommercial}{for Non-Commercial purposes only},
-\item \ifnotlicenseoption{\noderivative}{Create and Use Adapted Material \iflicenseoption{\noncommercial}{for Non-Commercial purposes only} \iflicenseoption{\derivativetracking}{provided that the Adapted Material is Derivative Tracked from the License NFT} \iflicenseoption{\sharealike}{provided that the Adapted Material is Share-Alike Sublicensed from the License NFT}},
-\item Identify You as the Owner of the License NFT,
-\item Use the Licensed Material in connection with the sale and advertising for sale of the License NFT,
-\end{itemize}
-This License becomes effective when the Licensor causes the License NFT to Invoke it. Because this is a unilateral license grant and not a contract, Your assent is not required for it to become effective. \iflicenseoption{\publiclicense}{This license grant is in addition to any rights granted to You as a member of the public under the terms of the Public License Grant above.}
-
-All rights granted under this License last for the full duration of the Licensor's Licensed Rights, except that if the License NFT Revokes this License, Your rights under this license grant will terminate, as will all sublicenses granted hereunder.
-
-This license grant is non-transferable. If the License NFT is Transferred such that You are no longer the Owner, Your rights under this license grant will terminate. Notwithstanding the previous sentence, if the Licensing Process contains a Grace Period Process, You may continue to Use the Licensed Material and any already-existing Adapted Material under the terms of the license grant above during the Grace Period, but You may not Create or Use new Adapted Material, grant new sublicenses, or Use the Licensed Material to identify yourself as the owner of the License NFT.
-
-If the License NFT is Transferred, any sublicenses granted hereunder that are Sublicensed will continue in force as sublicenses from the new Owner. If You have become the Owner of the License NFT as a result of a Transfer, you automatically grant any such sublicenses that are Sublicensed. This License does not by itself require you to continue or grant any sublicenses given by a previous Owner that were not Sublicensed, but it does not prevent other law from doing so.
-
-
-\sect{Interpretation}
-
-By adopting this License, the Licensor intends to enhance the clarity and predictability of intellectual-property licensing via digital transactions. In cases of doubt or ambiguity, the terms of this license should be interpreted and applied to promote the goals of (1) making the information in the Digital System accurately reflect the licensing relationships it describes, and vice versa, (2) providing clear, simple, and unambiguous mechanisms for parties to express their licensing intentions, (3) protecting parties from duress, fraud, forgery, and mistake, and (4) achieving uniformity and consistency in the application of this License to different transactions, at different times, and in different jurisdictions.
-
-To the extent possible, if any provision of this License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this License without affecting the enforceability of the remaining terms.
-
-\sect{Disclaimer of Warranties and Limitation of Liability}
-
-Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.
-
-To the extent possible, unless otherwise separately undertaken by the Licensor, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.
-
-The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
-
-\end{sffamily}
-
-\end{document}
diff --git a/assets/eip-5218/license-tree.png b/assets/eip-5218/license-tree.png
deleted file mode 100644
index 088cae0..0000000
Binary files a/assets/eip-5218/license-tree.png and /dev/null differ
diff --git a/assets/eip-5219/IDecentralizedApp.sol b/assets/eip-5219/IDecentralizedApp.sol
deleted file mode 100644
index c25dbae..0000000
--- a/assets/eip-5219/IDecentralizedApp.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-struct KeyValue {
- string key;
- string value;
-}
-
-interface IDecentralizedApp {
- /// @notice Send an HTTP GET-like request to this contract
- /// @param resource The resource to request (e.g. "/asdf/1234" turns in to `["asdf", "1234"]`)
- /// @param params The query parameters. (e.g. "?asdf=1234&foo=bar" turns in to `[{ key: "asdf", value: "1234" }, { key: "foo", value: "bar" }]`)
- /// @return statusCode The HTTP status code (e.g. 200)
- /// @return body The body of the response
- /// @return headers A list of header names (e.g. [{ key: "Content-Type", value: "application/json" }])
- function request(string[] memory resource, KeyValue[] memory params) external view returns (uint8 statusCode, string memory body, KeyValue[] headers);
-}
diff --git a/assets/eip-5247/ProposalRegistry.sol b/assets/eip-5247/ProposalRegistry.sol
deleted file mode 100644
index 76f56f2..0000000
--- a/assets/eip-5247/ProposalRegistry.sol
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: MIT
-// A fully runnalbe version can be found in https://github.com/ercref/ercref-contracts/tree/869843f23dc4da793f0d9d018ed92e3950da8f75
-pragma solidity ^0.8.17;
-
-import "./IERC5247.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-
-struct Proposal {
- address by;
- uint256 proposalId;
- address[] targets;
- uint256[] values;
- uint256[] gasLimits;
- bytes[] calldatas;
-}
-
-contract ProposalRegistry is IERC5247 {
- using Address for address;
- mapping(uint256 => Proposal) public proposals;
- uint256 private proposalCount;
- function createProposal(
- uint256 proposalId,
- address[] calldata targets,
- uint256[] calldata values,
- uint256[] calldata gasLimits,
- bytes[] calldata calldatas,
- bytes calldata extraParams
- ) external returns (uint256 registeredProposalId) {
- require(targets.length == values.length, "GeneralForwarder: targets and values length mismatch");
- require(targets.length == gasLimits.length, "GeneralForwarder: targets and gasLimits length mismatch");
- require(targets.length == calldatas.length, "GeneralForwarder: targets and calldatas length mismatch");
- registeredProposalId = proposalCount;
- proposalCount++;
-
- proposals[registeredProposalId] = Proposal({
- by: msg.sender,
- proposalId: proposalId,
- targets: targets,
- values: values,
- calldatas: calldatas,
- gasLimits: gasLimits
- });
- emit ProposalCreated(msg.sender, proposalId, targets, values, gasLimits, calldatas, extraParams);
- return registeredProposalId;
- }
- function executeProposal(uint256 proposalId, bytes calldata extraParams) external {
- Proposal storage proposal = proposals[proposalId];
- address[] memory targets = proposal.targets;
- string memory errorMessage = "Governor: call reverted without message";
- for (uint256 i = 0; i < targets.length; ++i) {
- (bool success, bytes memory returndata) = proposal.targets[i].call{value: proposal.values[i]}(proposal.calldatas[i]);
- Address.verifyCallResult(success, returndata, errorMessage);
- }
- emit ProposalExecuted(msg.sender, proposalId, extraParams);
- }
-
- function getProposal(uint256 proposalId) external view returns (Proposal memory) {
- return proposals[proposalId];
- }
-
- function getProposalCount() external view returns (uint256) {
- return proposalCount;
- }
-
-}
diff --git a/assets/eip-5247/testProposalRegistry.ts b/assets/eip-5247/testProposalRegistry.ts
deleted file mode 100644
index 947c40b..0000000
--- a/assets/eip-5247/testProposalRegistry.ts
+++ /dev/null
@@ -1,162 +0,0 @@
-// A fully runnalbe version can be found in https://github.com/ercref/ercref-contracts/tree/869843f23dc4da793f0d9d018ed92e3950da8f75
-import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { hexlify } from "ethers/lib/utils";
-import { ethers } from "hardhat";
-
-describe("ProposalRegistry", function () {
- async function deployFixture() {
- // Contracts are deployed using the first signer/account by default
- const [owner, otherAccount] = await ethers.getSigners();
-
- const ProposalRegistry = await ethers.getContractFactory("ProposalRegistry");
- const contract = await ProposalRegistry.deploy();
-
- const ERC721ForTesting = await ethers.getContractFactory("ERC721ForTesting");
- const erc721 = await ERC721ForTesting.deploy();
-
- const SimpleForwarder = await ethers.getContractFactory("SimpleForwarder");
- const forwarder = await SimpleForwarder.deploy();
- return { contract, erc721, forwarder, owner, otherAccount };
- }
-
- describe("Deployment", function () {
- it("Should work for a simple case", async function () {
- const { contract, erc721, owner } = await loadFixture(deployFixture);
- const callData1 = erc721.interface.encodeFunctionData("mint", [owner.address, 1]);
- const callData2 = erc721.interface.encodeFunctionData("mint", [owner.address, 2]);
- await contract.connect(owner)
- .createProposal(
- 0,
- [erc721.address, erc721.address],
- [0,0],
- [0,0],
- [callData1, callData2],
- []);
- expect(await erc721.balanceOf(owner.address)).to.equal(0);
- await contract.connect(owner).executeProposal(0, []);
- expect(await erc721.balanceOf(owner.address)).to.equal(2);
- });
- const Ns = [0, 50, 100, 150, 200];
- for (let n of Ns) {
-
- it(`Should work for a proposal case of ${n}`, async function () {
- const { contract, erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = n;
- const calldatas = [];
- for (let i = 0 ; i < numOfMint; i++) {
- const callData = erc721.interface.encodeFunctionData("mint", [owner.address, i]);
- calldatas.push(callData);
- }
- let txCreate = await contract.connect(owner)
- .createProposal(
- 0,
- Array(numOfMint).fill(erc721.address),
- Array(numOfMint).fill(0),
- Array(numOfMint).fill(0),
- calldatas,
- []);
- let txCreateWaited = await txCreate.wait();
- console.log(`Creation TX gas`, txCreateWaited.cumulativeGasUsed.toString());
- console.log(`Gas per mint`, parseInt(txCreateWaited.cumulativeGasUsed.toString()) / numOfMint);
- expect(await erc721.balanceOf(owner.address)).to.equal(0);
- let txExecute = await contract.connect(owner).executeProposal(0, []);
- let txExecuteWaited = await txExecute.wait();
- console.log(`Execution TX gas`, txExecuteWaited.cumulativeGasUsed.toString());
- console.log(`Gas per mint`, parseInt(txExecuteWaited.cumulativeGasUsed.toString()) / numOfMint);
- expect(await erc721.balanceOf(owner.address)).to.equal(numOfMint);
- });
- }
- });
- describe("Benchmark", function () {
- it(`Should work for a forwarding case`, async function () {
- const { forwarder, erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = 200;
- const calldatas = [];
- for (let i = 0 ; i < numOfMint; i++) {
- const callData = erc721.interface.encodeFunctionData("mint", [owner.address, i]);
- calldatas.push(callData);
- }
- expect(await erc721.balanceOf(owner.address)).to.equal(0);
- let txForward = await forwarder.connect(owner)
- .forward(
- Array(numOfMint).fill(erc721.address),
- Array(numOfMint).fill(0),
- Array(numOfMint).fill(0),
- calldatas);
- let txForwardWaited = await txForward.wait();
-
- console.log(`txForwardWaited TX gas`, txForwardWaited.cumulativeGasUsed.toString());
-
- console.log(`Gas per mint`, parseInt(txForwardWaited.cumulativeGasUsed.toString()) / numOfMint);
- expect(await erc721.balanceOf(owner.address)).to.equal(numOfMint);
-
- });
-
-
- it(`Should work for erc721 batchMint with same addresses`, async function () {
- const { erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = 200;
- const tokenIds = [];
- const addresses = [];
-
- for (let i = 0 ; i < numOfMint; i++) {
- addresses.push(owner.address);// addresses.push(hexlify(ethers.utils.randomBytes(20)));
- tokenIds.push(i);
- }
- const tx = await erc721.connect(owner).batchMint(addresses, tokenIds);
- const txWaited = await tx.wait();
- console.log(`batchMint TX gas`, txWaited.cumulativeGasUsed.toString());
- console.log(`At ${numOfMint} Gas per mint`, parseInt(txWaited.cumulativeGasUsed.toString()) / numOfMint);
- })
-
- it(`Should work for erc721 batchMint with different addresses`, async function () {
- const { erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = 200;
- const tokenIds = [];
- const addresses = [];
-
- for (let i = 0 ; i < numOfMint; i++) {
- addresses.push(hexlify(ethers.utils.randomBytes(20)));
- tokenIds.push(i);
- }
- const tx = await erc721.connect(owner).batchMint(addresses, tokenIds);
- const txWaited = await tx.wait();
- console.log(`batchMint TX gas`, txWaited.cumulativeGasUsed.toString());
- console.log(`At ${numOfMint} Gas per mint`, parseInt(txWaited.cumulativeGasUsed.toString()) / numOfMint);
- });
-
-
- it(`Should work for erc721 batchSafeMint with same addresses`, async function () {
- const { erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = 400;
- const tokenIds = [];
- const addresses = [];
-
- for (let i = 0 ; i < numOfMint; i++) {
- addresses.push(owner.address);// addresses.push(hexlify(ethers.utils.randomBytes(20)));
- tokenIds.push(i);
- }
- const tx = await erc721.connect(owner).batchSafeMint(addresses, tokenIds);
- const txWaited = await tx.wait();
- console.log(`batchSafeMint TX gas`, txWaited.cumulativeGasUsed.toString());
- console.log(`At ${numOfMint} Gas per mint`, parseInt(txWaited.cumulativeGasUsed.toString()) / numOfMint);
- });
-
- it(`Should work for erc721 batchSafeMint with different addresses`, async function () {
- const { erc721, owner } = await loadFixture(deployFixture);
- const numOfMint = 400;
- const tokenIds = [];
- const addresses = [];
-
- for (let i = 0 ; i < numOfMint; i++) {
- addresses.push(hexlify(ethers.utils.randomBytes(20)));
- tokenIds.push(i);
- }
- const tx = await erc721.connect(owner).batchSafeMint(addresses, tokenIds);
- const txWaited = await tx.wait();
- console.log(`batchSafeMint TX gas`, txWaited.cumulativeGasUsed.toString());
- console.log(`At ${numOfMint} the Gas per mint`, parseInt(txWaited.cumulativeGasUsed.toString()) / numOfMint);
- });
- });
-});
diff --git a/assets/eip-5252/.gitignore b/assets/eip-5252/.gitignore
deleted file mode 100644
index b41feef..0000000
--- a/assets/eip-5252/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-node_modules
-.env
-coverage
-coverage.json
-typechain
-typechain-types
-yarn.lock
-package-lock.json
-yarn-error.log
-.DS_Store
-
-#Hardhat files
-cache
-artifacts
diff --git a/assets/eip-5252/README.md b/assets/eip-5252/README.md
deleted file mode 100644
index 5136b9b..0000000
--- a/assets/eip-5252/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# EIP 5252 implementation
-
-This project is a reference implementation of EIP-5252.
-
-Try running some of the following tasks:
-
-```shell
-npx hardhat help
-npx hardhat test
-GAS_REPORT=true npx hardhat test
-npx hardhat node
-npx hardhat run scripts/deploy.ts
-```
diff --git a/assets/eip-5252/contracts/ABT.sol b/assets/eip-5252/contracts/ABT.sol
deleted file mode 100644
index a9896e0..0000000
--- a/assets/eip-5252/contracts/ABT.sol
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC721A.sol";
-import "@openzeppelin/contracts/access/AccessControl.sol";
-import "./interfaces/IFactory.sol";
-import "./interfaces/IFinance.sol";
-import "./interfaces/IDescriptor.sol";
-
-contract ABT is ERC721A, AccessControl {
- // Create a new role identifier for the minter role
- bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
- bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
- // factory address
- address public factory;
- // SVG for ABT
- address public descriptor;
-
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721A, AccessControl) returns (bool) {
- return super.supportsInterface(interfaceId);
- }
-
- function setDescriptor(address descriptor_) public {
- require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "ABT: Caller is not a default admin");
- descriptor = descriptor_;
- }
-
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory tokenURI) {
- require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
- tokenURI = IDescriptor(descriptor).tokenURI(tokenId);
- }
-
- constructor(address factory_)
- ERC721A("Account-Bound Token", "ABT") {
- _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
-
- _setupRole(MINTER_ROLE, _msgSender());
- _setupRole(BURNER_ROLE, _msgSender());
- factory = factory_;
- }
-
- function setFactory(address factory_) public {
- require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "ABT: Caller is not a default admin");
- factory = factory_;
- }
-
- function mint(address to) external {
- // Check that the calling account has the minter role
- require(_msgSender() == factory, "ABT: Caller is not factory");
- _safeMint(to, 1);
- }
-
- function burn(uint256 tokenId_) external {
- require(hasRole(BURNER_ROLE, _msgSender()), "ABT: must have burner role to burn");
- _burn(tokenId_);
- }
-
- function exists(uint256 tokenId_) external view returns (bool) {
- return _exists(tokenId_);
- }
-
- function transfer(
- address to,
- uint256 tokenId
- ) public virtual {
- transferFrom(msg.sender, to, tokenId);
- }
-}
diff --git a/assets/eip-5252/contracts/ERC721A.sol b/assets/eip-5252/contracts/ERC721A.sol
deleted file mode 100644
index 92ebd12..0000000
--- a/assets/eip-5252/contracts/ERC721A.sol
+++ /dev/null
@@ -1,616 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-// Creator: Chiru Labs
-
-pragma solidity ^0.8.4;
-
-import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
-import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
-import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol';
-import '@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol';
-import '@openzeppelin/contracts/utils/Address.sol';
-import '@openzeppelin/contracts/utils/Context.sol';
-import '@openzeppelin/contracts/utils/Strings.sol';
-import '@openzeppelin/contracts/utils/introspection/ERC165.sol';
-
-error ApprovalCallerNotOwnerNorApproved();
-error ApprovalQueryForNonexistentToken();
-error ApproveToCaller();
-error ApprovalToCurrentOwner();
-error BalanceQueryForZeroAddress();
-error MintedQueryForZeroAddress();
-error BurnedQueryForZeroAddress();
-error AuxQueryForZeroAddress();
-error MintToZeroAddress();
-error MintZeroQuantity();
-error OwnerIndexOutOfBounds();
-error OwnerQueryForNonexistentToken();
-error TokenIndexOutOfBounds();
-error TransferCallerNotOwnerNorApproved();
-error TransferFromIncorrectOwner();
-error TransferToNonERC721ReceiverImplementer();
-error TransferToZeroAddress();
-error URIQueryForNonexistentToken();
-
-/**
- * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
- * the Metadata extension. Built to optimize for lower gas during batch mints.
- *
- * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
- *
- * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
- *
- * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
- */
-contract ERC721A is Context, ERC165, IERC721, IERC721Metadata {
- using Address for address;
- using Strings for uint256;
-
- // Compiler will pack this into a single 256bit word.
- struct TokenOwnership {
- // The address of the owner.
- address addr;
- // Keeps track of the start time of ownership with minimal overhead for tokenomics.
- uint64 startTimestamp;
- // Whether the token has been burned.
- bool burned;
- }
-
- // Compiler will pack this into a single 256bit word.
- struct AddressData {
- // Realistically, 2**64-1 is more than enough.
- uint64 balance;
- // Keeps track of mint count with minimal overhead for tokenomics.
- uint64 numberMinted;
- // Keeps track of burn count with minimal overhead for tokenomics.
- uint64 numberBurned;
- // For miscellaneous variable(s) pertaining to the address
- // (e.g. number of whitelist mint slots used).
- // If there are multiple variables, please pack them into a uint64.
- uint64 aux;
- }
-
- // The tokenId of the next token to be minted.
- uint256 internal _currentIndex;
-
- // The number of tokens burned.
- uint256 internal _burnCounter;
-
- // Token name
- string private _name;
-
- // Token symbol
- string private _symbol;
-
- // Mapping from token ID to ownership details
- // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
- mapping(uint256 => TokenOwnership) internal _ownerships;
-
- // Mapping owner address to address data
- mapping(address => AddressData) private _addressData;
-
- // Mapping from token ID to approved address
- mapping(uint256 => address) private _tokenApprovals;
-
- // Mapping from owner to operator approvals
- mapping(address => mapping(address => bool)) private _operatorApprovals;
-
- constructor(string memory name_, string memory symbol_) {
- _name = name_;
- _symbol = symbol_;
- _currentIndex = _startTokenId();
- }
-
- /**
- * To change the starting tokenId, please override this function.
- */
- function _startTokenId() internal view virtual returns (uint256) {
- return 0;
- }
-
- /**
- * @dev See {IERC721Enumerable-totalSupply}.
- * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
- */
- function totalSupply() public view returns (uint256) {
- // Counter underflow is impossible as _burnCounter cannot be incremented
- // more than _currentIndex - _startTokenId() times
- unchecked {
- return _currentIndex - _burnCounter - _startTokenId();
- }
- }
-
- /**
- * Returns the total amount of tokens minted in the contract.
- */
- function _totalMinted() internal view returns (uint256) {
- // Counter underflow is impossible as _currentIndex does not decrement,
- // and it is initialized to _startTokenId()
- unchecked {
- return _currentIndex - _startTokenId();
- }
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
- return
- interfaceId == type(IERC721).interfaceId ||
- interfaceId == type(IERC721Metadata).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev See {IERC721-balanceOf}.
- */
- function balanceOf(address owner) public view override returns (uint256) {
- if (owner == address(0)) revert BalanceQueryForZeroAddress();
- return uint256(_addressData[owner].balance);
- }
-
- /**
- * Returns the number of tokens minted by `owner`.
- */
- function _numberMinted(address owner) internal view returns (uint256) {
- if (owner == address(0)) revert MintedQueryForZeroAddress();
- return uint256(_addressData[owner].numberMinted);
- }
-
- /**
- * Returns the number of tokens burned by or on behalf of `owner`.
- */
- function _numberBurned(address owner) internal view returns (uint256) {
- if (owner == address(0)) revert BurnedQueryForZeroAddress();
- return uint256(_addressData[owner].numberBurned);
- }
-
- /**
- * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
- */
- function _getAux(address owner) internal view returns (uint64) {
- if (owner == address(0)) revert AuxQueryForZeroAddress();
- return _addressData[owner].aux;
- }
-
- /**
- * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
- * If there are multiple variables, please pack them into a uint64.
- */
- function _setAux(address owner, uint64 aux) internal {
- if (owner == address(0)) revert AuxQueryForZeroAddress();
- _addressData[owner].aux = aux;
- }
-
- /**
- * Gas spent here starts off proportional to the maximum mint batch size.
- * It gradually moves to O(1) as tokens get transferred around in the collection over time.
- */
- function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
- uint256 curr = tokenId;
-
- unchecked {
- if (_startTokenId() <= curr && curr < _currentIndex) {
- TokenOwnership memory ownership = _ownerships[curr];
- if (!ownership.burned) {
- if (ownership.addr != address(0)) {
- return ownership;
- }
- // Invariant:
- // There will always be an ownership that has an address and is not burned
- // before an ownership that does not have an address and is not burned.
- // Hence, curr will not underflow.
- while (true) {
- curr--;
- ownership = _ownerships[curr];
- if (ownership.addr != address(0)) {
- return ownership;
- }
- }
- }
- }
- }
- revert OwnerQueryForNonexistentToken();
- }
-
- /**
- * @dev See {IERC721-ownerOf}.
- */
- function ownerOf(uint256 tokenId) public view override returns (address) {
- return ownershipOf(tokenId).addr;
- }
-
- /**
- * @dev See {IERC721Metadata-name}.
- */
- function name() public view virtual override returns (string memory) {
- return _name;
- }
-
- /**
- * @dev See {IERC721Metadata-symbol}.
- */
- function symbol() public view virtual override returns (string memory) {
- return _symbol;
- }
-
- /**
- * @dev See {IERC721Metadata-tokenURI}.
- */
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
- if (!_exists(tokenId)) revert URIQueryForNonexistentToken();
-
- string memory baseURI = _baseURI();
- return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : '';
- }
-
- /**
- * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
- * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
- * by default, can be overridden in child contracts.
- */
- function _baseURI() internal view virtual returns (string memory) {
- return '';
- }
-
- /**
- * @dev See {IERC721-approve}.
- */
- function approve(address to, uint256 tokenId) public override {
- address owner = ERC721A.ownerOf(tokenId);
- if (to == owner) revert ApprovalToCurrentOwner();
-
- if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) {
- revert ApprovalCallerNotOwnerNorApproved();
- }
-
- _approve(to, tokenId, owner);
- }
-
- /**
- * @dev See {IERC721-getApproved}.
- */
- function getApproved(uint256 tokenId) public view override returns (address) {
- if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();
-
- return _tokenApprovals[tokenId];
- }
-
- /**
- * @dev See {IERC721-setApprovalForAll}.
- */
- function setApprovalForAll(address operator, bool approved) public override {
- if (operator == _msgSender()) revert ApproveToCaller();
-
- _operatorApprovals[_msgSender()][operator] = approved;
- emit ApprovalForAll(_msgSender(), operator, approved);
- }
-
- /**
- * @dev See {IERC721-isApprovedForAll}.
- */
- function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
- return _operatorApprovals[owner][operator];
- }
-
- /**
- * @dev See {IERC721-transferFrom}.
- */
- function transferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public virtual override {
- _transfer(from, to, tokenId);
- }
-
- /**
- * @dev See {IERC721-safeTransferFrom}.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public virtual override {
- safeTransferFrom(from, to, tokenId, '');
- }
-
- /**
- * @dev See {IERC721-safeTransferFrom}.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId,
- bytes memory _data
- ) public virtual override {
- _transfer(from, to, tokenId);
- if (to.isContract() && !_checkContractOnERC721Received(from, to, tokenId, _data)) {
- revert TransferToNonERC721ReceiverImplementer();
- }
- }
-
- /**
- * @dev Returns whether `tokenId` exists.
- *
- * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
- *
- * Tokens start existing when they are minted (`_mint`),
- */
- function _exists(uint256 tokenId) internal view returns (bool) {
- return _startTokenId() <= tokenId && tokenId < _currentIndex &&
- !_ownerships[tokenId].burned;
- }
-
- function _safeMint(address to, uint256 quantity) internal {
- _safeMint(to, quantity, '');
- }
-
- /**
- * @dev Safely mints `quantity` tokens and transfers them to `to`.
- *
- * Requirements:
- *
- * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
- * - `quantity` must be greater than 0.
- *
- * Emits a {Transfer} event.
- */
- function _safeMint(
- address to,
- uint256 quantity,
- bytes memory _data
- ) internal {
- _mint(to, quantity, _data, true);
- }
-
- /**
- * @dev Mints `quantity` tokens and transfers them to `to`.
- *
- * Requirements:
- *
- * - `to` cannot be the zero address.
- * - `quantity` must be greater than 0.
- *
- * Emits a {Transfer} event.
- */
- function _mint(
- address to,
- uint256 quantity,
- bytes memory _data,
- bool safe
- ) internal {
- uint256 startTokenId = _currentIndex;
- if (to == address(0)) revert MintToZeroAddress();
- if (quantity == 0) revert MintZeroQuantity();
-
- _beforeTokenTransfers(address(0), to, startTokenId, quantity);
-
- // Overflows are incredibly unrealistic.
- // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
- // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
- unchecked {
- _addressData[to].balance += uint64(quantity);
- _addressData[to].numberMinted += uint64(quantity);
-
- _ownerships[startTokenId].addr = to;
- _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);
-
- uint256 updatedIndex = startTokenId;
- uint256 end = updatedIndex + quantity;
-
- if (safe && to.isContract()) {
- do {
- emit Transfer(address(0), to, updatedIndex);
- if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
- revert TransferToNonERC721ReceiverImplementer();
- }
- } while (updatedIndex != end);
- // Reentrancy protection
- if (_currentIndex != startTokenId) revert();
- } else {
- do {
- emit Transfer(address(0), to, updatedIndex++);
- } while (updatedIndex != end);
- }
- _currentIndex = updatedIndex;
- }
- _afterTokenTransfers(address(0), to, startTokenId, quantity);
- }
-
- /**
- * @dev Transfers `tokenId` from `from` to `to`.
- *
- * Requirements:
- *
- * - `to` cannot be the zero address.
- * - `tokenId` token must be owned by `from`.
- *
- * Emits a {Transfer} event.
- */
- function _transfer(
- address from,
- address to,
- uint256 tokenId
- ) private {
- TokenOwnership memory prevOwnership = ownershipOf(tokenId);
-
- bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
- isApprovedForAll(prevOwnership.addr, _msgSender()) ||
- getApproved(tokenId) == _msgSender());
-
- if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
- if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();
- if (to == address(0)) revert TransferToZeroAddress();
-
- _beforeTokenTransfers(from, to, tokenId, 1);
-
- // Clear approvals from the previous owner
- _approve(address(0), tokenId, prevOwnership.addr);
-
- // Underflow of the sender's balance is impossible because we check for
- // ownership above and the recipient's balance can't realistically overflow.
- // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
- unchecked {
- _addressData[from].balance -= 1;
- _addressData[to].balance += 1;
-
- _ownerships[tokenId].addr = to;
- _ownerships[tokenId].startTimestamp = uint64(block.timestamp);
-
- // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
- // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
- uint256 nextTokenId = tokenId + 1;
- if (_ownerships[nextTokenId].addr == address(0)) {
- // This will suffice for checking _exists(nextTokenId),
- // as a burned slot cannot contain the zero address.
- if (nextTokenId < _currentIndex) {
- _ownerships[nextTokenId].addr = prevOwnership.addr;
- _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
- }
- }
- }
-
- emit Transfer(from, to, tokenId);
- _afterTokenTransfers(from, to, tokenId, 1);
- }
-
- /**
- * @dev Destroys `tokenId`.
- * The approval is cleared when the token is burned.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- *
- * Emits a {Transfer} event.
- */
- function _burn(uint256 tokenId) internal virtual {
- TokenOwnership memory prevOwnership = ownershipOf(tokenId);
-
- _beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);
-
- // Clear approvals from the previous owner
- _approve(address(0), tokenId, prevOwnership.addr);
-
- // Underflow of the sender's balance is impossible because we check for
- // ownership above and the recipient's balance can't realistically overflow.
- // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
- unchecked {
- _addressData[prevOwnership.addr].balance -= 1;
- _addressData[prevOwnership.addr].numberBurned += 1;
-
- // Keep track of who burned the token, and the timestamp of burning.
- _ownerships[tokenId].addr = prevOwnership.addr;
- _ownerships[tokenId].startTimestamp = uint64(block.timestamp);
- _ownerships[tokenId].burned = true;
-
- // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
- // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
- uint256 nextTokenId = tokenId + 1;
- if (_ownerships[nextTokenId].addr == address(0)) {
- // This will suffice for checking _exists(nextTokenId),
- // as a burned slot cannot contain the zero address.
- if (nextTokenId < _currentIndex) {
- _ownerships[nextTokenId].addr = prevOwnership.addr;
- _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp;
- }
- }
- }
-
- emit Transfer(prevOwnership.addr, address(0), tokenId);
- _afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1);
-
- // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
- unchecked {
- _burnCounter++;
- }
- }
-
- /**
- * @dev Approve `to` to operate on `tokenId`
- *
- * Emits a {Approval} event.
- */
- function _approve(
- address to,
- uint256 tokenId,
- address owner
- ) private {
- _tokenApprovals[tokenId] = to;
- emit Approval(owner, to, tokenId);
- }
-
- /**
- * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target contract.
- *
- * @param from address representing the previous owner of the given token ID
- * @param to target address that will receive the tokens
- * @param tokenId uint256 ID of the token to be transferred
- * @param _data bytes optional data to send along with the call
- * @return bool whether the call correctly returned the expected magic value
- */
- function _checkContractOnERC721Received(
- address from,
- address to,
- uint256 tokenId,
- bytes memory _data
- ) private returns (bool) {
- try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
- return retval == IERC721Receiver(to).onERC721Received.selector;
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert TransferToNonERC721ReceiverImplementer();
- } else {
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- }
-
- /**
- * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
- * And also called before burning one token.
- *
- * startTokenId - the first token id to be transferred
- * quantity - the amount to be transferred
- *
- * Calling conditions:
- *
- * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
- * transferred to `to`.
- * - When `from` is zero, `tokenId` will be minted for `to`.
- * - When `to` is zero, `tokenId` will be burned by `from`.
- * - `from` and `to` are never both zero.
- */
- function _beforeTokenTransfers(
- address from,
- address to,
- uint256 startTokenId,
- uint256 quantity
- ) internal virtual {}
-
- /**
- * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
- * minting.
- * And also called after one token has been burned.
- *
- * startTokenId - the first token id to be transferred
- * quantity - the amount to be transferred
- *
- * Calling conditions:
- *
- * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
- * transferred to `to`.
- * - When `from` is zero, `tokenId` has been minted for `to`.
- * - When `to` is zero, `tokenId` has been burned by `from`.
- * - `from` and `to` are never both zero.
- */
- function _afterTokenTransfers(
- address from,
- address to,
- uint256 startTokenId,
- uint256 quantity
- ) internal virtual {}
-}
\ No newline at end of file
diff --git a/assets/eip-5252/contracts/Factory.sol b/assets/eip-5252/contracts/Factory.sol
deleted file mode 100644
index 335e01a..0000000
--- a/assets/eip-5252/contracts/Factory.sol
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/access/AccessControl.sol";
-import "./Finance.sol";
-import "./libraries/CloneFactory.sol";
-import "./interfaces/IFactory.sol";
-
-contract Factory is AccessControl, IFactory {
- // Vaults
- address[] public allFinances;
- /// Address of cdp nft registry
- address public override abt;
- /// Address of Wrapped Ether
- address public override WETH;
- /// Address of manager
- address public override manager;
- /// version number of impl
- uint256 version;
- /// address of vault impl
- address public impl;
-
- constructor() {
- _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
- _createImpl();
- }
-
- /// Vault can issue stablecoin, it just manages the position
- function createFinance(
- address weth_,
- uint256 amount_,
- address recipient
- ) external override returns (address vault, uint256 id) {
- require(msg.sender == manager, "Factory: IA");
- uint256 gIndex = allFinancesLength();
- address proxy = CloneFactory._createClone(impl);
- IFinance(proxy).initialize(manager, gIndex, abt, amount_, weth_);
- allFinances.push(proxy);
- IABT(abt).mint(recipient);
- return (proxy, gIndex);
- }
-
- // Set immutable, consistent, one rule for vault implementation
- function _createImpl() internal {
- address addr;
- bytes memory bytecode = type(Finance).creationCode;
- bytes32 salt = keccak256(abi.encodePacked("finance", version));
- assembly {
- addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
- if iszero(extcodesize(addr)) {
- revert(0, 0)
- }
- }
- impl = addr;
- }
-
- function isClone(address vault) external view returns (bool cloned) {
- cloned = CloneFactory._isClone(impl, vault);
- }
-
- function initialize(
- address abt_,
- address weth_,
- address manager_,
- uint256 version_
- ) public {
- require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "IA"); // Invalid Access
- abt = abt_;
- WETH = weth_;
- manager = manager_;
- version = version_;
- }
-
- function getFinance(uint256 financeId_)
- external
- view
- override
- returns (address)
- {
- return allFinances[financeId_];
- }
-
- function financeCodeHash()
- external
- pure
- override
- returns (bytes32 vaultCode)
- {
- return keccak256(hex"3d602d80600a3d3981f3");
- }
-
- function allFinancesLength() public view returns (uint256) {
- return allFinances.length;
- }
-}
diff --git a/assets/eip-5252/contracts/Finance.sol b/assets/eip-5252/contracts/Finance.sol
deleted file mode 100644
index 69d4be5..0000000
--- a/assets/eip-5252/contracts/Finance.sol
+++ /dev/null
@@ -1,83 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./interfaces/IERC20Minimal.sol";
-import "./libraries/TransferHelper.sol";
-import "./interfaces/IFinance.sol";
-import "./interfaces/IABT.sol";
-import "./interfaces/IWETH.sol";
-import "./libraries/Initializable.sol";
-import "./interfaces/IManager.sol";
-import "./interfaces/IInfluencer.sol";
-
-contract Finance is IFinance, Initializable {
- /// Address of a manager
- address public override manager;
- /// Address of a factory
- address public override factory;
- /// Address of a factory
- address public override influencer;
- /// Address of account bound token
- address public override abt;
- /// Finance global identifier
- uint256 public override financeId;
- /// Address of wrapped eth
- address public override WETH;
- /// Finance Creation Date
- uint256 public override createdAt;
- /// Finance Last Updated Date
- uint256 public override lastUpdated;
- /// deposited amount to the account
- uint256 public override deposit;
-
- modifier onlyFinanceOwner() {
- require(
- IABT(abt).ownerOf(financeId) == msg.sender,
- "Finance: Finance is not owned by you"
- );
- _;
- }
-
- // called once by the factory at time of deployment
- function initialize(
- address manager_,
- uint256 financeId_,
- address abt_,
- uint256 amount_,
- address weth_
- ) external override initializer {
- financeId = financeId_;
- abt = abt_;
- WETH = weth_;
- manager = manager_;
- factory = msg.sender;
- deposit = amount_;
- lastUpdated = block.timestamp;
- createdAt = block.timestamp;
- influencer = IManager(manager_).influencer();
- }
-
- function depositNative() external payable onlyFinanceOwner {
- // wrap deposit
- deposit += msg.value;
- IInfluencer(influencer).deposit(msg.value);
- IWETH(WETH).deposit{value: msg.value}();
- emit DepositFundNative(financeId, msg.value);
- }
-
- /// Withdraw collateral as native currency
- function withdrawNative(uint256 amount_) external virtual onlyFinanceOwner {
- deposit -= amount_;
- IInfluencer(influencer).withdraw(amount_);
- // unwrap collateral
- IWETH(WETH).withdraw(amount_);
- // send withdrawn native currency
- TransferHelper.safeTransferETH(msg.sender, address(this).balance);
- emit WithdrawFundNative(financeId, amount_);
- }
-
- receive() external payable {
- assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
- }
-}
diff --git a/assets/eip-5252/contracts/Manager.sol b/assets/eip-5252/contracts/Manager.sol
deleted file mode 100644
index 3b1142c..0000000
--- a/assets/eip-5252/contracts/Manager.sol
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/access/AccessControl.sol";
-import "./interfaces/IWETH.sol";
-import "./interfaces/IManager.sol";
-import "./interfaces/IFactory.sol";
-import "./interfaces/IERC20Minimal.sol";
-
-contract Manager is AccessControl, IManager {
-
- // Configs
- /// key: Collateral address, value: Liquidation Fee Ratio (LFR) in percent(%) with 5 decimal precision(100.00000%)
- mapping (address => uint) internal ExampleConfig;
-
- address public override factory;
-
- constructor() {
- _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
- }
-
- function initializeConfig(address something, uint example) public {
- require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "IA"); // Invalid Access
- ExampleConfig[something] = example;
- emit ConfigInitialized(something, example);
- }
-
- function initialize(address stablecoin_, address factory_, address liquidator_) public {
- require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "IA"); // Invalid Access
- factory = factory_;
- }
-
- function createFinanceNative(uint amount_) payable public returns(bool success) {
- address WETH = IFactory(factory).WETH();
- // check validity
-
- // create vault
- (address vlt, uint256 id) = IFactory(factory).createFinance(WETH, amount_, _msgSender());
- require(vlt != address(0), "VAULTMANAGER: FE"); // Factory error
- // wrap native currency
- IWETH(WETH).deposit{value: address(this).balance}();
- uint256 weth = IERC20Minimal(WETH).balanceOf(address(this));
- // then transfer collateral native currency to the finance contract, manage collateral from there.
- require(IWETH(WETH).transfer(vlt, weth));
- emit FinanceCreated(id, WETH, msg.sender, vlt, msg.value);
- return true;
- }
-
-
- function getExampleConfig(address something) external view override returns (uint) {
- return ExampleConfig[something];
- }
-}
-
diff --git a/assets/eip-5252/contracts/governance/Governor.sol b/assets/eip-5252/contracts/governance/Governor.sol
deleted file mode 100644
index 5d06e65..0000000
--- a/assets/eip-5252/contracts/governance/Governor.sol
+++ /dev/null
@@ -1,109 +0,0 @@
-pragma solidity ^0.8.4;
-
-import "@openzeppelin/contracts/governance/Governor.sol";
-import "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol";
-import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";
-import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
-import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
-import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
-import "../interfaces/IInfluencer.sol";
-import "@openzeppelin/contracts/governance/utils/IVotes.sol";
-
-contract MyGovernor is Governor, GovernorSettings, GovernorCountingSimple, GovernorVotes, GovernorTimelockControl {
- constructor(IVotes _token, TimelockController _timelock)
- Governor("MyGovernor")
- GovernorSettings(1 /* 1 block */, 45818 /* 1 week */, 0)
- GovernorVotes(_token)
- GovernorVotesQuorumFraction(4)
- GovernorTimelockControl(_timelock)
- {}
-
- // The following functions are overrides required by Solidity.
-
- function votingDelay()
- public
- view
- override(IGovernor, GovernorSettings)
- returns (uint256)
- {
- return super.votingDelay();
- }
-
- function votingPeriod()
- public
- view
- override(IGovernor, GovernorSettings)
- returns (uint256)
- {
- return super.votingPeriod();
- }
-
- function quorum(uint256 blockNumber)
- public
- view
- override(IGovernor, GovernorVotesQuorumFraction)
- returns (uint256)
- {
- return super.quorum(blockNumber);
- }
-
- function state(uint256 proposalId)
- public
- view
- override(Governor, GovernorTimelockControl)
- returns (ProposalState)
- {
- return super.state(proposalId);
- }
-
- function propose(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, string memory description)
- public
- override(Governor, IGovernor)
- returns (uint256)
- {
- // check if sender is enforcer
- return super.propose(targets, values, calldatas, description);
- }
-
- function proposalThreshold()
- public
- view
- override(Governor, GovernorSettings)
- returns (uint256)
- {
- return super.proposalThreshold();
- }
-
- function _execute(uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
- internal
- override(Governor, GovernorTimelockControl)
- {
- super._execute(proposalId, targets, values, calldatas, descriptionHash);
- }
-
- function _cancel(address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash)
- internal
- override(Governor, GovernorTimelockControl)
- returns (uint256)
- {
- return super._cancel(targets, values, calldatas, descriptionHash);
- }
-
- function _executor()
- internal
- view
- override(Governor, GovernorTimelockControl)
- returns (address)
- {
- return super._executor();
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- override(Governor, GovernorTimelockControl)
- returns (bool)
- {
- return super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5252/contracts/governance/Influencer.sol b/assets/eip-5252/contracts/governance/Influencer.sol
deleted file mode 100644
index d34000f..0000000
--- a/assets/eip-5252/contracts/governance/Influencer.sol
+++ /dev/null
@@ -1,44 +0,0 @@
-pragma solidity ^0.8.0;
-
-import "../interfaces/IABT.sol";
-import "../interfaces/IFactory.sol";
-import "../interfaces/IFinance.sol";
-import "../interfaces/IERC20Minimal.sol";
-
-contract Influencer {
-
- uint256 totalContributionValue;
-
- mapping(string => Weight) weights;
-
- struct Weight {
- uint256 percentage;
- uint256 decimal;
- }
-
- function getInfluence(address abt_, uint256 id_) public returns (uint multiplier) {
- return _getInfluence(abt_, id_);
- }
-
-
- function _getInfluence(address abt_, uint256 id_) internal returns (uint influence) {
- // get Finance address
- address factory = IABT(abt_).factory();
- address finance = IFactory(factory).getFinance(id_);
- address WETH = IFinance(finance).WETH();
- // normalize finance value
- uint256 norm_alpha = IERC20Minimal(WETH).balanceOf(finance) / totalContributionValue * 100;
- uint256 norm_beta = block.timestamp - IFinance(finance).createdAt() / block.timestamp * 100;
-
- // Divide with each decimal
- uint256 influence_dec = weights["alpha"].percentage * norm_alpha + weights["beta"].percentage * norm_beta;
- return influence_dec / weights["alpha"].decimal / weights["beta"].decimal;
- }
-
- function setWeight(string memory key, uint256 percentage, uint256 decimal) public {
- weights[key] = Weight({
- percentage: percentage,
- decimal: decimal
- });
- }
-}
\ No newline at end of file
diff --git a/assets/eip-5252/contracts/governance/Vote.sol b/assets/eip-5252/contracts/governance/Vote.sol
deleted file mode 100644
index 003ebb1..0000000
--- a/assets/eip-5252/contracts/governance/Vote.sol
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.2;
-
-import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
-import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol";
-import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol";
-import "@openzeppelin/contracts/governance/Governor.sol";
-import "../interfaces/IInfluencer.sol";
-import "../interfaces/IABT.sol";
-
-contract MyToken is ERC20, ERC20Permit, ERC20Votes, Governor {
- constructor() ERC20("GovToken", "GOV") ERC20Permit("Governance Token") {}
-
- mapping(address => uint256[]) private _multiplier;
- address public influencer;
-
- // The functions below are overrides required by Solidity.
-
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 amount
- ) internal override(ERC20, ERC20Votes) {
- super._afterTokenTransfer(from, to, amount);
- }
-
- function _mint(address to, uint256 amount)
- internal
- override(ERC20, ERC20Votes)
- {
- super._mint(to, amount);
- }
-
- function _burn(address account, uint256 amount)
- internal
- override(ERC20, ERC20Votes)
- {
- super._burn(account, amount);
- }
-
- function _sqrt(uint256 x) internal returns (uint256 y) {
- uint256 z = (x + 1) / 2;
- y = x;
- while (z < y) {
- y = z;
- z = (x / z + z) / 2;
- }
- }
-
- function getVotes(address account)
- public
- view
- virtual
- override
- returns (uint256)
- {
- uint256 pos = _checkpoints[account].length;
- uint256 vote = pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;
- // 0 as None, Multiplied with
- uint256 multiplied = _multiplier[pos - 1] > 0
- ? _sqrt(vote)
- : _sqrt(vote * _multiplier[pos - 1]);
- return multiplied;
- }
-
- function mulInfluence(address abt, uint256 id) public {
- require(IABT(abt).ownerOf(id) == msg.sender, "Vote: not abt owner");
- uint256 pos = _checkpoints[msg.sender].length;
- _multiplier[pos - 1] = IInfluencer.getInfluence(abt, id);
- }
-
- function setInfluencer(address influencer_) public onlyGovernance {
- influencer = influencer_;
- }
-}
diff --git a/assets/eip-5252/contracts/interfaces/IABT.sol b/assets/eip-5252/contracts/interfaces/IABT.sol
deleted file mode 100644
index e6b3d5f..0000000
--- a/assets/eip-5252/contracts/interfaces/IABT.sol
+++ /dev/null
@@ -1,11 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IABT {
- function mint(address to) external;
- function burn(uint256 tokenId_) external;
- function exists(uint256 tokenId_) external view returns (bool);
- function ownerOf(uint256 tokenId) external view returns (address owner);
- function factory() external view returns (address factory);
-}
diff --git a/assets/eip-5252/contracts/interfaces/IDescriptor.sol b/assets/eip-5252/contracts/interfaces/IDescriptor.sol
deleted file mode 100644
index eecf268..0000000
--- a/assets/eip-5252/contracts/interfaces/IDescriptor.sol
+++ /dev/null
@@ -1,5 +0,0 @@
-pragma solidity ^0.8.0;
-
-interface IDescriptor {
- function tokenURI(uint256 tokenId) external view returns (string memory);
-}
diff --git a/assets/eip-5252/contracts/interfaces/IERC20Minimal.sol b/assets/eip-5252/contracts/interfaces/IERC20Minimal.sol
deleted file mode 100644
index 5e58531..0000000
--- a/assets/eip-5252/contracts/interfaces/IERC20Minimal.sol
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity >=0.5.0;
-
-interface IERC20Minimal {
- function totalSupply() external view returns (uint);
- function balanceOf(address owner) external view returns (uint);
- function decimals() external view returns (uint8);
-}
diff --git a/assets/eip-5252/contracts/interfaces/IFactory.sol b/assets/eip-5252/contracts/interfaces/IFactory.sol
deleted file mode 100644
index e764bc1..0000000
--- a/assets/eip-5252/contracts/interfaces/IFactory.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IFactory {
-
- /// View funcs
- /// NFT token address
- function abt() external view returns (address);
- /// Address of wrapped eth
- function WETH() external view returns (address);
- /// Address of a manager
- function manager() external view returns (address);
-
- /// Getters
- /// Get Config of CDP
- function financeCodeHash() external pure returns (bytes32);
- function createFinance(address weth, uint256 amount_, address recipient) external returns (address vault, uint256 id);
- function getFinance(uint financeId_) external view returns (address);
-
- /// Event
- event FinanceCreated(uint256 vaultId, address collateral, address debt, address creator, address vault, uint256 cAmount, uint256 dAmount);
-}
diff --git a/assets/eip-5252/contracts/interfaces/IFinance.sol b/assets/eip-5252/contracts/interfaces/IFinance.sol
deleted file mode 100644
index 5f9749c..0000000
--- a/assets/eip-5252/contracts/interfaces/IFinance.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IFinance {
- event DepositFundNative(uint256 vaultID, uint256 amount);
- event WithdrawFundNative(uint256 vaultID, uint256 amount);
- /// Getters
- /// Address of a factory
- function factory() external view returns (address);
- /// Address of a manager
- function manager() external view returns (address);
- function influencer() external view returns (address);
- /// Address of account bound token
- function abt() external view returns (address);
- /// Finance global identifier
- function financeId() external view returns (uint256);
- /// Finance Last Updated Date
- function lastUpdated() external view returns (uint256);
- /// Finance creation date
- function createdAt() external view returns (uint256);
- /// address of wrapped eth
- function WETH() external view returns (address);
- /// deposit amount of finance account
- function deposit() external view returns (uint256);
-
- /// Functions
- function initialize(
- address manager_,
- uint256 financeId_,
- address abt_,
- uint256 amount_,
- address weth_
- ) external;
-
-}
diff --git a/assets/eip-5252/contracts/interfaces/IInfluencer.sol b/assets/eip-5252/contracts/interfaces/IInfluencer.sol
deleted file mode 100644
index c732c48..0000000
--- a/assets/eip-5252/contracts/interfaces/IInfluencer.sol
+++ /dev/null
@@ -1,7 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity >=0.5.0;
-
-interface IInfluencer {
- function isEnforcer(address sender) external;
-}
diff --git a/assets/eip-5252/contracts/interfaces/IManager.sol b/assets/eip-5252/contracts/interfaces/IManager.sol
deleted file mode 100644
index 3f7bfa1..0000000
--- a/assets/eip-5252/contracts/interfaces/IManager.sol
+++ /dev/null
@@ -1,9 +0,0 @@
-pragma solidity ^0.8.0;
-
-interface IManager {
- function factory() external view returns (address);
- function influencer() external view returns (address);
- function getExampleConfig(address something) external view returns (uint);
- event ConfigInitialized(address something, uint example);
- event FinanceCreated(uint id, address weth, address sender, address finance, uint input);
-}
diff --git a/assets/eip-5252/contracts/interfaces/IWETH.sol b/assets/eip-5252/contracts/interfaces/IWETH.sol
deleted file mode 100644
index 6cf78ea..0000000
--- a/assets/eip-5252/contracts/interfaces/IWETH.sol
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity >=0.5.0;
-
-interface IWETH {
- function deposit() external payable;
- function transfer(address to, uint value) external returns (bool);
- function withdraw(uint) external;
-}
diff --git a/assets/eip-5252/contracts/libraries/CloneFactory.sol b/assets/eip-5252/contracts/libraries/CloneFactory.sol
deleted file mode 100644
index 911e6b5..0000000
--- a/assets/eip-5252/contracts/libraries/CloneFactory.sol
+++ /dev/null
@@ -1,82 +0,0 @@
-library CloneFactory {
- function _createClone(address target) internal returns (address result) {
- // convert address to 20 bytes
- bytes20 targetBytes = bytes20(target);
-
- // actual code //
- // 3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3
-
- // creation code //
- // copy runtime code into memory and return it
- // 3d602d80600a3d3981f3
-
- // runtime code //
- // code to delegatecall to address
- // 363d3d373d3d3d363d73 address 5af43d82803e903d91602b57fd5bf3
-
- assembly {
- /*
- reads the 32 bytes of memory starting at pointer stored in 0x40
-
- In solidity, the 0x40 slot in memory is special: it contains the "free memory pointer"
- which points to the end of the currently allocated memory.
- */
- let clone := mload(0x40)
- // store 32 bytes to memory starting at "clone"
- mstore(
- clone,
- 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
- )
-
- /*
- | 20 bytes |
- 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
- ^
- pointer
- */
- // store 32 bytes to memory starting at "clone" + 20 bytes
- // 0x14 = 20
- mstore(add(clone, 0x14), targetBytes)
-
- /*
- | 20 bytes | 20 bytes |
- 0x3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe
- ^
- pointer
- */
- // store 32 bytes to memory starting at "clone" + 40 bytes
- // 0x28 = 40
- mstore(
- add(clone, 0x28),
- 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
- )
-
- /*
- | 20 bytes | 20 bytes | 15 bytes |
- 0x3d602d80600a3d3981f3363d3d373d3d3d363d73bebebebebebebebebebebebebebebebebebebebe5af43d82803e903d91602b57fd5bf3
- */
- // create new contract
- // send 0 Ether
- // code starts at pointer stored in "clone"
- // code size 0x37 (55 bytes)
- result := create(0, clone, 0x37)
- }
- }
-
- function _isClone(address target, address query) internal view returns (bool result) {
- bytes20 targetBytes = bytes20(target);
- assembly {
- let clone := mload(0x40)
- mstore(clone, 0x363d3d373d3d3d363d7300000000000000000000000000000000000000000000)
- mstore(add(clone, 0xa), targetBytes)
- mstore(add(clone, 0x1e), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
-
- let other := add(clone, 0x40)
- extcodecopy(query, other, 0, 0x2d)
- result := and(
- eq(mload(clone), mload(other)),
- eq(mload(add(clone, 0xd)), mload(add(other, 0xd)))
- )
- }
- }
-}
diff --git a/assets/eip-5252/contracts/libraries/Initializable.sol b/assets/eip-5252/contracts/libraries/Initializable.sol
deleted file mode 100644
index 55a3978..0000000
--- a/assets/eip-5252/contracts/libraries/Initializable.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-contract Initializable {
- bool private _initialized = false;
-
- modifier initializer() {
- // solhint-disable-next-line reason-string
- require(!_initialized);
- _;
- _initialized = true;
- }
-
- function initialized() external view returns (bool) {
- return _initialized;
- }
-}
diff --git a/assets/eip-5252/contracts/libraries/SVG.sol b/assets/eip-5252/contracts/libraries/SVG.sol
deleted file mode 100644
index e69de29..0000000
diff --git a/assets/eip-5252/contracts/libraries/TransferHelper.sol b/assets/eip-5252/contracts/libraries/TransferHelper.sol
deleted file mode 100644
index 550db79..0000000
--- a/assets/eip-5252/contracts/libraries/TransferHelper.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
-library TransferHelper {
- function safeApprove(address token, address to, uint value) internal {
- // bytes4(keccak256(bytes("approve(address,uint256)")));
- (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
- require(success && (data.length == 0 || abi.decode(data, (bool))), "AF");
- }
-
- function safeTransfer(address token, address to, uint value) internal {
- // bytes4(keccak256(bytes("transfer(address,uint256)")));
- (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
- require(success && (data.length == 0 || abi.decode(data, (bool))), "TF");
- }
-
- function safeTransferFrom(address token, address from, address to, uint value) internal {
- // bytes4(keccak256(bytes("transferFrom(address,address,uint256)")));
- (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
- require(success && (data.length == 0 || abi.decode(data, (bool))), "TFF");
- }
-
- function safeTransferETH(address to, uint value) internal {
- (bool success,) = to.call{value:value}(new bytes(0));
- require(success, "ETF");
- }
-}
diff --git a/assets/eip-5252/hardhat.config.ts b/assets/eip-5252/hardhat.config.ts
deleted file mode 100644
index 414e974..0000000
--- a/assets/eip-5252/hardhat.config.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { HardhatUserConfig } from "hardhat/config";
-import "@nomicfoundation/hardhat-toolbox";
-
-const config: HardhatUserConfig = {
- solidity: "0.8.9",
-};
-
-export default config;
diff --git a/assets/eip-5252/media/media.svg b/assets/eip-5252/media/media.svg
deleted file mode 100644
index c74c943..0000000
--- a/assets/eip-5252/media/media.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/assets/eip-5252/package.json b/assets/eip-5252/package.json
deleted file mode 100644
index af7ea0c..0000000
--- a/assets/eip-5252/package.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "name": "hardhat-project",
- "devDependencies": {
- "@nomicfoundation/hardhat-toolbox": "^1.0.2",
- "hardhat": "^2.10.1",
- "ts-node": "^10.9.1",
- "typescript": "^4.7.4"
- },
- "dependencies": {
- "@openzeppelin/contracts": "^4.7.1"
- }
-}
diff --git a/assets/eip-5252/scripts/deploy.ts b/assets/eip-5252/scripts/deploy.ts
deleted file mode 100644
index 90e8908..0000000
--- a/assets/eip-5252/scripts/deploy.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { ethers } from "hardhat";
-
-async function main() {
- const currentTimestampInSeconds = Math.round(Date.now() / 1000);
- const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
- const unlockTime = currentTimestampInSeconds + ONE_YEAR_IN_SECS;
-
- const lockedAmount = ethers.utils.parseEther("1");
-
- const Lock = await ethers.getContractFactory("Lock");
- const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
-
- await lock.deployed();
-
- console.log("Lock with 1 ETH deployed to:", lock.address);
-}
-
-// We recommend this pattern to be able to use async/await everywhere
-// and properly handle errors.
-main().catch((error) => {
- console.error(error);
- process.exitCode = 1;
-});
diff --git a/assets/eip-5252/test/Lock.ts b/assets/eip-5252/test/Lock.ts
deleted file mode 100644
index 3127221..0000000
--- a/assets/eip-5252/test/Lock.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-
-describe("Lock", function () {
- // We define a fixture to reuse the same setup in every test.
- // We use loadFixture to run this setup once, snapshot that state,
- // and reset Hardhat Network to that snapshopt in every test.
- async function deployOneYearLockFixture() {
- const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
- const ONE_GWEI = 1_000_000_000;
-
- const lockedAmount = ONE_GWEI;
- const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
-
- // Contracts are deployed using the first signer/account by default
- const [owner, otherAccount] = await ethers.getSigners();
-
- const Lock = await ethers.getContractFactory("Lock");
- const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
-
- return { lock, unlockTime, lockedAmount, owner, otherAccount };
- }
-
- describe("Deployment", function () {
- it("Should set the right unlockTime", async function () {
- const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
-
- expect(await lock.unlockTime()).to.equal(unlockTime);
- });
-
- it("Should set the right owner", async function () {
- const { lock, owner } = await loadFixture(deployOneYearLockFixture);
-
- expect(await lock.owner()).to.equal(owner.address);
- });
-
- it("Should receive and store the funds to lock", async function () {
- const { lock, lockedAmount } = await loadFixture(
- deployOneYearLockFixture
- );
-
- expect(await ethers.provider.getBalance(lock.address)).to.equal(
- lockedAmount
- );
- });
-
- it("Should fail if the unlockTime is not in the future", async function () {
- // We don't use the fixture here because we want a different deployment
- const latestTime = await time.latest();
- const Lock = await ethers.getContractFactory("Lock");
- await expect(Lock.deploy(latestTime, { value: 1 })).to.be.revertedWith(
- "Unlock time should be in the future"
- );
- });
- });
-
- describe("Withdrawals", function () {
- describe("Validations", function () {
- it("Should revert with the right error if called too soon", async function () {
- const { lock } = await loadFixture(deployOneYearLockFixture);
-
- await expect(lock.withdraw()).to.be.revertedWith(
- "You can't withdraw yet"
- );
- });
-
- it("Should revert with the right error if called from another account", async function () {
- const { lock, unlockTime, otherAccount } = await loadFixture(
- deployOneYearLockFixture
- );
-
- // We can increase the time in Hardhat Network
- await time.increaseTo(unlockTime);
-
- // We use lock.connect() to send a transaction from another account
- await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith(
- "You aren't the owner"
- );
- });
-
- it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
- const { lock, unlockTime } = await loadFixture(
- deployOneYearLockFixture
- );
-
- // Transactions are sent using the first signer by default
- await time.increaseTo(unlockTime);
-
- await expect(lock.withdraw()).not.to.be.reverted;
- });
- });
-
- describe("Events", function () {
- it("Should emit an event on withdrawals", async function () {
- const { lock, unlockTime, lockedAmount } = await loadFixture(
- deployOneYearLockFixture
- );
-
- await time.increaseTo(unlockTime);
-
- await expect(lock.withdraw())
- .to.emit(lock, "Withdrawal")
- .withArgs(lockedAmount, anyValue); // We accept any value as `when` arg
- });
- });
-
- describe("Transfers", function () {
- it("Should transfer the funds to the owner", async function () {
- const { lock, unlockTime, lockedAmount, owner } = await loadFixture(
- deployOneYearLockFixture
- );
-
- await time.increaseTo(unlockTime);
-
- await expect(lock.withdraw()).to.changeEtherBalances(
- [owner, lock],
- [lockedAmount, -lockedAmount]
- );
- });
- });
- });
-});
diff --git a/assets/eip-5252/tsconfig.json b/assets/eip-5252/tsconfig.json
deleted file mode 100644
index e5f1a64..0000000
--- a/assets/eip-5252/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "compilerOptions": {
- "target": "es2020",
- "module": "commonjs",
- "esModuleInterop": true,
- "forceConsistentCasingInFileNames": true,
- "strict": true,
- "skipLibCheck": true
- }
-}
diff --git a/assets/eip-5269/contracts/ERC5269.sol b/assets/eip-5269/contracts/ERC5269.sol
deleted file mode 100644
index 4d89b47..0000000
--- a/assets/eip-5269/contracts/ERC5269.sol
+++ /dev/null
@@ -1,39 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Author: Zainan Victor Zhou
-// DRAFTv1
-// Source https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5269
-// Deployment https://goerli.etherscan.io/address/0x33F735852619E3f99E1AF069cCf3b9232b2806bE#code
-
-pragma solidity ^0.8.9;
-
-import "./IERC5269.sol";
-
-contract ERC5269 is IERC5269 {
- bytes32 constant public EIP_STATUS = keccak256("DRAFTv1");
- constructor () {
- emit OnSupportEIP(address(0x0), 5269, bytes32(0), EIP_STATUS, "");
- }
-
- function _supportEIP(
- address /*caller*/,
- uint256 majorEIPIdentifier,
- bytes32 minorEIPIdentifier,
- bytes calldata /*extraData*/)
- internal virtual view returns (bytes32 eipStatus) {
- if (majorEIPIdentifier == 5269) {
- if (minorEIPIdentifier == bytes32(0)) {
- return EIP_STATUS;
- }
- }
- return bytes32(0);
- }
-
- function supportEIP(
- address caller,
- uint256 majorEIPIdentifier,
- bytes32 minorEIPIdentifier,
- bytes calldata extraData)
- external virtual view returns (bytes32 eipStatus) {
- return _supportEIP(caller, majorEIPIdentifier, minorEIPIdentifier, extraData);
- }
-}
diff --git a/assets/eip-5269/contracts/IERC5269.sol b/assets/eip-5269/contracts/IERC5269.sol
deleted file mode 100644
index 8b44454..0000000
--- a/assets/eip-5269/contracts/IERC5269.sol
+++ /dev/null
@@ -1,34 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Author: Zainan Victor Zhou
-// DRAFTv1
-// Source https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5269
-// Deployment https://goerli.etherscan.io/address/0x33F735852619E3f99E1AF069cCf3b9232b2806bE#code
-pragma solidity ^0.8.9;
-
-interface IERC5269 {
- event OnSupportEIP(
- address indexed caller, // when emitted with `address(0x0)` means all callers.
- uint256 indexed majorEIPIdentifier,
- bytes32 indexed minorEIPIdentifier, // 0 means the entire EIP
- bytes32 eipStatus,
- bytes extraData
- );
-
- /// @dev The core method of EIP/ERC Interface Detection
- /// @param caller, a `address` value of the address of a caller being queried whether the given EIP is supported.
- /// @param majorEIPIdentifier, a `uint256` value and SHOULD BE the EIP number being queried. Unless superseded by future EIP, such EIP number SHOULD BE less or equal to (0, 2^32-1]. For a function call to `supportEIP`, any value outside of this range is deemed unspecified and open to implementation's choice or for future EIPs to specify.
- /// @param minorEIPIdentifier, a `bytes32` value reserved for authors of individual EIP to specify. For example the author of [EIP-721](/EIPS/eip-721) MAY specify `keccak256("ERC721Metadata")` or `keccak256("ERC721Metadata.tokenURI")` as `minorEIPIdentifier` to be quired for support. Author could also use this minorEIPIdentifier to specify different versions, such as EIP-712 has its V1-V4 with different behavior.
- /// @param extraData, a `bytes` for [EIP-5750](/EIPS/eip-5750) for future extensions.
- /// @return eipStatus a bytes32 indicating the status of EIP the contract supports.
- /// - For FINAL EIPs, it MUST return `keccak256("FINAL")`.
- /// - For non-FINAL EIPs, it SHOULD return `keccak256("DRAFT")`.
- /// During EIP procedure, EIP authors are allowed to specify their own
- /// eipStatus other than `FINAL` or `DRAFT` at their discretion such as `keccak256("DRAFTv1")`
- /// or `keccak256("DRAFT-option1")`and such value of eipStatus MUST be documented in the EIP body
- function supportEIP(
- address caller,
- uint256 majorEIPIdentifier,
- bytes32 minorEIPIdentifier,
- bytes calldata extraData)
- external view returns (bytes32 eipStatus);
-}
diff --git a/assets/eip-5269/contracts/testing/ERC721ForTesting.sol b/assets/eip-5269/contracts/testing/ERC721ForTesting.sol
deleted file mode 100644
index 22d21c4..0000000
--- a/assets/eip-5269/contracts/testing/ERC721ForTesting.sol
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Author: Zainan Victor Zhou
-// DRAFTv1
-// Source https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5269
-// Deployment https://goerli.etherscan.io/address/0x33F735852619E3f99E1AF069cCf3b9232b2806bE#code
-pragma solidity ^0.8.9;
-// import 721
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-// impport 5269
-import "../ERC5269.sol";
-
-contract ERC721ForTesting is ERC721, ERC5269 {
-
- bytes32 constant public EIP_FINAL = keccak256("FINAL");
- constructor() ERC721("ERC721ForTesting", "E721FT") ERC5269() {
- _mint(msg.sender, 0);
- emit OnSupportEIP(address(0x0), 721, bytes32(0), EIP_FINAL, "");
- emit OnSupportEIP(address(0x0), 721, keccak256("ERC721Metadata"), EIP_FINAL, "");
- emit OnSupportEIP(address(0x0), 721, keccak256("ERC721Enumerable"), EIP_FINAL, "");
- }
-
- function supportEIP(
- address caller,
- uint256 majorEIPIdentifier,
- bytes32 minorEIPIdentifier,
- bytes calldata extraData)
- external
- override
- view
- returns (bytes32 eipStatus) {
- if (majorEIPIdentifier == 721) {
- if (minorEIPIdentifier == 0) {
- return keccak256("FINAL");
- } else if (minorEIPIdentifier == keccak256("ERC721Metadata")) {
- return keccak256("FINAL");
- } else if (minorEIPIdentifier == keccak256("ERC721Enumerable")) {
- return keccak256("FINAL");
- }
- }
- return super._supportEIP(caller, majorEIPIdentifier, minorEIPIdentifier, extraData);
- }
-}
diff --git a/assets/eip-5269/test/TestERC5269.ts b/assets/eip-5269/test/TestERC5269.ts
deleted file mode 100644
index b71635d..0000000
--- a/assets/eip-5269/test/TestERC5269.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-// Author: Zainan Victor Zhou
-// DRAFTv1
-// Source https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5269
-// Deployment https://goerli.etherscan.io/address/0x33F735852619E3f99E1AF069cCf3b9232b2806bE#code
-
-import { loadFixture, mine } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { BigNumber, ContractReceipt, Wallet } from "ethers";
-import { ethers } from "hardhat";
-
-describe("ERC5269", function () {
- async function deployFixture() {
- // Contracts are deployed using the first signer/account by default
- const [owner, mintSender, recipient] = await ethers.getSigners();
- const testWallet: Wallet = new ethers.Wallet("0x0000000000000000000000000000000000000000000000000000000000000001");
-
- const factory = await ethers.getContractFactory("ERC5269");
- const contract = await factory.deploy();
- let tx1 = await contract.deployed();
- let txDeployErc5269: ContractReceipt = await tx1.deployTransaction.wait();
-
- const ERC721ForTesting = await ethers.getContractFactory("ERC721ForTesting");
- const erc721ForTesting = await ERC721ForTesting.deploy();
- let tx2 = await erc721ForTesting.deployed();
- const txDeployErc721: ContractReceipt = await tx2.deployTransaction.wait();
- const provider = ethers.provider;
- return {
- provider,
- contract,
- erc721ForTesting,
- tx1, txDeployErc5269,
- tx2, txDeployErc721,
- owner, mintSender, recipient, testWallet
- };
- }
-
- describe("Deployment", function () {
- it("Should be deployable", async function () {
- await loadFixture(deployFixture);
- });
-
- it("Should emit proper OnSupportEIP events", async function () {
- let { txDeployErc721 } = await loadFixture(deployFixture);
- let events = txDeployErc721.events?.filter(event => event.event === 'OnSupportEIP');
- expect(events).to.have.lengthOf(4);
-
- let ev5269 = events!.filter(
- (event) => event.args!.majorEIPIdentifier.eq(5269));
- expect(ev5269).to.have.lengthOf(1);
- expect(ev5269[0].args!.caller).to.equal(BigNumber.from(0));
- expect(ev5269[0].args!.minorEIPIdentifier).to.equal(BigNumber.from(0));
- expect(ev5269[0].args!.eipStatus).to.equal(ethers.utils.id("DRAFTv1"));
-
- let ev721 = events!.filter(
- (event) => event.args!.majorEIPIdentifier.eq(721));
- expect(ev721).to.have.lengthOf(3);
- expect(ev721[0].args!.caller).to.equal(BigNumber.from(0));
- expect(ev721[0].args!.minorEIPIdentifier).to.equal(BigNumber.from(0));
- expect(ev721[0].args!.eipStatus).to.equal(ethers.utils.id("FINAL"));
-
- expect(ev721[1].args!.caller).to.equal(BigNumber.from(0));
- expect(ev721[1].args!.minorEIPIdentifier).to.equal(ethers.utils.id("ERC721Metadata"));
- expect(ev721[1].args!.eipStatus).to.equal(ethers.utils.id("FINAL"));
-
- expect(ev721[2].args!.caller).to.equal(BigNumber.from(0));
- expect(ev721[2].args!.minorEIPIdentifier).to.equal(ethers.utils.id("ERC721Enumerable"));
- expect(ev721[2].args!.eipStatus).to.equal(ethers.utils.id("FINAL"));
- });
-
- it("Should return proper eipStatus value when called supportEIP() for declared supported EIP/features", async function () {
- let { erc721ForTesting, owner } = await loadFixture(deployFixture);
- expect(await erc721ForTesting.supportEIP(owner.address, 5269, ethers.utils.hexZeroPad("0x00", 32), [])).to.equal(ethers.utils.id("DRAFTv1"));
- expect(await erc721ForTesting.supportEIP(owner.address, 721, ethers.utils.hexZeroPad("0x00", 32), [])).to.equal(ethers.utils.id("FINAL"));
- expect(await erc721ForTesting.supportEIP(owner.address, 721, ethers.utils.id("ERC721Metadata"), [])).to.equal(ethers.utils.id("FINAL"));
- expect(await erc721ForTesting.supportEIP(owner.address, 721, ethers.utils.id("ERC721Enumerable"), [])).to.equal(ethers.utils.id("FINAL"));
-
- expect(await erc721ForTesting.supportEIP(owner.address, 721, ethers.utils.id("WRONG FEATURE"), [])).to.equal(BigNumber.from(0));
- expect(await erc721ForTesting.supportEIP(owner.address, 9999, ethers.utils.hexZeroPad("0x00", 32), [])).to.equal(BigNumber.from(0));
- });
-
- it("Should return zero as eipStatus value when called supportEIP() for non declared EIP/features", async function () {
- let { erc721ForTesting, owner } = await loadFixture(deployFixture);
- expect(await erc721ForTesting.supportEIP(owner.address, 721, ethers.utils.id("WRONG FEATURE"), [])).to.equal(BigNumber.from(0));
- expect(await erc721ForTesting.supportEIP(owner.address, 9999, ethers.utils.hexZeroPad("0x00", 32), [])).to.equal(BigNumber.from(0));
- });
- });
-});
diff --git a/assets/eip-5289/ERC5289Library.sol b/assets/eip-5289/ERC5289Library.sol
deleted file mode 100644
index 04bb6c7..0000000
--- a/assets/eip-5289/ERC5289Library.sol
+++ /dev/null
@@ -1,42 +0,0 @@
-/// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./interfaces/IERC165.sol";
-import "./interfaces/IERC5289Library.sol";
-
-contract ERC5289Library is IERC165, IERC5289Library {
- uint16 private counter = 0;
- mapping(uint16 => string) private uris;
- mapping(uint16 => mapping(address => uint64)) signedAt;
-
- constructor() { }
-
- function registerDocument(string memory uri) public returns (uint16) {
- uris[counter] = uri;
- return counter++;
- }
-
- function legalDocument(uint16 documentId) public view returns (string uri) {
- return uris[documentId];
- }
-
- function documentSigned(address user, uint16 documentId) public view returns (bool isSigned) {
- return signedAt[documentId][user] != 0;
- }
-
- function documentSignedAt(address user, uint16 documentId) public view returns (uint64 timestamp) {
- return signedAt[documentId][user];
- }
-
- function signDocument(address signer, uint16 documentId) public {
- require(signer == msg.sender, "invalid user");
-
- signedAt[documentId][msg.sender] = uint64(block.timestamp);
-
- emit DocumentSigned(msg.sender, documentId);
- }
-
- function supportsInterface(bytes4 _interfaceId) public view returns (bool) {
- return _interfaceId == type(IERC5289Library).interfaceId;
- }
-}
diff --git a/assets/eip-5289/example-popup.png b/assets/eip-5289/example-popup.png
deleted file mode 100644
index 957bb6b..0000000
Binary files a/assets/eip-5289/example-popup.png and /dev/null differ
diff --git a/assets/eip-5289/interfaces/IERC165.sol b/assets/eip-5289/interfaces/IERC165.sol
deleted file mode 100644
index 3e6ec8e..0000000
--- a/assets/eip-5289/interfaces/IERC165.sol
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC165 {
- /// @notice Query if a contract implements an interface
- /// @param interfaceID The interface identifier, as specified in ERC-165
- /// @dev Interface identification is specified in ERC-165. This function
- /// uses less than 30,000 gas.
- /// @return `true` if the contract implements `interfaceID` and
- /// `interfaceID` is not 0xffffffff, `false` otherwise
- function supportsInterface(bytes4 interfaceID) external view returns (bool);
-}
diff --git a/assets/eip-5289/interfaces/IERC5289Library.sol b/assets/eip-5289/interfaces/IERC5289Library.sol
deleted file mode 100644
index 6eb68b1..0000000
--- a/assets/eip-5289/interfaces/IERC5289Library.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-/// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC165.sol";
-
-interface IERC5289Library is IERC165 {
- /// @notice Emitted when signDocument is called
- event DocumentSigned(address indexed signer, uint16 indexed documentId);
-
- /// @notice An immutable link to the legal document (RECOMMENDED to be hosted on IPFS). This MUST use a common file format, such as PDF, HTML, TeX, or Markdown.
- function legalDocument(uint16 documentId) external view returns (string memory);
-
- /// @notice Returns whether or not the given user signed the document.
- function documentSigned(address user, uint16 documentId) external view returns (bool signed);
-
- /// @notice Returns when the the given user signed the document.
- /// @dev If the user has not signed the document, the timestamp may be anything.
- function documentSignedAt(address user, uint16 documentId) external view returns (uint64 timestamp);
-
- /// @notice Sign a document
- /// @dev This MUST be validated by the smart contract. This MUST emit DocumentSigned or throw.
- function signDocument(address signer, uint16 documentId) external;
-}
diff --git a/assets/eip-5334/ERC5334.sol b/assets/eip-5334/ERC5334.sol
deleted file mode 100644
index b6a79ac..0000000
--- a/assets/eip-5334/ERC5334.sol
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC5334.sol";
-
-contract ERC5334 is ERC721, IERC5334 {
- struct UserInfo
- {
- address user; // address of user role
- uint64 expires; // unix timestamp, user expires
- uint8 level; // user level
- }
-
- mapping (uint256 => UserInfo) internal _users;
-
- constructor(string memory name_, string memory symbol_)
- ERC721(name_,symbol_)
- {
- }
-
- /// @notice set the user and expires and level of a NFT
- /// @dev The zero address indicates there is no user
- /// Throws if `tokenId` is not valid NFT
- /// @param user The new user of the NFT
- /// @param expires UNIX timestamp, The new user could use the NFT before expires
- /// @param level user level
- function setUser(uint256 tokenId, address user, uint64 expires, uint8 level) public virtual{
- require(_isApprovedOrOwner(msg.sender, tokenId),"ERC721: transfer caller is not owner nor approved");
- UserInfo storage info = _users[tokenId];
- info.user = user;
- info.expires = expires;
- info.level = level
- emit UpdateUser(tokenId,user,expires,level);
- }
-
- /// @notice Get the user address of an NFT
- /// @dev The zero address indicates that there is no user or the user is expired
- /// @param tokenId The NFT to get the user address for
- /// @return The user address for this NFT
- function userOf(uint256 tokenId)public view virtual returns(address){
- if( uint256(_users[tokenId].expires) >= block.timestamp){
- return _users[tokenId].user;
- }
- else{
- return address(0);
- }
- }
-
- /// @notice Get the user expires of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user expires for
- /// @return The user expires for this NFT
- function userExpires(uint256 tokenId) public view virtual returns(uint256){
- return _users[tokenId].expires;
- }
-
- /// @notice Get the user level of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user level for
- /// @return The user level for this NFT
- function userLevel(uint256 tokenId) public view virtual returns(uint256){
- return _users[tokenId].level;
- }
-
- /// @dev See {IERC165-supportsInterface}.
- function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
- return interfaceId == type(IERC5334).interfaceId || super.supportsInterface(interfaceId);
- }
-
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override{
- super._beforeTokenTransfer(from, to, tokenId);
-
- if (from != to && _users[tokenId].user != address(0)) {
- delete _users[tokenId];
- emit UpdateUser(tokenId, address(0), 0, 0);
- }
- }
-}
-
diff --git a/assets/eip-5334/IERC5334.sol b/assets/eip-5334/IERC5334.sol
deleted file mode 100644
index 0adc386..0000000
--- a/assets/eip-5334/IERC5334.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5334 {
- // Logged when the user of a token assigns a new user or updates expires
- /// @notice Emitted when the `user` of an NFT or the `expires` of the `user` is changed or the `level` of the `user` is changed
- /// The zero address for user indicates that there is no user address
- event UpdateUser(uint256 indexed tokenId, address indexed user, uint64 expires, uint8 level);
-
- /// @notice set the user and expires of a NFT
- /// @dev The zero address indicates there is no user
- /// Throws if `tokenId` is not valid NFT
- /// @param user The new user of the NFT
- /// @param expires UNIX timestamp, The new user could use the NFT before expires
- /// @param level user level
- function setUser(uint256 tokenId, address user, uint64 expires, uint8 level) external ;
-
- /// @notice Get the user address of an NFT
- /// @dev The zero address indicates that there is no user or the user is expired
- /// @param tokenId The NFT to get the user address for
- /// @return The user address for this NFT
- function userOf(uint256 tokenId) external view returns(address);
-
- /// @notice Get the user expires of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user expires for
- /// @return The user expires for this NFT
- function userExpires(uint256 tokenId) external view returns(uint256);
-
- /// @notice Get the user level of an NFT
- /// @dev The zero value indicates that there is no user
- /// @param tokenId The NFT to get the user level for
- /// @return The user level for this NFT
- function userLevel(uint256 tokenId) external view returns(uint256);
-}
diff --git a/assets/eip-5345/walletconnect-flow.png b/assets/eip-5345/walletconnect-flow.png
deleted file mode 100644
index 4e0ab78..0000000
Binary files a/assets/eip-5345/walletconnect-flow.png and /dev/null differ
diff --git a/assets/eip-5453/AERC5453.sol b/assets/eip-5453/AERC5453.sol
deleted file mode 100644
index f3b4d76..0000000
--- a/assets/eip-5453/AERC5453.sol
+++ /dev/null
@@ -1,271 +0,0 @@
-// SPDX-License-Identifier: CC0.0 OR Apache-2.0
-// Author: Zainan Victor Zhou
-// See a full runnable hardhat project in https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5453
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/utils/cryptography/SignatureChecker.sol";
-import "@openzeppelin/contracts/utils/cryptography/EIP712.sol";
-
-import "./IERC5453.sol";
-
-abstract contract AERC5453Endorsible is EIP712,
- IERC5453EndorsementCore, IERC5453EndorsementDigest, IERC5453EndorsementDataTypeA, IERC5453EndorsementDataTypeB {
- uint256 private threshold;
- uint256 private currentNonce = 0;
- bytes32 constant MAGIC_WORLD = keccak256("ERC5453-ENDORSEMENT"); // ASCII of "ENDORSED"
- uint256 constant ERC5453_TYPE_A = 1;
- uint256 constant ERC5453_TYPE_B = 2;
-
- constructor(
- string memory _name,
- string memory _erc721Version
- ) EIP712(_name, _erc721Version) {}
-
- function _validate(
- bytes32 msgDigest,
- SingleEndorsementData memory endersement
- ) internal virtual {
- require(
- endersement.sig.length == 65,
- "AERC5453Endorsible: wrong signature length"
- );
- require(
- SignatureChecker.isValidSignatureNow(
- endersement.endorserAddress,
- msgDigest,
- endersement.sig
- ),
- "AERC5453Endorsible: invalid signature"
- );
- }
-
- function _extractEndorsers(
- bytes32 digest,
- GeneralExtensionDataStruct memory data
- ) internal virtual returns (address[] memory endorsers) {
- require(
- data.erc5453MagicWord == MAGIC_WORLD,
- "AERC5453Endorsible: MagicWord not matched"
- );
- require(
- data.validSince <= block.number,
- "AERC5453Endorsible: Not valid yet"
- ); // TODO consider per-Endorser validSince
- require(data.validBy >= block.number, "AERC5453Endorsible: Expired"); // TODO consider per-Endorser validBy
- require(
- currentNonce == data.nonce,
- "AERC5453Endorsible: Nonce not matched"
- ); // TODO consider per-Endorser nonce or range of nonce
- currentNonce += 1;
-
- if (data.erc5453Type == ERC5453_TYPE_A) {
- SingleEndorsementData memory endersement = abi.decode(
- data.endorsementPayload,
- (SingleEndorsementData)
- );
- endorsers = new address[](1);
- endorsers[0] = endersement.endorserAddress;
- _validate(digest, endersement);
- } else if (data.erc5453Type == ERC5453_TYPE_B) {
- SingleEndorsementData[] memory endorsements = abi.decode(
- data.endorsementPayload,
- (SingleEndorsementData[])
- );
- endorsers = new address[](endorsements.length);
- for (uint256 i = 0; i < endorsements.length; ++i) {
- endorsers[i] = endorsements[i].endorserAddress;
- _validate(digest, endorsements[i]);
- }
- return endorsers;
- }
- }
-
- function _decodeExtensionData(
- bytes memory extensionData
- ) internal pure virtual returns (GeneralExtensionDataStruct memory) {
- return abi.decode(extensionData, (GeneralExtensionDataStruct));
- }
-
- // Well, I know this is epensive. Let's improve it later.
- function _noRepeat(address[] memory _owners) internal pure returns (bool) {
- for (uint256 i = 0; i < _owners.length; i++) {
- for (uint256 j = i + 1; j < _owners.length; j++) {
- if (_owners[i] == _owners[j]) {
- return false;
- }
- }
- }
- return true;
- }
-
- function _isEndorsed(
- bytes32 _functionParamStructHash,
- bytes calldata _extraData
- ) internal returns (bool) {
- GeneralExtensionDataStruct memory _data = _decodeExtensionData(
- _extraData
- );
- bytes32 finalDigest = _computeValidityDigest(
- _functionParamStructHash,
- _data.validSince,
- _data.validBy,
- _data.nonce
- );
-
- address[] memory endorsers = _extractEndorsers(finalDigest, _data);
- require(
- endorsers.length >= threshold,
- "AERC5453Endorsable: not enough endorsers"
- );
- require(_noRepeat(endorsers));
- for (uint256 i = 0; i < endorsers.length; i++) {
- require(
- _isEligibleEndorser(endorsers[i]),
- "AERC5453Endorsable: not eligible endorsers"
- ); // everyone must be a legit endorser
- }
- return true;
- }
-
- function _isEligibleEndorser(
- address /*_endorser*/
- ) internal view virtual returns (bool);
-
- modifier onlyEndorsed(
- bytes32 _functionParamStructHash,
- bytes calldata _extensionData
- ) {
- require(_isEndorsed(_functionParamStructHash, _extensionData));
- _;
- }
-
- function _computeValidityDigest(
- bytes32 _functionParamStructHash,
- uint256 _validSince,
- uint256 _validBy,
- uint256 _nonce
- ) internal view returns (bytes32) {
- return
- super._hashTypedDataV4(
- keccak256(
- abi.encode(
- keccak256(
- "ValidityBound(bytes32 functionParamStructHash,uint256 validSince,uint256 validBy,uint256 nonce)"
- ),
- _functionParamStructHash,
- _validSince,
- _validBy,
- _nonce
- )
- )
- );
- }
-
- function _computeFunctionParamHash(
- string memory _functionStructure,
- bytes memory _functionParamPacked
- ) internal pure returns (bytes32) {
- bytes32 functionParamStructHash = keccak256(
- abi.encodePacked(
- keccak256(bytes(_functionStructure)),
- _functionParamPacked
- )
- );
- return functionParamStructHash;
- }
-
- function _setThreshold(uint256 _threshold) internal virtual {
- threshold = _threshold;
- }
-
- function computeValidityDigest(
- bytes32 _functionParamStructHash,
- uint256 _validSince,
- uint256 _validBy,
- uint256 _nonce
- ) external view override returns (bytes32) {
- return
- _computeValidityDigest(
- _functionParamStructHash,
- _validSince,
- _validBy,
- _nonce
- );
- }
-
- function computeFunctionParamHash(
- string memory _functionName,
- bytes memory _functionParamPacked
- ) external pure override returns (bytes32) {
- return
- _computeFunctionParamHash(
- _functionName,
- _functionParamPacked
- );
- }
-
- function eip5453Nonce(address addr) external view override returns (uint256) {
- require(address(this) == addr, "AERC5453Endorsable: not self");
- return currentNonce;
- }
-
- function isEligibleEndorser(address _endorser)
- external
- view
- override
- returns (bool)
- {
- return _isEligibleEndorser(_endorser);
- }
-
- function computeExtensionDataTypeA(
- uint256 nonce,
- uint256 validSince,
- uint256 validBy,
- address endorserAddress,
- bytes calldata sig
- ) external pure override returns (bytes memory) {
- return
- abi.encode(
- GeneralExtensionDataStruct(
- MAGIC_WORLD,
- ERC5453_TYPE_A,
- nonce,
- validSince,
- validBy,
- abi.encode(SingleEndorsementData(endorserAddress, sig))
- )
- );
- }
-
- function computeExtensionDataTypeB(
- uint256 nonce,
- uint256 validSince,
- uint256 validBy,
- address[] calldata endorserAddress,
- bytes[] calldata sigs
- ) external pure override returns (bytes memory) {
- require(endorserAddress.length == sigs.length);
- SingleEndorsementData[]
- memory endorsements = new SingleEndorsementData[](
- endorserAddress.length
- );
- for (uint256 i = 0; i < endorserAddress.length; ++i) {
- endorsements[i] = SingleEndorsementData(
- endorserAddress[i],
- sigs[i]
- );
- }
- return
- abi.encode(
- GeneralExtensionDataStruct(
- MAGIC_WORLD,
- ERC5453_TYPE_B,
- nonce,
- validSince,
- validBy,
- abi.encode(endorsements)
- )
- );
- }
-}
diff --git a/assets/eip-5453/EndorsableERC721.sol b/assets/eip-5453/EndorsableERC721.sol
deleted file mode 100644
index 3299ef8..0000000
--- a/assets/eip-5453/EndorsableERC721.sol
+++ /dev/null
@@ -1,47 +0,0 @@
-/// SPDX-License-Identifier: CC0.0 OR Apache-2.0
-// Author: Zainan Victor Zhou
-// See a full runnable hardhat project in https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5453
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-
-import "./AERC5453.sol";
-
-contract EndorsableERC721 is ERC721, AERC5453Endorsible {
- mapping(address => bool) private owners;
-
- constructor()
- ERC721("ERC721ForTesting", "ERC721ForTesting")
- AERC5453Endorsible("EndorsableERC721", "v1")
- {
- owners[msg.sender] = true;
- }
-
- function addOwner(address _owner) external {
- require(owners[msg.sender], "EndorsableERC721: not owner");
- owners[_owner] = true;
- }
-
- function mint(
- address _to,
- uint256 _tokenId,
- bytes calldata _extraData
- )
- external
- onlyEndorsed(
- _computeFunctionParamHash(
- "function mint(address _to,uint256 _tokenId)",
- abi.encode(_to, _tokenId)
- ),
- _extraData
- )
- {
- _mint(_to, _tokenId);
- }
-
- function _isEligibleEndorser(
- address _endorser
- ) internal view override returns (bool) {
- return owners[_endorser];
- }
-}
diff --git a/assets/eip-5453/IERC5453.sol b/assets/eip-5453/IERC5453.sol
deleted file mode 100644
index d51df70..0000000
--- a/assets/eip-5453/IERC5453.sol
+++ /dev/null
@@ -1,65 +0,0 @@
-// SPDX-License-Identifier: CC0.0 OR Apache-2.0
-// Author: Zainan Victor Zhou
-// See a full runnable hardhat project in https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5453
-pragma solidity ^0.8.9;
-
-struct ValidityBound {
- bytes32 functionParamStructHash;
- uint256 validSince;
- uint256 validBy;
- uint256 nonce;
-}
-
-struct SingleEndorsementData {
- address endorserAddress; // 32
- bytes sig; // dynamic = 65
-}
-
-struct GeneralExtensionDataStruct {
- bytes32 erc5453MagicWord;
- uint256 erc5453Type;
- uint256 nonce;
- uint256 validSince;
- uint256 validBy;
- bytes endorsementPayload;
-}
-
-interface IERC5453EndorsementCore {
- function eip5453Nonce(address endorser) external view returns (uint256);
- function isEligibleEndorser(address endorser) external view returns (bool);
-}
-
-interface IERC5453EndorsementDigest {
- function computeValidityDigest(
- bytes32 _functionParamStructHash,
- uint256 _validSince,
- uint256 _validBy,
- uint256 _nonce
- ) external view returns (bytes32);
-
- function computeFunctionParamHash(
- string memory _functionName,
- bytes memory _functionParamPacked
- ) external view returns (bytes32);
-}
-
-interface IERC5453EndorsementDataTypeA {
- function computeExtensionDataTypeA(
- uint256 nonce,
- uint256 validSince,
- uint256 validBy,
- address endorserAddress,
- bytes calldata sig
- ) external view returns (bytes memory);
-}
-
-
-interface IERC5453EndorsementDataTypeB {
- function computeExtensionDataTypeB(
- uint256 nonce,
- uint256 validSince,
- uint256 validBy,
- address[] calldata endorserAddress,
- bytes[] calldata sigs
- ) external view returns (bytes memory);
-}
diff --git a/assets/eip-5453/ThresholdMultiSigForwarder.sol b/assets/eip-5453/ThresholdMultiSigForwarder.sol
deleted file mode 100644
index c366e6d..0000000
--- a/assets/eip-5453/ThresholdMultiSigForwarder.sol
+++ /dev/null
@@ -1,56 +0,0 @@
-// SPDX-License-Identifier: CC0.0 OR Apache-2.0
-// Author: Zainan Victor Zhou
-// See a full runnable hardhat project in https://github.com/ercref/ercref-contracts/tree/main/ERCs/eip-5453
-pragma solidity ^0.8.9;
-
-import "./AERC5453.sol";
-
-contract ThresholdMultiSigForwarder is AERC5453Endorsible {
- mapping(address => bool) private owners;
- uint256 private ownerCount;
-
- constructor() AERC5453Endorsible("ThresholdMultiSigForwarder", "v1") {}
-
- function initialize(
- address[] calldata _owners,
- uint256 _threshold
- ) external {
- require(_threshold >= 1, "Threshold must be positive");
- require(_owners.length >= _threshold);
- require(_noRepeat(_owners));
- _setThreshold(_threshold);
- for (uint256 i = 0; i < _owners.length; i++) {
- owners[_owners[i]] = true;
- }
- ownerCount = _owners.length;
- }
-
- function forward(
- address _dest,
- uint256 _value,
- uint256 _gasLimit,
- bytes calldata _calldata,
- bytes calldata _extraData
- )
- external
- onlyEndorsed(
- _computeFunctionParamHash(
- "function forward(address _dest,uint256 _value,uint256 _gasLimit,bytes calldata _calldata)",
- abi.encode(_dest, _value, _gasLimit, keccak256(_calldata))
- ),
- _extraData
- )
- {
- string memory errorMessage = "Fail to call remote contract";
- (bool success, bytes memory returndata) = _dest.call{value: _value}(
- _calldata
- );
- Address.verifyCallResult(success, returndata, errorMessage);
- }
-
- function _isEligibleEndorser(
- address _endorser
- ) internal view override returns (bool) {
- return owners[_endorser] == true;
- }
-}
diff --git a/assets/eip-5489/contracts/ERC5489.sol b/assets/eip-5489/contracts/ERC5489.sol
deleted file mode 100644
index 8625d77..0000000
--- a/assets/eip-5489/contracts/ERC5489.sol
+++ /dev/null
@@ -1,127 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./IERC5489.sol";
-
-contract ERC5489 is IERC5489, ERC721Enumerable, Ownable {
- using EnumerableSet for EnumerableSet.AddressSet;
-
- mapping(uint256 => EnumerableSet.AddressSet) tokenId2AuthroizedAddresses;
- mapping(uint256 => mapping(address=> string)) tokenId2Address2Value;
- mapping(uint256 => string) tokenId2ImageUri;
-
- string private _imageURI;
- string private _name;
-
- constructor() ERC721("Hyperlink NFT Collection", "HNFT") {}
-
- modifier onlyTokenOwner(uint256 tokenId) {
- require(_msgSender() == ownerOf(tokenId), "should be the token owner");
- _;
- }
-
- modifier onlySlotManager(uint256 tokenId) {
- require(_msgSender() == ownerOf(tokenId) || tokenId2AuthroizedAddresses[tokenId].contains(_msgSender()), "address should be authorized");
- _;
- }
-
- function setSlotUri(uint256 tokenId, string calldata value) override external onlySlotManager(tokenId) {
- tokenId2Address2Value[tokenId][_msgSender()] = value;
-
- emit SlotUriUpdated(tokenId, _msgSender(), value);
- }
-
- function getSlotUri(uint256 tokenId, address slotManagerAddr) override external view returns (string memory) {
- return tokenId2Address2Value[tokenId][slotManagerAddr];
- }
-
- function authorizeSlotTo(uint256 tokenId, address slotManagerAddr) override external onlyTokenOwner(tokenId) {
- require(!tokenId2AuthroizedAddresses[tokenId].contains(slotManagerAddr), "address already authorized");
-
- _authorizeSlotTo(tokenId, slotManagerAddr);
- }
-
- function _authorizeSlotTo(uint256 tokenId, address slotManagerAddr) private {
- tokenId2AuthroizedAddresses[tokenId].add(slotManagerAddr);
- emit SlotAuthorizationCreated(tokenId, slotManagerAddr);
- }
-
- function revokeAuthorization(uint256 tokenId, address slotManagerAddr) override external onlyTokenOwner(tokenId) {
- tokenId2AuthroizedAddresses[tokenId].remove(slotManagerAddr);
- delete tokenId2Address2Value[tokenId][slotManagerAddr];
-
- emit SlotAuthorizationRevoked(tokenId, slotManagerAddr);
- }
-
- function revokeAllAuthorizations(uint256 tokenId) override external onlyTokenOwner(tokenId) {
- for (uint256 i = tokenId2AuthroizedAddresses[tokenId].length() - 1;i > 0; i--) {
- address addr = tokenId2AuthroizedAddresses[tokenId].at(i);
- tokenId2AuthroizedAddresses[tokenId].remove(addr);
- delete tokenId2Address2Value[tokenId][addr];
-
- emit SlotAuthorizationRevoked(tokenId, addr);
- }
-
- if (tokenId2AuthroizedAddresses[tokenId].length() > 0) {
- address addr = tokenId2AuthroizedAddresses[tokenId].at(0);
- tokenId2AuthroizedAddresses[tokenId].remove(addr);
- delete tokenId2Address2Value[tokenId][addr];
-
- emit SlotAuthorizationRevoked(tokenId, addr);
- }
- }
-
- function isSlotManager(uint256 tokenId, address addr) public view returns (bool) {
- return tokenId2AuthroizedAddresses[tokenId].contains(addr);
- }
-
- // !!expensive, should call only when no gas is needed;
- function getSlotManagers(uint256 tokenId) external view returns (address[] memory) {
- return tokenId2AuthroizedAddresses[tokenId].values();
- }
-
- function _mintToken(uint256 tokenId, string calldata imageUri) private {
- _safeMint(msg.sender, tokenId);
- tokenId2ImageUri[tokenId] = imageUri;
- }
-
- function mint(string calldata imageUri) external {
- uint256 tokenId = totalSupply() + 1;
- _mintToken(tokenId, imageUri);
- }
-
- function mintAndAuthorizeTo(string calldata imageUri, address slotManagerAddr) external {
- uint256 tokenId = totalSupply() + 1;
- _mintToken(tokenId, imageUri);
- _authorizeSlotTo(tokenId, slotManagerAddr);
- }
-
- function tokenURI(uint256 _tokenId) public view override returns (string memory) {
- require(
- _exists(_tokenId),
- "URI query for nonexistent token"
- );
-
- return
- string(
- abi.encodePacked(
- "data:application/json;base64,",
- Base64.encode(
- bytes(
- abi.encodePacked(
- '{"name":"',
- abi.encodePacked(
- _name,
- " # ",
- Strings.toString(_tokenId)
- ),
- '",',
- '"description":"Hyperlink NFT collection created with Parami Foundation"',
- '}'
- )
- )
- )
- )
- );
- }
-}
diff --git a/assets/eip-5489/contracts/IERC5489.sol b/assets/eip-5489/contracts/IERC5489.sol
deleted file mode 100644
index ba6ba4f..0000000
--- a/assets/eip-5489/contracts/IERC5489.sol
+++ /dev/null
@@ -1,63 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC5489 {
- /**
- * @dev this event emits when the slot on `tokenId` is authorzized to `slotManagerAddr`
- */
- event SlotAuthorizationCreated(uint256 indexed tokenId, address indexed slotManagerAddr);
-
- /**
- * @dev this event emits when the authorization on slot `slotManagerAddr` of token `tokenId` is revoked.
- * So, the corresponding DApp can handle this to stop on-going incentives or rights
- */
- event SlotAuthorizationRevoked(uint256 indexed tokenId, address indexed slotManagerAddr);
-
- /**
- * @dev this event emits when the uri on slot `slotManagerAddr` of token `tokenId` has been updated to `uri`.
- */
- event SlotUriUpdated(uint256 indexed tokenId, address indexed slotManagerAddr, string uri);
-
- /**
- * @dev
- * Authorize a hyperlink slot on `tokenId` to address `slotManagerAddr`.
- * Indeed slot is an entry in a map whose key is address `slotManagerAddr`.
- * Only the address `slotManagerAddr` can manage the specific slot.
- * This method will emit SlotAuthorizationCreated event
- */
- function authorizeSlotTo(uint256 tokenId, address slotManagerAddr) external;
-
- /**
- * @dev
- * Revoke the authorization of the slot indicated by `slotManagerAddr` on token `tokenId`
- * This method will emit SlotAuthorizationRevoked event
- */
- function revokeAuthorization(uint256 tokenId, address slotManagerAddr) external;
-
- /**
- * @dev
- * Revoke all authorizations of slot on token `tokenId`
- * This method will emit SlotAuthorizationRevoked event for each slot
- */
- function revokeAllAuthorizations(uint256 tokenId) external;
-
- /**
- * @dev
- * Set uri for a slot on a token, which is indicated by `tokenId` and `slotManagerAddr`
- * Only the address with authorization through {authorizeSlotTo} can manipulate this slot.
- * This method will emit SlotUriUpdated event
- */
- function setSlotUri(
- uint256 tokenId,
- string calldata newUri
- ) external;
-
- /**
- * @dev
- * returns the latest uri of an slot on a token, which is indicated by `tokenId`, `slotManagerAddr`
- */
- function getSlotUri(uint256 tokenId, address slotManagerAddr)
- external
- view
- returns (string memory);
-}
\ No newline at end of file
diff --git a/assets/eip-5496/contracts/ERC5496.sol b/assets/eip-5496/contracts/ERC5496.sol
deleted file mode 100644
index fe5c467..0000000
--- a/assets/eip-5496/contracts/ERC5496.sol
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import "./IERC5496.sol";
-
-contract ERC5496 is ERC721, IERC5496 {
- struct PrivilegeRecord {
- address user;
- uint256 expiresAt;
- }
- struct PrivilegeStorage {
- uint lastExpiresAt;
- // privId => PrivilegeRecord
- mapping(uint => PrivilegeRecord) privilegeEntry;
- }
-
- uint public privilegeTotal;
- // tokenId => PrivilegeStorage
- mapping(uint => PrivilegeStorage) public privilegeBook;
- mapping(address => mapping(address => bool)) private privilegeDelegator;
-
- constructor(string memory name_, string memory symbol_)
- ERC721(name_,symbol_)
- {
-
- }
-
- function setPrivilege(
- uint tokenId,
- uint privId,
- address user,
- uint64 expires
- ) external virtual {
- require((hasPrivilege(tokenId, privId, ownerOf(tokenId)) && _isApprovedOrOwner(msg.sender, tokenId)) || _isDelegatorOrHolder(msg.sender, tokenId, privId), "ERC721: transfer caller is not owner nor approved");
- require(expires < block.timestamp + 30 days, "expire time invalid");
- require(privId < privilegeTotal, "invalid privilege id");
- privilegeBook[tokenId].privilegeEntry[privId].user = user;
- if (_isApprovedOrOwner(msg.sender, tokenId)) {
- privilegeBook[tokenId].privilegeEntry[privId].expiresAt = expires;
- if (privilegeBook[tokenId].lastExpiresAt < expires) {
- privilegeBook[tokenId].lastExpiresAt = expires;
- }
- }
- emit PrivilegeAssigned(tokenId, privId, user, uint64(privilegeBook[tokenId].privilegeEntry[privId].expiresAt));
- }
-
- function hasPrivilege(
- uint256 tokenId,
- uint256 privId,
- address user
- ) public virtual view returns(bool) {
- if ( privilegeBook[tokenId].privilegeEntry[privId].expiresAt >= block.timestamp ){
- return privilegeBook[tokenId].privilegeEntry[privId].user == user;
- }
- return ownerOf(tokenId) == user;
- }
-
- function privilegeExpires(
- uint256 tokenId,
- uint256 privId
- ) public virtual view returns(uint256){
- return privilegeBook[tokenId].privilegeEntry[privId].expiresAt;
- }
-
- function _setPrivilegeTotal(
- uint total
- ) internal {
- emit PrivilegeTotalChanged(total, privilegeTotal);
- privilegeTotal = total;
- }
-
- function getPrivilegeInfo(uint tokenId, uint privId) external view returns(address user, uint256 expiresAt) {
- return (privilegeBook[tokenId].privilegeEntry[privId].user, privilegeBook[tokenId].privilegeEntry[privId].expiresAt);
- }
-
- function setDelegator(address delegator, bool enabled) external {
- privilegeDelegator[msg.sender][delegator] = enabled;
- }
-
- function _isDelegatorOrHolder(address delegator, uint256 tokenId, uint privId) internal virtual view returns (bool) {
- address holder = privilegeBook[tokenId].privilegeEntry[privId].user;
- return (delegator == holder || privilegeDelegator[holder][delegator]);
- }
-
- function supportsInterface(bytes4 interfaceId) public override virtual view returns (bool) {
- return interfaceId == type(IERC5496).interfaceId || super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5496/contracts/ERC5496CloneableDemo.sol b/assets/eip-5496/contracts/ERC5496CloneableDemo.sol
deleted file mode 100644
index 49f7fb1..0000000
--- a/assets/eip-5496/contracts/ERC5496CloneableDemo.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./extensions/ERC5496Cloneable.sol";
-
-contract ERC5496CloneableDemo is ERC5496Cloneable {
-
- constructor(string memory name_, string memory symbol_)
- ERC5496(name_,symbol_)
- {
-
- }
-
- function mint(uint256 tokenId, address to) public {
- _mint(to, tokenId);
- }
-
- function setPrivilegeTotal(uint total) external {
- _setPrivilegeTotal(total);
- }
-
- function increasePrivileges(bool _cloneable) external {
- uint privId = privilegeTotal;
- _setPrivilegeTotal(privilegeTotal + 1);
- cloneable[privId] = _cloneable;
- }
-}
diff --git a/assets/eip-5496/contracts/ERC5496Demo.sol b/assets/eip-5496/contracts/ERC5496Demo.sol
deleted file mode 100644
index deb7c07..0000000
--- a/assets/eip-5496/contracts/ERC5496Demo.sol
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-import "./ERC5496.sol";
-
-contract ERC5496Demo is ERC5496 {
-
- constructor(string memory name_, string memory symbol_)
- ERC5496(name_,symbol_)
- {
-
- }
-
- function mint(uint256 tokenId, address to) public {
- _mint(to, tokenId);
- }
-
- function setPrivilegeTotal(uint total) external {
- _setPrivilegeTotal(total);
- }
-
- function increasePrivileges(bool ) external {
- _setPrivilegeTotal(privilegeTotal + 1);
- }
-}
diff --git a/assets/eip-5496/contracts/IERC5496.sol b/assets/eip-5496/contracts/IERC5496.sol
deleted file mode 100644
index 178241a..0000000
--- a/assets/eip-5496/contracts/IERC5496.sol
+++ /dev/null
@@ -1,10 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC5496 {
- event PrivilegeAssigned(uint tokenId, uint privId, address user, uint64 expires);
- event PrivilegeTotalChanged(uint newTotal, uint oldTotal);
- function setPrivilege(uint256 tokenId, uint privId, address user, uint64 expires) external;
- function privilegeExpires(uint256 tokenId, uint256 privId) external view returns(uint256);
- function hasPrivilege(uint256 tokenId, uint256 privId, address user) external view returns(bool);
-}
diff --git a/assets/eip-5496/contracts/extensions/ERC5496Cloneable.sol b/assets/eip-5496/contracts/extensions/ERC5496Cloneable.sol
deleted file mode 100644
index c08d829..0000000
--- a/assets/eip-5496/contracts/extensions/ERC5496Cloneable.sol
+++ /dev/null
@@ -1,57 +0,0 @@
-// SPDX-License-Identifier: MIT
-// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)
-
-pragma solidity ^0.8.0;
-
-import "../ERC5496.sol";
-import "./IERC5496Cloneable.sol";
-
-/**
- * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
- * enumerability of all the token ids in the contract as well as all token ids owned by each
- * account.
- */
-abstract contract ERC5496Cloneable is ERC5496, IERC5496Cloneable {
- struct CloneableRecord {
- // account => shared
- mapping(address => bool) shared;
- // account => refer
- mapping(address => address) referrer;
- }
-
- // privId => isCloneable
- mapping(uint => bool) public cloneable;
- // tokenId => privId => CloneableRecord
- mapping(uint => mapping(uint => CloneableRecord)) cloneableSetting;
-
- function supportsInterface(bytes4 interfaceId) public override virtual view returns (bool) {
- return interfaceId == type(IERC5496Cloneable).interfaceId || super.supportsInterface(interfaceId);
- }
-
- function hasPrivilege(
- uint256 tokenId,
- uint256 privId,
- address user
- ) public override virtual view returns(bool) {
- if ( privilegeBook[tokenId].privilegeEntry[privId].expiresAt >= block.timestamp ){
- return cloneableSetting[tokenId][privId].shared[user] || super.hasPrivilege(tokenId, privId, user);
- }
- return ownerOf(tokenId) == user;
- }
-
- function clonePrivilege(uint tokenId, uint privId, address referrer) external returns (bool) {
- require(cloneable[privId], "privilege not cloneable");
- return _clonePrivilege(tokenId, privId, referrer);
- }
-
- function _clonePrivilege(uint tokenId, uint privId, address referrer) internal returns (bool) {
- require(privilegeBook[tokenId].privilegeEntry[privId].user == referrer || cloneableSetting[tokenId][privId].shared[referrer], "referrer not exists");
- if (cloneableSetting[tokenId][privId].referrer[msg.sender] == address(0)) {
- cloneableSetting[tokenId][privId].shared[msg.sender] = true;
- cloneableSetting[tokenId][privId].referrer[msg.sender] = referrer;
- emit PrivilegeCloned(tokenId, privId, referrer, msg.sender);
- return true;
- }
- return false;
- }
-}
diff --git a/assets/eip-5496/contracts/extensions/IERC5496Cloneable.sol b/assets/eip-5496/contracts/extensions/IERC5496Cloneable.sol
deleted file mode 100644
index 9228e7c..0000000
--- a/assets/eip-5496/contracts/extensions/IERC5496Cloneable.sol
+++ /dev/null
@@ -1,7 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC5496Cloneable {
- event PrivilegeCloned(uint tokenId, uint privId, address from, address to);
- function clonePrivilege(uint tokenId, uint privId, address referrer) external returns (bool);
-}
diff --git a/assets/eip-5496/test/test.js b/assets/eip-5496/test/test.js
deleted file mode 100644
index f8d47d5..0000000
--- a/assets/eip-5496/test/test.js
+++ /dev/null
@@ -1,122 +0,0 @@
-const { assert } = require("chai");
-const { expectRevert } = require('@openzeppelin/test-helpers');
-
-const ERC5496Demo = artifacts.require("ERC5496Demo");
-
-contract("ERC5496", async accounts => {
- const Alice = accounts[0];
- const Bob = accounts[1];
- const Tom = accounts[2];
- let demoContract;
-
- before(async function() {
- const instance = await ERC5496Demo.deployed("ERC5496Demo", "EPD");
- demoContract = instance;
- await demoContract.mint(1, Alice);
- await demoContract.mint(2, Alice);
- await demoContract.mint(3, Alice);
- await demoContract.increasePrivileges(false);
- await demoContract.increasePrivileges(false);
- })
-
- it("Should set privilege 0 to Bob", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(1, 0, Bob, BigInt(expires));
-
- let user_hasP0 = await demoContract.hasPrivilege(1, 0, Bob);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 1 should be Bob"
- );
- });
-
- it("Privilege should belong to the owner by default", async () => {
- let owner_1 = await demoContract.ownerOf(1);
- assert.equal(
- owner_1,
- Alice ,
- "Owner of NFT 1 should be Alice"
- );
- let user_hasP1 = await demoContract.hasPrivilege(1, 1, Alice);
- assert.equal(
- user_hasP1,
- true,
- "Privilege 1 of NFT 1 should be Alice"
- );
- });
-
- it("The privilege holder is allowed to transfer the privilege to others", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(2, 0, Bob, BigInt(expires));
- let user_hasP0 = await demoContract.hasPrivilege(2, 0, Bob);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 2 should be Bob"
- );
- await demoContract.setPrivilege(2, 0, Tom, BigInt(expires + 100), { from: Bob })
- user_hasP0 = await demoContract.hasPrivilege(2, 0, Tom);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 2 should be Tom"
- );
- let privilege_info = await demoContract.getPrivilegeInfo(2, 0);
- assert.equal(
- privilege_info.expiresAt,
- expires,
- "Only owner can set the expiresAt"
- )
- });
-
- it("User is allowed to transfer NFT while privileges on renting", async () => {
- await demoContract.transferFrom(Alice, Bob, 1);
- let owner_1 = await demoContract.ownerOf(1);
- assert.equal(
- owner_1,
- Bob,
- "Owner of NFT 1 should be Bob"
- );
- let expires = Math.floor(new Date().getTime()/1000) + 1000;
- await demoContract.setPrivilege(1, 1, Tom, BigInt(expires), { from: Bob });
- let user_hasP1 = await demoContract.hasPrivilege(1, 1, Tom);
- assert.equal(
- user_hasP1,
- true,
- "Bob should be allowed to set the unassigned privilege to Tom"
- );
- });
-
- it("NFT owner may change the privileges total for each tokenId", async () => {
- await demoContract.increasePrivileges(false);
- let owner_1 = await demoContract.ownerOf(1);
- let user_hasP2 = await demoContract.hasPrivilege(1, 2, owner_1);
- assert.equal(
- user_hasP2,
- true,
- "privilege 2 available after NFT owner update the privilege total"
- );
- });
-
- it("NFT owner should not change the privilege if it has been assigned", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(3, 0, Bob, BigInt(expires));
- await expectRevert(
- demoContract.setPrivilege(3, 0, Tom, BigInt(expires)),
- "ERC721: transfer caller is not owner nor approved",
- );
- });
-
- it("NFT should support interface IERC5496", async () => {
- const interfaceIds = {
- IERC165: "0x01ffc9a7",
- IERC721: "0x80ac58cd",
- IERC5496: "0x076e1bbb",
- }
- for(let interfaceName in interfaceIds) {
- let isSupport = await demoContract.supportsInterface(interfaceIds[interfaceName]);
- assert.equal(isSupport, true, "NFT should support interface "+interfaceName);
- }
- })
-});
diff --git a/assets/eip-5496/test/testCloneable.js b/assets/eip-5496/test/testCloneable.js
deleted file mode 100644
index 07e316e..0000000
--- a/assets/eip-5496/test/testCloneable.js
+++ /dev/null
@@ -1,158 +0,0 @@
-const { assert } = require("chai");
-const { expectRevert } = require('@openzeppelin/test-helpers');
-
-const ERC5496Demo = artifacts.require("ERC5496CloneableDemo");
-
-contract("ERC5496Cloneable", async accounts => {
- const Alice = accounts[0];
- const Bob = accounts[1];
- const Tom = accounts[2];
- let demoContract;
-
- before(async function() {
- const instance = await ERC5496Demo.deployed("ERC5496CDemo", "EPCD");
- demoContract = instance;
- await demoContract.mint(1, Alice);
- await demoContract.mint(2, Alice);
- await demoContract.mint(3, Alice);
- await demoContract.mint(4, Alice);
- await demoContract.increasePrivileges(false);
- await demoContract.increasePrivileges(false);
- await demoContract.increasePrivileges(false);
- await demoContract.increasePrivileges(true);
- })
-
- it("Should set privilege 0 to Bob", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(1, 0, Bob, BigInt(expires));
-
- let user_hasP0 = await demoContract.hasPrivilege(1, 0, Bob);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 1 should be Bob"
- );
- });
-
- it("Privilege should belong to the owner by default", async () => {
- let owner_1 = await demoContract.ownerOf(1);
- assert.equal(
- owner_1,
- Alice ,
- "Owner of NFT 1 should be Alice"
- );
- let user_hasP1 = await demoContract.hasPrivilege(1, 1, Alice);
- assert.equal(
- user_hasP1,
- true,
- "Privilege 1 of NFT 1 should be Alice"
- );
- });
-
- it("The privilege holder is allowed to transfer the privilege to others", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(2, 0, Bob, BigInt(expires));
- let user_hasP0 = await demoContract.hasPrivilege(2, 0, Bob);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 2 should be Bob"
- );
- await demoContract.setPrivilege(2, 0, Tom, BigInt(expires + 100), { from: Bob })
- user_hasP0 = await demoContract.hasPrivilege(2, 0, Tom);
- assert.equal(
- user_hasP0,
- true,
- "Privilege 0 of NFT 2 should be Tom"
- );
- let privilege_info = await demoContract.getPrivilegeInfo(2, 0);
- assert.equal(
- privilege_info.expiresAt,
- expires,
- "Only owner can set the expiresAt"
- )
- });
-
- it("User is allowed to transfer NFT while privileges on renting", async () => {
- await demoContract.transferFrom(Alice, Bob, 1);
- let owner_1 = await demoContract.ownerOf(1);
- assert.equal(
- owner_1,
- Bob,
- "Owner of NFT 1 should be Bob"
- );
- let expires = Math.floor(new Date().getTime()/1000) + 1000;
- await demoContract.setPrivilege(1, 1, Tom, BigInt(expires), { from: Bob });
- let user_hasP1 = await demoContract.hasPrivilege(1, 1, Tom);
- assert.equal(
- user_hasP1,
- true,
- "Bob should be allowed to set unassigned privilege to Tom"
- );
- });
-
- it("NFT owner may change the privileges total for each tokenId", async () => {
- let owner_1 = await demoContract.ownerOf(1);
- let user_hasP2 = await demoContract.hasPrivilege(1, 2, owner_1);
- assert.equal(
- user_hasP2,
- true,
- "privilege 2 available after NFT owner update the privilege total"
- );
- });
-
- it("NFT owner should not change the privilege if it has been assigned", async () => {
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(3, 0, Bob, BigInt(expires));
- await expectRevert(
- demoContract.setPrivilege(3, 0, Tom, BigInt(expires)),
- "ERC721: transfer caller is not owner nor approved",
- );
- });
-
- it("ERC5496 cloneable", async () => {
- let owner_1 = await demoContract.ownerOf(4);
- let cloneable_P2 = await demoContract.cloneable(2);
- assert.equal(
- cloneable_P2,
- false,
- "privilege 2 should not be cloneable"
- );
- let cloneable_P3 = await demoContract.cloneable(3);
- assert.equal(
- cloneable_P3,
- true,
- "privilege 3 should be cloneable"
- );
- let expires = Math.floor(new Date().getTime()/1000) + 5000;
- await demoContract.setPrivilege(4, 3, Bob, BigInt(expires), { from: Alice });
-
- await expectRevert(
- demoContract.clonePrivilege(4, 2, owner_1, {from: Bob}),
- "privilege not cloneable",
- );
- await expectRevert(
- demoContract.clonePrivilege(4, 3, Tom, { from: Bob }),
- "referrer not exists",
- );
- await demoContract.clonePrivilege(4, 3, Bob, { from: Tom });
- let user_hasP3 = await demoContract.hasPrivilege(4, 3, Tom);
- assert.equal(
- user_hasP3,
- true,
- "privilege 3 available after Bob cloned"
- );
- });
-
- it("NFT should support interface IERC5496", async () => {
- const interfaceIds = {
- IERC165: "0x01ffc9a7",
- IERC721: "0x80ac58cd",
- IERC5496: "0x076e1bbb",
- }
- for(let interfaceName in interfaceIds) {
- let isSupport = await demoContract.supportsInterface(interfaceIds[interfaceName]);
- assert.equal(isSupport, true, "NFT should support interface "+interfaceName);
- }
- })
-});
diff --git a/assets/eip-5501/contracts/ERC5501.sol b/assets/eip-5501/contracts/ERC5501.sol
deleted file mode 100644
index 6dd2f65..0000000
--- a/assets/eip-5501/contracts/ERC5501.sol
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC5501.sol";
-
-/**
- * @dev Implementation of https://eips.ethereum.org/EIPS/eip-5501 with OpenZeppelin ERC721 version.
- */
-contract ERC5501 is IERC5501, ERC721 {
- /**
- * @dev Structure to hold user information.
- * @notice If isBorrowed is true, UserInfo cannot be modified before it expires.
- */
- struct UserInfo {
- address user; // Address of user role
- uint64 expires; // Unix timestamp, user expires on
- bool isBorrowed; // Borrowed flag
- }
-
- // Mapping from token ID to UserInfo
- mapping(uint256 => UserInfo) internal _users;
-
- /**
- * @dev Initializes the contract by setting a name and a symbol to the token collection.
- */
- constructor(string memory name_, string memory symbol_)
- ERC721(name_, symbol_)
- {}
-
- /**
- * @dev See {IERC5501-setUser}.
- */
- function setUser(
- uint256 tokenId,
- address user,
- uint64 expires,
- bool isBorrowed
- ) public virtual override {
- require(
- _isApprovedOrOwner(msg.sender, tokenId),
- "ERC5501: set user caller is not token owner or approved"
- );
- require(user != address(0), "ERC5501: set user to zero address");
-
- UserInfo storage info = _users[tokenId];
- require(
- !info.isBorrowed || info.expires < block.timestamp,
- "ERC5501: token is borrowed"
- );
- info.user = user;
- info.expires = expires;
- info.isBorrowed = isBorrowed;
- emit UpdateUser(tokenId, user, expires, isBorrowed);
- }
-
- /**
- * @dev See {IERC5501-userOf}.
- */
- function userOf(uint256 tokenId)
- public
- view
- virtual
- override
- returns (address)
- {
- require(
- uint256(_users[tokenId].expires) >= block.timestamp,
- "ERC5501: user does not exist for this token"
- );
- return _users[tokenId].user;
- }
-
- /**
- * @dev See {IERC5501-userExpires}.
- */
- function userExpires(uint256 tokenId)
- public
- view
- virtual
- override
- returns (uint64)
- {
- return _users[tokenId].expires;
- }
-
- /**
- * @dev See {IERC5501-isBorrowed}.
- */
- function userIsBorrowed(uint256 tokenId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return _users[tokenId].isBorrowed;
- }
-
- /**
- * @dev See {EIP-165: Standard Interface Detection}.
- * https://eips.ethereum.org/EIPS/eip-165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5501).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev Hook that is called after any token transfer.
- * If user is set and token is not borrowed, reset user.
- */
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override {
- super._afterTokenTransfer(from, to, tokenId);
- if (
- from != to &&
- !_users[tokenId].isBorrowed &&
- _users[tokenId].user != address(0)
- ) {
- delete _users[tokenId];
- emit UpdateUser(tokenId, address(0), 0, false);
- }
- }
-}
diff --git a/assets/eip-5501/contracts/ERC5501Balance.sol b/assets/eip-5501/contracts/ERC5501Balance.sol
deleted file mode 100644
index a967ccb..0000000
--- a/assets/eip-5501/contracts/ERC5501Balance.sol
+++ /dev/null
@@ -1,102 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC5501.sol";
-import "./IERC5501Balance.sol";
-
-/**
- * @dev Implementation of Balance extension of https://eips.ethereum.org/EIPS/eip-5501 with OpenZeppelin ERC721 version.
- */
-contract ERC5501Balance is IERC5501Balance, ERC5501 {
- // Mapping from address to userOf tokens
- mapping(address => uint256[]) internal _userBalances;
-
- /**
- * @dev Initializes the contract by setting a name and a symbol to the token collection.
- */
- constructor(string memory name_, string memory symbol_)
- ERC5501(name_, symbol_)
- {}
-
- /**
- * @dev See {IERC5501-setUser}.
- */
- function setUser(
- uint256 tokenId,
- address user,
- uint64 expires,
- bool isBorrowed
- ) public virtual override {
- flushExpired(user);
- super.setUser(tokenId, user, expires, isBorrowed);
- _userBalances[user].push(tokenId);
- }
-
- /**
- * @dev See {IERC5501-userBalanceOf}.
- */
- function userBalanceOf(address user)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(
- user != address(0),
- "ERC5501Balance: address zero is not a valid owner"
- );
- uint256 balance;
- uint256[] memory candidates = _userBalances[user];
- unchecked {
- for (uint256 i; i < candidates.length; ++i) {
- if (
- _users[candidates[i]].expires >= block.timestamp &&
- _users[candidates[i]].user == user
- ) {
- ++balance;
- }
- }
- }
- return balance;
- }
-
- /**
- * @notice On setUser flush all expired userOf statuses.
- * @dev This function may revert out of gas if user borrows too many tokens at once.
- * There must be a way to prevent such behaviour (such as flushing by parts only).
- * @param user an address to flush
- */
- function flushExpired(address user) internal {
- uint256[] storage candidates = _userBalances[user];
- unchecked {
- for (uint256 i; i < candidates.length; ++i) {
- if (
- _users[candidates[i]].user != user ||
- _users[candidates[i]].expires < block.timestamp
- ) {
- candidates[i] = candidates[candidates.length - 1];
- candidates.pop();
- --i; // test moved element
- }
- }
- }
- }
-
- /**
- * @dev See {EIP-165: Standard Interface Detection}.
- * https://eips.ethereum.org/EIPS/eip-165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5501Balance).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5501/contracts/ERC5501Combined.sol b/assets/eip-5501/contracts/ERC5501Combined.sol
deleted file mode 100644
index 95f8b27..0000000
--- a/assets/eip-5501/contracts/ERC5501Combined.sol
+++ /dev/null
@@ -1,325 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "./IERC5501.sol";
-import "./IERC5501Balance.sol";
-import "./IERC5501Enumerable.sol";
-import "./IERC5501Terminable.sol";
-
-/**
- * @dev Implementation of ERC5501 contract with all extensions https://eips.ethereum.org/EIPS/eip-5501 with OpenZeppelin ERC721 version.
- */
-contract ERC5501Combined is
- IERC5501,
- IERC5501Balance,
- IERC5501Terminable,
- IERC5501Enumerable,
- ERC721
-{
- /**
- * @dev Structure to hold user information.
- * @notice If isBorrowed is true, UserInfo cannot be modified before it expires.
- */
- struct UserInfo {
- address user; // Address of user role
- uint64 expires; // Unix timestamp, user expires on
- bool isBorrowed; // Borrowed flag
- }
-
- /**
- * @dev Structure to hold agreements from both parties to terminate a borrow.
- * @notice If both parties agree, it is possible to modify UserInfo even before it expires.
- * In such case, isBorrowed status is reverted to false.
- */
- struct BorrowTerminationInfo {
- bool lenderAgreement;
- bool borrowerAgreement;
- }
-
- // Mapping from token ID to UserInfo
- mapping(uint256 => UserInfo) internal _users;
-
- // Mapping from address to userOf tokens
- mapping(address => uint256[]) internal _userBalances;
-
- // Mapping from token ID to BorrowTerminationInfo
- mapping(uint256 => BorrowTerminationInfo) internal _borrowTerminations;
-
- /**
- * @dev Initializes the contract by setting a name and a symbol to the token collection.
- */
- constructor(string memory name_, string memory symbol_)
- ERC721(name_, symbol_)
- {}
-
- /**
- * @dev See {IERC5501-setUser}.
- */
- function setUser(
- uint256 tokenId,
- address user,
- uint64 expires,
- bool isBorrowed
- ) public virtual override {
- // Balance extension
- flushExpired(user);
-
- require(
- _isApprovedOrOwner(msg.sender, tokenId),
- "ERC5501: set user caller is not token owner or approved"
- );
- require(user != address(0), "ERC5501: set user to zero address");
-
- UserInfo storage info = _users[tokenId];
- require(
- !info.isBorrowed || info.expires < block.timestamp,
- "ERC5501: token is borrowed"
- );
- info.user = user;
- info.expires = expires;
- info.isBorrowed = isBorrowed;
- emit UpdateUser(tokenId, user, expires, isBorrowed);
-
- // Balance extension
- _userBalances[user].push(tokenId);
- // Terminable extension
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- }
-
- /**
- * @dev See {IERC5501-userOf}.
- */
- function userOf(uint256 tokenId)
- public
- view
- virtual
- override
- returns (address)
- {
- require(
- uint256(_users[tokenId].expires) >= block.timestamp,
- "ERC5501: user does not exist for this token"
- );
- return _users[tokenId].user;
- }
-
- /**
- * @dev See {IERC5501-userBalanceOf}.
- */
- function userBalanceOf(address user)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(
- user != address(0),
- "ERC5501Balance: address zero is not a valid owner"
- );
- uint256 balance;
- uint256[] memory candidates = _userBalances[user];
- unchecked {
- for (uint256 i; i < candidates.length; ++i) {
- if (
- _users[candidates[i]].expires >= block.timestamp &&
- _users[candidates[i]].user == user
- ) {
- ++balance;
- }
- }
- }
- return balance;
- }
-
- /**
- * @dev See {IERC5501-tokenOfUserByIndex}.
- */
- function tokenOfUserByIndex(address user, uint256 index)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(
- user != address(0),
- "ERC5501Enumerable: address zero is not a valid owner"
- );
- uint256[] memory balance = _userBalances[user];
- require(
- balance.length > 0 && index < balance.length,
- "ERC5501Enumerable: owner index out of bounds"
- );
- uint256 counter;
- unchecked {
- for (uint256 i; i < balance.length; ++i) {
- if (
- _users[balance[i]].expires >= block.timestamp &&
- _users[balance[i]].user == user
- ) {
- if (counter == index) {
- return balance[i];
- }
- ++counter;
- }
- }
- }
- revert("ERC5501Enumerable: owner index out of bounds");
- }
-
- /**
- * @dev See {IERC5501-userExpires}.
- */
- function userExpires(uint256 tokenId)
- public
- view
- virtual
- override
- returns (uint64)
- {
- return _users[tokenId].expires;
- }
-
- /**
- * @dev See {IERC5501-isBorrowed}.
- */
- function userIsBorrowed(uint256 tokenId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return _users[tokenId].isBorrowed;
- }
-
- /**
- * @dev See {IERC5501Terminable-getBorrowTermination}.
- */
- function getBorrowTermination(uint256 tokenId)
- public
- view
- virtual
- override
- returns (bool, bool)
- {
- return (
- _borrowTerminations[tokenId].lenderAgreement,
- _borrowTerminations[tokenId].borrowerAgreement
- );
- }
-
- /**
- * @dev See {IERC5501Terminable-setBorrowTermination}.
- */
- function setBorrowTermination(uint256 tokenId) public virtual override {
- UserInfo storage userInfo = _users[tokenId];
- require(
- userInfo.expires >= block.timestamp && userInfo.isBorrowed,
- "ERC5501Terminable: borrow not active"
- );
-
- BorrowTerminationInfo storage terminationInfo = _borrowTerminations[
- tokenId
- ];
- if (ownerOf(tokenId) == msg.sender) {
- terminationInfo.lenderAgreement = true;
- emit AgreeToTerminateBorrow(tokenId, msg.sender, true);
- }
- if (userInfo.user == msg.sender) {
- terminationInfo.borrowerAgreement = true;
- emit AgreeToTerminateBorrow(tokenId, msg.sender, false);
- }
- }
-
- /**
- * @dev See {IERC5501Terminable-terminateBorrow}.
- */
- function terminateBorrow(uint256 tokenId) public virtual override {
- BorrowTerminationInfo storage info = _borrowTerminations[tokenId];
- require(
- info.lenderAgreement && info.borrowerAgreement,
- "ERC5501Terminable: not agreed"
- );
- _users[tokenId].isBorrowed = false;
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- emit TerminateBorrow(
- tokenId,
- ownerOf(tokenId),
- _users[tokenId].user,
- msg.sender
- );
- }
-
- /**
- * @notice On setUser flush all expired userOf statuses.
- * @dev This function may revert out of gas if user borrows too many tokens at once.
- * There must be a way to prevent such behaviour (such as flushing by parts only).
- * @param user an address to flush
- */
- function flushExpired(address user) internal {
- uint256[] storage candidates = _userBalances[user];
- unchecked {
- for (uint256 i; i < candidates.length; ++i) {
- if (
- _users[candidates[i]].user != user ||
- _users[candidates[i]].expires < block.timestamp
- ) {
- candidates[i] = candidates[candidates.length - 1];
- candidates.pop();
- --i; // test moved element
- }
- }
- }
- }
-
- /**
- * @dev See {EIP-165: Standard Interface Detection}.
- * https://eips.ethereum.org/EIPS/eip-165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5501).interfaceId ||
- interfaceId == type(IERC5501Balance).interfaceId ||
- interfaceId == type(IERC5501Enumerable).interfaceId ||
- interfaceId == type(IERC5501Terminable).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev Hook that is called after any token transfer.
- * If user is set and token is not borrowed, reset user.
- */
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override {
- super._afterTokenTransfer(from, to, tokenId);
- if (
- from != to &&
- !_users[tokenId].isBorrowed &&
- _users[tokenId].user != address(0)
- ) {
- delete _users[tokenId];
- emit UpdateUser(tokenId, address(0), 0, false);
- } else if (
- // Terminable extension
- from != to && _users[tokenId].isBorrowed
- ) {
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- }
- }
-}
diff --git a/assets/eip-5501/contracts/ERC5501Enumerable.sol b/assets/eip-5501/contracts/ERC5501Enumerable.sol
deleted file mode 100644
index 1068cad..0000000
--- a/assets/eip-5501/contracts/ERC5501Enumerable.sol
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC5501Balance.sol";
-import "./IERC5501Enumerable.sol";
-
-/**
- * @dev Implementation of Enumerable extension of https://eips.ethereum.org/EIPS/eip-5501 with OpenZeppelin ERC721 version.
- */
-contract ERC5501Enumerable is IERC5501Enumerable, ERC5501Balance {
- /**
- * @dev Initializes the contract by setting a name and a symbol to the token collection.
- */
- constructor(string memory name_, string memory symbol_)
- ERC5501Balance(name_, symbol_)
- {}
-
- /**
- * @dev See {IERC5501-tokenOfUserByIndex}.
- */
- function tokenOfUserByIndex(address user, uint256 index)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(
- user != address(0),
- "ERC5501Enumerable: address zero is not a valid owner"
- );
- uint256[] memory balance = _userBalances[user];
- require(
- balance.length > 0 && index < balance.length,
- "ERC5501Enumerable: owner index out of bounds"
- );
- uint256 counter;
- unchecked {
- for (uint256 i; i < balance.length; ++i) {
- if (
- _users[balance[i]].expires >= block.timestamp &&
- _users[balance[i]].user == user
- ) {
- if (counter == index) {
- return balance[i];
- }
- ++counter;
- }
- }
- }
- revert("ERC5501Enumerable: owner index out of bounds");
- }
-
- /**
- * @dev See {EIP-165: Standard Interface Detection}.
- * https://eips.ethereum.org/EIPS/eip-165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5501Enumerable).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-}
diff --git a/assets/eip-5501/contracts/ERC5501Terminable.sol b/assets/eip-5501/contracts/ERC5501Terminable.sol
deleted file mode 100644
index 938ef78..0000000
--- a/assets/eip-5501/contracts/ERC5501Terminable.sol
+++ /dev/null
@@ -1,136 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "./ERC5501.sol";
-import "./IERC5501Terminable.sol";
-
-/**
- * @dev Implementation of Terminable extension of https://eips.ethereum.org/EIPS/eip-5501 with OpenZeppelin ERC721 version.
- */
-contract ERC5501Terminable is IERC5501Terminable, ERC5501 {
- /**
- * @dev Structure to hold agreements from both parties to terminate a borrow.
- * @notice If both parties agree, it is possible to modify UserInfo even before it expires.
- * In such case, isBorrowed status is reverted to false.
- */
- struct BorrowTerminationInfo {
- bool lenderAgreement;
- bool borrowerAgreement;
- }
-
- // Mapping from token ID to BorrowTerminationInfo
- mapping(uint256 => BorrowTerminationInfo) internal _borrowTerminations;
-
- /**
- * @dev Initializes the contract by setting a name and a symbol to the token collection.
- */
- constructor(string memory name_, string memory symbol_)
- ERC5501(name_, symbol_)
- {}
-
- /**
- * @dev See {IERC5501-setUser}.
- */
- function setUser(
- uint256 tokenId,
- address user,
- uint64 expires,
- bool isBorrowed
- ) public virtual override {
- super.setUser(tokenId, user, expires, isBorrowed);
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- }
-
- /**
- * @dev See {IERC5501Terminable-setBorrowTermination}.
- */
- function setBorrowTermination(uint256 tokenId) public virtual override {
- UserInfo storage userInfo = _users[tokenId];
- require(
- userInfo.expires >= block.timestamp && userInfo.isBorrowed,
- "ERC5501Terminable: borrow not active"
- );
-
- BorrowTerminationInfo storage terminationInfo = _borrowTerminations[
- tokenId
- ];
- if (ownerOf(tokenId) == msg.sender) {
- terminationInfo.lenderAgreement = true;
- emit AgreeToTerminateBorrow(tokenId, msg.sender, true);
- }
- if (userInfo.user == msg.sender) {
- terminationInfo.borrowerAgreement = true;
- emit AgreeToTerminateBorrow(tokenId, msg.sender, false);
- }
- }
-
- /**
- * @dev See {IERC5501Terminable-getBorrowTermination}.
- */
- function getBorrowTermination(uint256 tokenId)
- public
- view
- virtual
- override
- returns (bool, bool)
- {
- return (
- _borrowTerminations[tokenId].lenderAgreement,
- _borrowTerminations[tokenId].borrowerAgreement
- );
- }
-
- /**
- * @dev See {IERC5501Terminable-terminateBorrow}.
- */
- function terminateBorrow(uint256 tokenId) public virtual override {
- BorrowTerminationInfo storage info = _borrowTerminations[tokenId];
- require(
- info.lenderAgreement && info.borrowerAgreement,
- "ERC5501Terminable: not agreed"
- );
- _users[tokenId].isBorrowed = false;
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- emit TerminateBorrow(
- tokenId,
- ownerOf(tokenId),
- _users[tokenId].user,
- msg.sender
- );
- }
-
- /**
- * @dev See {EIP-165: Standard Interface Detection}.
- * https://eips.ethereum.org/EIPS/eip-165
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override
- returns (bool)
- {
- return
- interfaceId == type(IERC5501Terminable).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev Hook that is called after any token transfer.
- * If user is set and token is borrowed, reset termination agreements.
- */
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override {
- super._afterTokenTransfer(from, to, tokenId);
- if (from != to && _users[tokenId].isBorrowed) {
- delete _borrowTerminations[tokenId];
- emit ResetTerminationAgreements(tokenId);
- }
- }
-}
diff --git a/assets/eip-5501/contracts/IERC5501.sol b/assets/eip-5501/contracts/IERC5501.sol
deleted file mode 100644
index 37626bd..0000000
--- a/assets/eip-5501/contracts/IERC5501.sol
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/**
- * @title IERC5501: Rental & Delegation NFT - EIP-721 Extension
- * @dev See https://eips.ethereum.org/EIPS/eip-5501
- * @notice the EIP-165 identifier for this interface is 0xf808ec37.
- */
-interface IERC5501 /* is IERC721 */ {
- /**
- * @dev Emitted when the user of an NFT is modified.
- */
- event UpdateUser(uint256 indexed _tokenId, address indexed _user, uint64 _expires, bool _isBorrowed);
-
- /**
- * @notice Set the user info of an NFT.
- * @dev User address cannot be zero address.
- * Only approved operator or NFT owner can set the user.
- * If NFT is borrowed, the user info cannot be changed until user status expires.
- * @param _tokenId uint256 ID of the token to set user info for
- * @param _user address of the new user
- * @param _expires Unix timestamp when user info expires
- * @param _isBorrowed flag whether or not the NFT is borrowed
- */
- function setUser(uint256 _tokenId, address _user, uint64 _expires, bool _isBorrowed) external;
-
- /**
- * @notice Get the user address of an NFT.
- * @dev Reverts if user is not set.
- * @param _tokenId uint256 ID of the token to get the user address for
- * @return address user address for this NFT
- */
- function userOf(uint256 _tokenId) external view returns (address);
-
- /**
- * @notice Get the user expires of an NFT.
- * @param _tokenId uint256 ID of the token to get the user expires for
- * @return uint64 user expires for this NFT
- */
- function userExpires(uint256 _tokenId) external view returns (uint64);
-
- /**
- * @notice Get the user isBorrowed of an NFT.
- * @param _tokenId uint256 ID of the token to get the user isBorrowed for
- * @return bool user isBorrowed for this NFT
- */
- function userIsBorrowed(uint256 _tokenId) external view returns (bool);
-}
diff --git a/assets/eip-5501/contracts/IERC5501Balance.sol b/assets/eip-5501/contracts/IERC5501Balance.sol
deleted file mode 100644
index fa32ec8..0000000
--- a/assets/eip-5501/contracts/IERC5501Balance.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/**
- * @title IERC5501Balance
- * @dev See https://eips.ethereum.org/EIPS/eip-5501
- * Extension for ERC5501 which adds userBalanceOf to query how many tokens address is userOf.
- * @notice the EIP-165 identifier for this interface is 0x0cb22289.
- */
-interface IERC5501Balance /* is IERC5501 */{
- /**
- * @notice Count of all NFTs assigned to a user.
- * @dev Reverts if user is zero address.
- * @param _user an address for which to query the balance
- * @return uint256 the number of NFTs the user has
- */
- function userBalanceOf(address _user) external view returns (uint256);
-}
diff --git a/assets/eip-5501/contracts/IERC5501Enumerable.sol b/assets/eip-5501/contracts/IERC5501Enumerable.sol
deleted file mode 100644
index 8780007..0000000
--- a/assets/eip-5501/contracts/IERC5501Enumerable.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/**
- * @title IERC5501Enumerable
- * @dev See https://eips.ethereum.org/EIPS/eip-5501
- * This extension for ERC5501 adds the option to iterate over user tokens.
- * @notice the EIP-165 identifier for this interface is 0x1d350ef8.
- */
-interface IERC5501Enumerable /* is IERC5501Balance, IERC5501 */ {
- /**
- * @notice Enumerate NFTs assigned to a user.
- * @dev Reverts if user is zero address or _index >= userBalanceOf(_owner).
- * @param _user an address to iterate over its tokens
- * @return uint256 the token ID for given index assigned to _user
- */
- function tokenOfUserByIndex(address _user, uint256 _index) external view returns (uint256);
-}
diff --git a/assets/eip-5501/contracts/IERC5501Terminable.sol b/assets/eip-5501/contracts/IERC5501Terminable.sol
deleted file mode 100644
index 6f74bb3..0000000
--- a/assets/eip-5501/contracts/IERC5501Terminable.sol
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-/**
- * @title IERC5501Terminable
- * @dev See https://eips.ethereum.org/EIPS/eip-5501
- * This extension for ERC5501 adds the option to terminate borrowing if both parties agree.
- * @notice the EIP-165 identifier for this interface is 0x6a26417e.
- */
-interface IERC5501Terminable /* is IERC5501 */ {
- /**
- * @dev Emitted when one party from borrowing contract approves termination of agreement.
- * @param _isLender true for lender, false for borrower
- */
- event AgreeToTerminateBorrow(uint256 indexed _tokenId, address indexed _party, bool _isLender);
-
- /**
- * @dev Emitted when agreements to terminate borrow are reset.
- */
- event ResetTerminationAgreements(uint256 indexed _tokenId);
-
- /**
- * @dev Emitted when borrow of token ID is terminated.
- */
- event TerminateBorrow(uint256 indexed _tokenId, address indexed _lender, address indexed _borrower, address _caller);
-
- /**
- * @notice Agree to terminate a borrowing.
- * @dev Lender must be ownerOf token ID. Borrower must be userOf token ID.
- * If lender and borrower are the same, set termination agreement for both at once.
- * @param _tokenId uint256 ID of the token to set termination info for
- */
- function setBorrowTermination(uint256 _tokenId) external;
-
- /**
- * @notice Get if it is possible to terminate a borrow agreement.
- * @param _tokenId uint256 ID of the token to get termination info for
- * @return bool, bool first indicates lender agrees, second indicates borrower agrees
- */
- function getBorrowTermination(uint256 _tokenId) external view returns (bool, bool);
-
- /**
- * @notice Terminate a borrow if both parties agreed.
- * @dev Both parties must have agreed, otherwise revert.
- * @param _tokenId uint256 ID of the token to terminate borrow of
- */
- function terminateBorrow(uint256 _tokenId) external;
-}
diff --git a/assets/eip-5501/contracts/test/ERC5501BalanceTestCollection.sol b/assets/eip-5501/contracts/test/ERC5501BalanceTestCollection.sol
deleted file mode 100644
index 38057df..0000000
--- a/assets/eip-5501/contracts/test/ERC5501BalanceTestCollection.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5501Balance.sol";
-
-contract ERC5501BalanceTestCollection is ERC5501Balance {
-
- constructor(string memory name_, string memory symbol_) ERC5501Balance(name_,symbol_) {}
-
- function getUserBalances(address user) external view returns (uint256[] memory) {
- return _userBalances[user];
- }
-
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5501/contracts/test/ERC5501CombinedCollection.sol b/assets/eip-5501/contracts/test/ERC5501CombinedCollection.sol
deleted file mode 100644
index 2a2c346..0000000
--- a/assets/eip-5501/contracts/test/ERC5501CombinedCollection.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5501Combined.sol";
-
-contract ERC5501CombinedTestCollection is ERC5501Combined {
-
- constructor(string memory name_, string memory symbol_) ERC5501Combined(name_,symbol_) {}
-
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5501/contracts/test/ERC5501EnumerableTestCollection.sol b/assets/eip-5501/contracts/test/ERC5501EnumerableTestCollection.sol
deleted file mode 100644
index eed0b4b..0000000
--- a/assets/eip-5501/contracts/test/ERC5501EnumerableTestCollection.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5501Enumerable.sol";
-
-contract ERC5501EnumerableTestCollection is ERC5501Enumerable {
-
- constructor(string memory name_, string memory symbol_) ERC5501Enumerable(name_,symbol_) {}
-
- function getUserBalances(address user) external view returns (uint256[] memory) {
- return _userBalances[user];
- }
-
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5501/contracts/test/ERC5501TerminableTestCollection.sol b/assets/eip-5501/contracts/test/ERC5501TerminableTestCollection.sol
deleted file mode 100644
index 1ba6f8e..0000000
--- a/assets/eip-5501/contracts/test/ERC5501TerminableTestCollection.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5501Terminable.sol";
-
-contract ERC5501TerminableTestCollection is ERC5501Terminable {
-
- constructor(string memory name_, string memory symbol_) ERC5501Terminable(name_,symbol_) {}
-
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5501/contracts/test/ERC5501TestCollection.sol b/assets/eip-5501/contracts/test/ERC5501TestCollection.sol
deleted file mode 100644
index 67429ad..0000000
--- a/assets/eip-5501/contracts/test/ERC5501TestCollection.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "../ERC5501.sol";
-
-contract ERC5501TestCollection is ERC5501 {
-
- constructor(string memory name_, string memory symbol_) ERC5501(name_,symbol_) {}
-
- function mint(address to, uint256 tokenId) public {
- _mint(to, tokenId);
- }
-}
diff --git a/assets/eip-5501/test/ERC5501BalanceTest.ts b/assets/eip-5501/test/ERC5501BalanceTest.ts
deleted file mode 100644
index a936ca0..0000000
--- a/assets/eip-5501/test/ERC5501BalanceTest.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { BigNumber } from "ethers";
-
-describe("ERC5501BalanceTest", function () {
- async function initialize() {
- // 365 * 24 * 60 * 60
- const fastForwardYear = 31536000;
- // Fri Jan 01 2021 00:00:00 GMT+0000
- const expired = 1609459200;
-
- const expires = (await time.latest()) + fastForwardYear - 1;
-
- const [owner, delegatee] = await ethers.getSigners();
-
- const contractFactory = await ethers.getContractFactory(
- "ERC5501BalanceTestCollection"
- );
- const contract = await contractFactory.deploy("Test Collection", "TEST");
-
- await contract.mint(owner.address, 1);
- await contract.mint(owner.address, 2);
- await contract.mint(owner.address, 3);
- await contract.mint(owner.address, 4);
- await contract.mint(owner.address, 5);
- await contract.mint(owner.address, 6);
- await contract.mint(owner.address, 7);
-
- return { contract, owner, delegatee, expires, expired, fastForwardYear };
- }
-
- it("Returns correct balance of user", async function () {
- const { contract, owner, delegatee, expires, expired, fastForwardYear } =
- await loadFixture(initialize);
-
- await contract.setUser(1, delegatee.address, expires, false);
- await contract.setUser(2, delegatee.address, expires, false);
- await contract.setUser(3, delegatee.address, expires, false);
- await contract.setUser(4, delegatee.address, expired, false);
- await contract.setUser(5, delegatee.address, expired, false);
- await contract.setUser(6, delegatee.address, expired, false);
- await contract.setUser(7, delegatee.address, expired, false);
-
- // flush function is called for user parameter - meaning flush does not happen for delegatee if user parameter is different address
- await contract.setUser(2, owner.address, expires, false);
- // delegatee is user of 1, 3
- // delegatee balances array is 1, 2, 3, 7
-
- expect(await contract.userBalanceOf(delegatee.address)).to.equal(2);
- expect(await contract.getUserBalances(delegatee.address)).to.deep.equal([
- BigNumber.from("1"),
- BigNumber.from("2"),
- BigNumber.from("3"),
- BigNumber.from("7"),
- ]);
-
- await time.increaseTo((await time.latest()) + fastForwardYear);
- await contract.setUser(
- 1,
- delegatee.address,
- expires + fastForwardYear,
- false
- );
-
- expect(await contract.userBalanceOf(delegatee.address)).to.equal(1);
- expect(await contract.getUserBalances(delegatee.address)).to.deep.equal([
- BigNumber.from("1"),
- ]);
-
- await time.increaseTo((await time.latest()) + fastForwardYear);
- expect(await contract.userBalanceOf(delegatee.address)).to.equal(0);
- });
-
- it("Revert user balance query for zero address", async function () {
- const { contract } = await loadFixture(initialize);
-
- await expect(
- contract.userBalanceOf(ethers.constants.AddressZero)
- ).to.be.revertedWith("ERC5501Balance: address zero is not a valid owner");
- });
-
- it("Supports interface", async function () {
- const { contract } = await loadFixture(initialize);
-
- expect(await contract.supportsInterface("0x0cb22289")).to.equal(true);
- });
-});
diff --git a/assets/eip-5501/test/ERC5501CombinedTest.ts b/assets/eip-5501/test/ERC5501CombinedTest.ts
deleted file mode 100644
index da8bb8d..0000000
--- a/assets/eip-5501/test/ERC5501CombinedTest.ts
+++ /dev/null
@@ -1,106 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { BigNumber } from "ethers";
-
-describe("ERC5501CombinedTest", function () {
- async function initialize() {
- // 7 * 24 * 60 * 60
- const week = 604800;
-
- const uint64MaxValue = BigNumber.from("18446744073709551615");
-
- const [owner, delegatee, borrower, rentalContractMock] =
- await ethers.getSigners();
-
- const contractFactory = await ethers.getContractFactory(
- "ERC5501CombinedTestCollection"
- );
- const contract = await contractFactory.deploy("Test Collection", "TEST");
-
- await contract.mint(owner.address, 1);
-
- return {
- contract,
- owner,
- delegatee,
- borrower,
- rentalContractMock,
- week,
- uint64MaxValue,
- };
- }
-
- it("Scenario", async function () {
- const {
- contract,
- owner,
- delegatee,
- borrower,
- rentalContractMock,
- week,
- uint64MaxValue,
- } = await loadFixture(initialize);
-
- // owner delegates NFT to hot wallet for security
- await expect(contract.setUser(1, delegatee.address, uint64MaxValue, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, uint64MaxValue, false);
- expect(await contract.userBalanceOf(delegatee.address)).to.equal(1);
- expect(await contract.userOf(1)).to.equal(delegatee.address);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 0)).to.equal(1);
- expect(await contract.userExpires(1)).to.equal(uint64MaxValue);
- expect(await contract.userIsBorrowed(1)).to.equal(false);
-
- // owner then decides to lend the NFT for one week
- await contract.setApprovalForAll(rentalContractMock.address, true);
- const oneWeekLater = (await time.latest()) + week;
- await expect(
- contract
- .connect(rentalContractMock)
- .setUser(1, borrower.address, oneWeekLater, true)
- )
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, oneWeekLater, true);
- expect(await contract.userBalanceOf(delegatee.address)).to.equal(0);
- expect(await contract.userBalanceOf(borrower.address)).to.equal(1);
- expect(await contract.tokenOfUserByIndex(borrower.address, 0)).to.equal(1);
- expect(await contract.userOf(1)).to.equal(borrower.address);
- expect(await contract.userExpires(1)).to.equal(oneWeekLater);
- expect(await contract.userIsBorrowed(1)).to.equal(true);
-
- // borrow expires
- await time.increaseTo((await time.latest()) + oneWeekLater + 1);
-
- // owner decides to lend the NFT again
- // this time, they accidentally set wrong time
- // the owner and borrower agree to terminate the loan under certain conditions
- await expect(
- contract
- .connect(rentalContractMock)
- .setUser(1, borrower.address, uint64MaxValue, true)
- )
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, uint64MaxValue, true);
- await expect(contract.connect(borrower).setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, borrower.address, false);
- await expect(contract.setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, true);
- await expect(contract.terminateBorrow(1))
- .to.emit(contract, "TerminateBorrow")
- .withArgs(1, owner.address, borrower.address, owner.address)
- .to.emit(contract, "ResetTerminationAgreements")
- .withArgs(1);
- });
-
- it("Supports interface", async function () {
- const { contract } = await loadFixture(initialize);
-
- expect(await contract.supportsInterface("0xf808ec37")).to.equal(true);
- expect(await contract.supportsInterface("0x0cb22289")).to.equal(true);
- expect(await contract.supportsInterface("0x1d350ef8")).to.equal(true);
- expect(await contract.supportsInterface("0x6a26417e")).to.equal(true);
- });
-});
diff --git a/assets/eip-5501/test/ERC5501EnumerableTest.ts b/assets/eip-5501/test/ERC5501EnumerableTest.ts
deleted file mode 100644
index 9717910..0000000
--- a/assets/eip-5501/test/ERC5501EnumerableTest.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-
-describe("ERC5501EnumerableTest", function () {
- async function initialize() {
- // 365 * 24 * 60 * 60
- const fastForwardYear = 31536000;
- // allows to set multiple tokens which will expire after fastForwardYear
- const expired = (await time.latest()) + fastForwardYear - 1;
-
- const expires = (await time.latest()) + fastForwardYear + fastForwardYear;
-
- const [owner, delegatee] = await ethers.getSigners();
-
- const contractFactory = await ethers.getContractFactory(
- "ERC5501EnumerableTestCollection"
- );
- const contract = await contractFactory.deploy("Test Collection", "TEST");
-
- await contract.mint(owner.address, 1);
- await contract.mint(owner.address, 2);
- await contract.mint(owner.address, 3);
- await contract.mint(owner.address, 4);
- await contract.mint(owner.address, 5);
- await contract.mint(owner.address, 6);
- await contract.mint(owner.address, 7);
-
- return { contract, owner, delegatee, expires, expired, fastForwardYear };
- }
-
- it("Return correct user tokens by index", async function () {
- const { contract, owner, delegatee, expires, expired, fastForwardYear } =
- await loadFixture(initialize);
-
- await contract.setUser(1, delegatee.address, expires, false);
- await contract.setUser(2, delegatee.address, expired, false);
- await contract.setUser(3, delegatee.address, expires, false);
- await contract.setUser(4, delegatee.address, expired, false);
- await contract.setUser(5, delegatee.address, expires, false);
- await contract.setUser(6, delegatee.address, expired, false);
- await contract.setUser(7, delegatee.address, expires, false);
-
- expect(await contract.tokenOfUserByIndex(delegatee.address, 0)).to.equal(1);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 1)).to.equal(2);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 2)).to.equal(3);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 3)).to.equal(4);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 4)).to.equal(5);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 5)).to.equal(6);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 6)).to.equal(7);
-
- // fast forward one year, token 2, 4, 6 expired for user
- // current balance: 1, 3, 5, 7
- await time.increaseTo((await time.latest()) + fastForwardYear);
-
- expect(await contract.tokenOfUserByIndex(delegatee.address, 0)).to.equal(1);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 1)).to.equal(3);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 2)).to.equal(5);
- expect(await contract.tokenOfUserByIndex(delegatee.address, 3)).to.equal(7);
- await expect(
- contract.tokenOfUserByIndex(delegatee.address, 4)
- ).to.be.revertedWith("ERC5501Enumerable: owner index out of bounds");
- });
-
- it("Revert user token id by index query for zero address", async function () {
- const { contract } = await loadFixture(initialize);
-
- await expect(
- contract.tokenOfUserByIndex(ethers.constants.AddressZero, 0)
- ).to.be.revertedWith("ERC5501Enumerable: address zero is not a valid owner");
- });
-
- it("Revert user token id by index query for out of bounds index", async function () {
- const { contract, delegatee } = await loadFixture(initialize);
-
- await expect(
- contract.tokenOfUserByIndex(delegatee.address, 0)
- ).to.be.revertedWith("ERC5501Enumerable: owner index out of bounds");
- });
-
- it("Supports interface", async function () {
- const { contract } = await loadFixture(initialize);
-
- expect(await contract.supportsInterface("0x1d350ef8")).to.equal(true);
- });
-});
diff --git a/assets/eip-5501/test/ERC5501TerminableTest.ts b/assets/eip-5501/test/ERC5501TerminableTest.ts
deleted file mode 100644
index c3da145..0000000
--- a/assets/eip-5501/test/ERC5501TerminableTest.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-import { BigNumber } from "ethers";
-
-describe("ERC5501TerminableTest", function () {
- async function initialize() {
- // 365 * 24 * 60 * 60
- const fastForwardYear = 31536000;
-
- const expires = (await time.latest()) + fastForwardYear - 1;
-
- const uint64MaxValue = BigNumber.from("18446744073709551615");
-
- const [owner, delegatee, borrower] = await ethers.getSigners();
-
- const contractFactory = await ethers.getContractFactory(
- "ERC5501TerminableTestCollection"
- );
- const contract = await contractFactory.deploy("Test Collection", "TEST");
-
- await contract.mint(owner.address, 1);
-
- return {
- contract,
- owner,
- delegatee,
- borrower,
- uint64MaxValue,
- expires,
- fastForwardYear,
- };
- }
-
- it("Cannot terminate borrow without approval of both parties", async function () {
- const { contract, borrower, uint64MaxValue } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, borrower.address, uint64MaxValue, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, uint64MaxValue, true);
- await expect(contract.terminateBorrow(1)).to.be.revertedWith(
- "ERC5501Terminable: not agreed"
- );
- });
-
- it("Cannot set borrow termination if borrow is not active", async function () {
- const { contract, delegatee, uint64MaxValue } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, delegatee.address, uint64MaxValue, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, uint64MaxValue, false);
- await expect(contract.setBorrowTermination(1)).to.be.revertedWith(
- "ERC5501Terminable: borrow not active"
- );
- });
-
- it("Can reset borrow if owner mistakenly borrowed token to own wallet and set a long duration", async function () {
- const { contract, owner, uint64MaxValue } = await loadFixture(initialize);
-
- await expect(contract.setUser(1, owner.address, uint64MaxValue, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, owner.address, uint64MaxValue, true);
-
- await expect(contract.setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, true)
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, false);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- true,
- true,
- ]);
-
- await expect(contract.terminateBorrow(1))
- .to.emit(contract, "TerminateBorrow")
- .withArgs(1, owner.address, owner.address, owner.address)
- .to.emit(contract, "ResetTerminationAgreements")
- .withArgs(1);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- false,
- false,
- ]);
- expect(await contract.userIsBorrowed(1)).to.equal(false);
- });
-
- it("Can reset borrow and set a new user if both parties agree", async function () {
- const { contract, owner, delegatee, borrower, uint64MaxValue } =
- await loadFixture(initialize);
-
- await expect(contract.setUser(1, borrower.address, uint64MaxValue, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, uint64MaxValue, true);
-
- await expect(contract.setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, true);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- true,
- false,
- ]);
-
- await expect(contract.connect(borrower).setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, borrower.address, false);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- true,
- true,
- ]);
-
- await expect(contract.terminateBorrow(1))
- .to.emit(contract, "TerminateBorrow")
- .withArgs(1, owner.address, borrower.address, owner.address)
- .to.emit(contract, "ResetTerminationAgreements")
- .withArgs(1);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- false,
- false,
- ]);
- expect(await contract.userIsBorrowed(1)).to.equal(false);
-
- await expect(contract.setUser(1, delegatee.address, 0, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, 0, false);
- });
-
- it("Agreed borrow terminations must be reset if userOf is changed", async function () {
- const { contract, owner, delegatee, borrower, expires, fastForwardYear } =
- await loadFixture(initialize);
-
- await expect(contract.setUser(1, borrower.address, expires, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
-
- await expect(contract.setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, true);
- await expect(contract.connect(borrower).setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, borrower.address, false);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- true,
- true,
- ]);
-
- await time.increaseTo((await time.latest()) + fastForwardYear);
-
- await expect(contract.setUser(1, delegatee.address, 0, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, 0, false)
- .to.emit(contract, "ResetTerminationAgreements")
- .withArgs(1);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- false,
- false,
- ]);
- });
-
- it("Reset termination agreements if token is transferred", async function () {
- const { contract, owner, delegatee, borrower, expires } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, borrower.address, expires, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
-
- await expect(contract.setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, owner.address, true);
- await expect(contract.connect(borrower).setBorrowTermination(1))
- .to.emit(contract, "AgreeToTerminateBorrow")
- .withArgs(1, borrower.address, false);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- true,
- true,
- ]);
-
- await expect(
- contract["safeTransferFrom(address,address,uint256)"](
- owner.address,
- delegatee.address,
- 1
- )
- )
- .to.emit(contract, "ResetTerminationAgreements")
- .withArgs(1);
-
- expect(await contract.getBorrowTermination(1)).to.have.ordered.members([
- false,
- false,
- ]);
- });
-
- it("Supports interface", async function () {
- const { contract } = await loadFixture(initialize);
-
- expect(await contract.supportsInterface("0x6a26417e")).to.equal(true);
- });
-});
diff --git a/assets/eip-5501/test/ERC5501Test.ts b/assets/eip-5501/test/ERC5501Test.ts
deleted file mode 100644
index 0be415a..0000000
--- a/assets/eip-5501/test/ERC5501Test.ts
+++ /dev/null
@@ -1,169 +0,0 @@
-import { time, loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { expect } from "chai";
-import { ethers } from "hardhat";
-
-describe("ERC5501Test", function () {
- async function initialize() {
- // 365 * 24 * 60 * 60
- const fastForwardYear = 31536000;
-
- const expires = (await time.latest()) + fastForwardYear - 1;
-
- const [owner, delegatee, borrower, rentalContractMock] =
- await ethers.getSigners();
-
- const contractFactory = await ethers.getContractFactory(
- "ERC5501TestCollection"
- );
- const contract = await contractFactory.deploy("Test Collection", "TEST");
-
- await contract.mint(owner.address, 1);
-
- return {
- contract,
- owner,
- delegatee,
- borrower,
- rentalContractMock,
- expires,
- fastForwardYear,
- };
- }
-
- it("Operator is not owner or approved", async function () {
- const { contract, borrower } = await loadFixture(initialize);
-
- await expect(
- contract.connect(borrower).setUser(1, borrower.address, 0, false)
- ).to.be.revertedWith(
- "ERC5501: set user caller is not token owner or approved"
- );
- });
-
- it("User cannot be zero address", async function () {
- const { contract } = await loadFixture(initialize);
-
- await expect(
- contract.setUser(1, ethers.constants.AddressZero, 0, false)
- ).to.be.revertedWith("ERC5501: set user to zero address");
- });
-
- it("Revert userOf if not set or expired", async function () {
- const { contract } = await loadFixture(initialize);
-
- await expect(contract.userOf(1)).to.be.revertedWith(
- "ERC5501: user does not exist for this token"
- );
- });
-
- it("Cannot set user if NFT is borrowed", async function () {
- const { contract, delegatee, borrower, rentalContractMock, expires } =
- await loadFixture(initialize);
-
- await contract.setApprovalForAll(rentalContractMock.address, true);
- await expect(
- contract
- .connect(rentalContractMock)
- .setUser(1, borrower.address, expires, true)
- )
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
- await expect(
- contract.setUser(1, delegatee.address, 0, false)
- ).to.be.revertedWith("ERC5501: token is borrowed");
- });
-
- it("Can delegate and redelegate user", async function () {
- const { contract, owner, delegatee, expires } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, owner.address, expires, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, owner.address, expires, false);
- await expect(contract.setUser(1, delegatee.address, expires, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, expires, false);
- });
-
- it("Can set user after borrow expires", async function () {
- const { contract, delegatee, borrower, expires, fastForwardYear } =
- await loadFixture(initialize);
-
- await expect(contract.setUser(1, borrower.address, expires, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
- await time.increaseTo((await time.latest()) + fastForwardYear);
- await expect(contract.setUser(1, delegatee.address, 0, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, 0, false);
- });
-
- it("User is reset if NFT is not borrowed and transferred", async function () {
- const { contract, owner, delegatee, expires } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, delegatee.address, expires, false))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, delegatee.address, expires, false);
- await expect(
- contract["safeTransferFrom(address,address,uint256)"](
- owner.address,
- delegatee.address,
- 1
- )
- )
- .to.emit(contract, "UpdateUser")
- .withArgs(1, ethers.constants.AddressZero, 0, false);
-
- await expect(contract.userOf(1)).to.be.revertedWith(
- "ERC5501: user does not exist for this token"
- );
- expect(await contract.userExpires(1)).to.equal(0);
- expect(await contract.userIsBorrowed(1)).to.equal(false);
- });
-
- it("User is not reset if NFT is borrowed and transferred", async function () {
- const { contract, owner, delegatee, borrower, expires } = await loadFixture(
- initialize
- );
-
- await expect(contract.setUser(1, borrower.address, expires, true))
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
- await contract["safeTransferFrom(address,address,uint256)"](
- owner.address,
- delegatee.address,
- 1
- );
-
- expect(await contract.userOf(1)).to.equal(borrower.address);
- expect(await contract.userExpires(1)).to.equal(expires);
- expect(await contract.userIsBorrowed(1)).to.equal(true);
- });
-
- it("Rental contract can set user", async function () {
- const { contract, borrower, rentalContractMock, expires } =
- await loadFixture(initialize);
-
- await contract.setApprovalForAll(rentalContractMock.address, true);
- await expect(
- contract
- .connect(rentalContractMock)
- .setUser(1, borrower.address, expires, true)
- )
- .to.emit(contract, "UpdateUser")
- .withArgs(1, borrower.address, expires, true);
-
- expect(await contract.userOf(1)).to.equal(borrower.address);
- expect(await contract.userExpires(1)).to.equal(expires);
- expect(await contract.userIsBorrowed(1)).to.equal(true);
- });
-
- it("Supports interface", async function () {
- const { contract } = await loadFixture(initialize);
-
- expect(await contract.supportsInterface("0xf808ec37")).to.equal(true);
- });
-});
diff --git a/assets/eip-5516/ERC5516.sol b/assets/eip-5516/ERC5516.sol
deleted file mode 100644
index 8e4a6e4..0000000
--- a/assets/eip-5516/ERC5516.sol
+++ /dev/null
@@ -1,819 +0,0 @@
-//SPDX-License-Identifier: CC0-1.0
-
-/**
- * @notice Reference implementation of the eip-5516 interface.
- * Note: this implementation only allows for each user to own only 1 token type for each `id`.
- * @author Matias Arazi , Lucas Martín Grasso Ramos
- * See https://github.com/ethereum/EIPs/pull/5516
- *
- */
-
-pragma solidity ^0.8.4;
-
-import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-import "@openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol";
-import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-import "@openzeppelin/contracts/utils/Context.sol";
-import "./IERC5516.sol";
-
-contract ERC5516 is Context, ERC165, IERC1155, IERC1155MetadataURI, IERC5516 {
- using Address for address;
-
- // Used for making each token unique, Maintains ID registry and quantity of tokens minted.
- uint256 private nonce;
-
- // Used as the URI for all token types by relying on ID substitution, e.g. https://ipfs.io/ipfs/token.data
- string private _uri;
-
- // Mapping from token ID to account balances
- mapping(address => mapping(uint256 => bool)) private _balances;
-
- // Mapping from address to mapping id bool that states if address has tokens(under id) awaiting to be claimed
- mapping(address => mapping(uint256 => bool)) private _pendings;
-
- // Mapping from account to operator approvals
- mapping(address => mapping(address => bool)) private _operatorApprovals;
-
- // Mapping from ID to minter address.
- mapping(uint256 => address) private _tokenMinters;
-
- // Mapping from ID to URI.
- mapping(uint256 => string) private _tokenURIs;
-
- /**
- * @dev Sets base uri for tokens. Preferably "https://ipfs.io/ipfs/"
- */
- constructor(string memory uri_) {
- _uri = uri_;
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(ERC165, IERC165)
- returns (bool)
- {
- return
- interfaceId == type(IERC1155).interfaceId ||
- interfaceId == type(IERC1155MetadataURI).interfaceId ||
- interfaceId == type(IERC5516).interfaceId ||
- super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev See {IERC1155MetadataURI-uri}.
- */
- function uri(uint256 _id)
- external
- view
- virtual
- override
- returns (string memory)
- {
- return string(abi.encodePacked(_uri, _tokenURIs[_id]));
- }
-
- /**
- * @dev See {IERC1155-balanceOf}.
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- *
- */
- function balanceOf(address account, uint256 id)
- public
- view
- virtual
- override
- returns (uint256)
- {
- require(account != address(0), "EIP5516: Address zero error");
- if (_balances[account][id]) {
- return 1;
- } else {
- return 0;
- }
- }
-
- /**
- * @dev See {IERC1155-balanceOfBatch}.
- *
- * Requirements:
- *
- * - `accounts` and `ids` must have the same length.
- *
- */
- function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
- public
- view
- virtual
- override
- returns (uint256[] memory)
- {
- require(
- accounts.length == ids.length,
- "EIP5516: Array lengths mismatch"
- );
-
- uint256[] memory batchBalances = new uint256[](accounts.length);
-
- for (uint256 i = 0; i < accounts.length; ++i) {
- batchBalances[i] = balanceOf(accounts[i], ids[i]);
- }
-
- return batchBalances;
- }
-
- /**
- * @dev Get tokens owned by a given address
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- *
- */
- function tokensFrom(address account)
- public
- view
- virtual
- override
- returns (uint256[] memory)
- {
- require(account != address(0), "EIP5516: Address zero error");
-
- uint256 _tokenCount = 0;
- for (uint256 i = 1; i <= nonce; ) {
- if (_balances[account][i]) {
- unchecked {
- ++_tokenCount;
- }
- }
- unchecked {
- ++i;
- }
- }
-
- uint256[] memory _ownedTokens = new uint256[](_tokenCount);
-
- for (uint256 i = 1; i <= nonce; ) {
- if (_balances[account][i]) {
- _ownedTokens[--_tokenCount] = i;
- }
- unchecked {
- ++i;
- }
- }
-
- return _ownedTokens;
- }
-
- /**
- * @dev Get tokens marked as _pendings of a given address
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- *
- */
- function pendingFrom(address account)
- public
- view
- virtual
- override
- returns (uint256[] memory)
- {
- require(account != address(0), "EIP5516: Address zero error");
-
- uint256 _tokenCount = 0;
-
- for (uint256 i = 1; i <= nonce; ) {
- if (_pendings[account][i]) {
- ++_tokenCount;
- }
- unchecked {
- ++i;
- }
- }
-
- uint256[] memory _pendingTokens = new uint256[](_tokenCount);
-
- for (uint256 i = 1; i <= nonce; ) {
- if (_pendings[account][i]) {
- _pendingTokens[--_tokenCount] = i;
- }
- unchecked {
- ++i;
- }
- }
-
- return _pendingTokens;
- }
-
- /**
- * @dev See {IERC1155-setApprovalForAll}.
- */
- function setApprovalForAll(address operator, bool approved)
- public
- virtual
- override
- {
- _setApprovalForAll(_msgSender(), operator, approved);
- }
-
- /**
- * @dev See {IERC1155-isApprovedForAll}.
- */
- function isApprovedForAll(address account, address operator)
- public
- view
- virtual
- override
- returns (bool)
- {
- return _operatorApprovals[account][operator];
- }
-
- /**
- * @dev mints(creates) a token
- */
- function _mint(address account, string memory data) internal virtual {
- unchecked {
- ++nonce;
- }
-
- address operator = _msgSender();
- uint256[] memory ids = _asSingletonArray(nonce);
- uint256[] memory amounts = _asSingletonArray(1);
- bytes memory _bData = bytes(data);
-
- _beforeTokenTransfer(
- operator,
- address(0),
- operator,
- ids,
- amounts,
- _bData
- );
- _tokenURIs[nonce] = data;
- _tokenMinters[nonce] = account;
- emit TransferSingle(operator, address(0), operator, nonce, 1);
- _afterTokenTransfer(
- operator,
- address(0),
- operator,
- ids,
- amounts,
- _bData
- );
- }
-
- /**
- * @dev See {IERC1155-safeTransferFrom}.
- *
- * Requirements:
- *
- * - `from` must be the creator(minter) of `id` or must have allowed _msgSender() as an operator.
- *
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) public virtual override {
- require(amount == 1, "EIP5516: Can only transfer one token");
- require(
- _msgSender() == _tokenMinters[id] ||
- isApprovedForAll(_tokenMinters[id], _msgSender()),
- "EIP5516: Unauthorized"
- );
-
- _safeTransferFrom(from, to, id, amount, data);
- }
-
- /**
- * @dev See {eip-5516-batchTransfer}
- *
- * Requirements:
- *
- * - 'from' must be the creator(minter) of `id` or must have allowed _msgSender() as an operator.
- *
- */
- function batchTransfer(
- address from,
- address[] memory to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) external virtual override {
- require(amount == 1, "EIP5516: Can only transfer one token");
- require(
- _msgSender() == _tokenMinters[id] ||
- isApprovedForAll(_tokenMinters[id], _msgSender()),
- "EIP5516: Unauthorized"
- );
-
- _batchTransfer(from, to, id, amount, data);
- }
-
- /**
- * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
- *
- * Emits a {TransferSingle} event.
- *
- * Requirements:
- *
- * - `from` must be the creator(minter) of the token under `id`.
- * - `to` must be non-zero.
- * - `to` must have the token `id` marked as _pendings.
- * - `to` must not own a token type under `id`.
- * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
- * acceptance magic value.
- *
- */
- function _safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) internal virtual {
- require(from != address(0), "EIP5516: Address zero error");
- require(
- _pendings[to][id] == false && _balances[to][id] == false,
- "EIP5516: Already Assignee"
- );
-
- address operator = _msgSender();
-
- uint256[] memory ids = _asSingletonArray(id);
- uint256[] memory amounts = _asSingletonArray(amount);
-
- _beforeTokenTransfer(operator, from, to, ids, amounts, data);
-
- _pendings[to][id] = true;
-
- emit TransferSingle(operator, from, to, id, amount);
- _afterTokenTransfer(operator, from, to, ids, amounts, data);
-
- _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
- }
-
- /**
- * Transfers `id` token from `from` to every address at `to[]`.
- *
- * Requirements:
- * - See {eip-5516-safeMultiTransfer}.
- *
- */
- function _batchTransfer(
- address from,
- address[] memory to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) internal virtual {
- address operator = _msgSender();
-
- _beforeBatchedTokenTransfer(operator, from, to, id, data);
-
- for (uint256 i = 0; i < to.length; ) {
- address _to = to[i];
-
- require(_to != address(0), "EIP5516: Address zero error");
- require(
- _pendings[_to][id] == false && _balances[_to][id] == false,
- "EIP5516: Already Assignee"
- );
-
- _pendings[_to][id] = true;
-
- unchecked {
- ++i;
- }
- }
-
- emit TransferMulti(operator, from, to, amount, id);
-
- _beforeBatchedTokenTransfer(operator, from, to, id, data);
- }
-
- /**
- * @dev See {eip-5516-claimOrReject}
- *
- * If action == true: Claims pending token under `id`.
- * Else, rejects pending token under `id`.
- *
- */
- function claimOrReject(
- address account,
- uint256 id,
- bool action
- ) external virtual override {
- require(_msgSender() == account, "EIP5516: Unauthorized");
-
- _claimOrReject(account, id, action);
- }
-
- /**
- * @dev See {eip-5516-claimOrReject}
- *
- * For each `id` - `action` pair:
- *
- * If action == true: Claims pending token under `id`.
- * Else, rejects pending token under `id`.
- *
- */
- function claimOrRejectBatch(
- address account,
- uint256[] memory ids,
- bool[] memory actions
- ) external virtual override {
- require(
- ids.length == actions.length,
- "EIP5516: Array lengths mismatch"
- );
-
- require(_msgSender() == account, "EIP5516: Unauthorized");
-
- _claimOrRejectBatch(account, ids, actions);
- }
-
- /**
- * @dev Claims or Reject pending token under `_id` from address `_account`.
- *
- * Requirements:
- *
- * - `account` cannot be the zero address.
- * - `account` must have a _pendings token under `id` at the moment of call.
- * - `account` mUST not own a token under `id` at the moment of call.
- *
- * Emits a {TokenClaimed} event.
- *
- */
- function _claimOrReject(
- address account,
- uint256 id,
- bool action
- ) internal virtual {
- require(
- _pendings[account][id] == true && _balances[account][id] == false,
- "EIP5516: Not claimable"
- );
-
- address operator = _msgSender();
-
- bool[] memory actions = new bool[](1);
- actions[0] = action;
- uint256[] memory ids = _asSingletonArray(id);
-
- _beforeTokenClaim(operator, account, actions, ids);
-
- _balances[account][id] = action;
- _pendings[account][id] = false;
-
- delete _pendings[account][id];
-
- emit TokenClaimed(operator, account, actions, ids);
-
- _afterTokenClaim(operator, account, actions, ids);
- }
-
- /**
- * @dev Claims or Reject _pendings `_id` from address `_account`.
- *
- * For each `id`-`action` pair:
- *
- * Requirements:
- * - `account` cannot be the zero address.
- * - `account` must have a pending token under `id` at the moment of call.
- * - `account` must not own a token under `id` at the moment of call.
- *
- * Emits a {TokenClaimed} event.
- *
- */
- function _claimOrRejectBatch(
- address account,
- uint256[] memory ids,
- bool[] memory actions
- ) internal virtual {
- uint256 totalIds = ids.length;
- address operator = _msgSender();
-
- _beforeTokenClaim(operator, account, actions, ids);
-
- for (uint256 i = 0; i < totalIds; ) {
- uint256 id = ids[i];
-
- require(
- _pendings[account][id] == true &&
- _balances[account][id] == false,
- "EIP5516: Not claimable"
- );
-
- _balances[account][id] = actions[i];
- _pendings[account][id] = false;
-
- delete _pendings[account][id];
-
- unchecked {
- ++i;
- }
- }
-
- emit TokenClaimed(operator, account, actions, ids);
-
- _afterTokenClaim(operator, account, actions, ids);
- }
-
- /**
- * @dev Destroys `id` token from `account`
- *
- * Emits a {TransferSingle} event with `to` set to the zero address.
- *
- * Requirements:
- *
- * - `account` must own a token under `id`.
- *
- */
- function _burn(address account, uint256 id) internal virtual {
- require(_balances[account][id] == true, "EIP5516: Unauthorized");
-
- address operator = _msgSender();
- uint256[] memory ids = _asSingletonArray(id);
- uint256[] memory amounts = _asSingletonArray(1);
-
- _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
-
- delete _balances[account][id];
-
- emit TransferSingle(operator, account, address(0), id, 1);
- _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
- }
-
- /**
- * @dev Destroys all tokens under `ids` from `account`
- *
- * Emits a {TransferBatch} event with `to` set to the zero address.
- *
- * Requirements:
- *
- * - `account` must own all tokens under `ids`.
- *
- */
- function _burnBatch(address account, uint256[] memory ids)
- internal
- virtual
- {
- uint256 totalIds = ids.length;
- address operator = _msgSender();
- uint256[] memory amounts = _asSingletonArray(totalIds);
- uint256[] memory values = _asSingletonArray(0);
-
- _beforeTokenTransfer(operator, account, address(0), ids, amounts, "");
-
- for (uint256 i = 0; i < totalIds; ) {
- uint256 id = ids[i];
-
- require(_balances[account][id] == true, "EIP5516: Unauthorized");
-
- delete _balances[account][id];
-
- unchecked {
- ++i;
- }
- }
-
- emit TransferBatch(operator, account, address(0), ids, values);
-
- _afterTokenTransfer(operator, account, address(0), ids, amounts, "");
- }
-
- /**
- * @dev Approve `operator` to operate on all of `owner` tokens
- *
- * Emits a {ApprovalForAll} event.
- *
- */
- function _setApprovalForAll(
- address owner,
- address operator,
- bool approved
- ) internal virtual {
- require(owner != operator, "ERC1155: setting approval status for self");
- _operatorApprovals[owner][operator] = approved;
- emit ApprovalForAll(owner, operator, approved);
- }
-
- /**
- * @dev Hook that is called before any token transfer. This includes minting
- * and burning, as well as batched variants.
- *
- * The same hook is called on both single and batched variants. For single
- * transfers, the length of the `ids` and `amounts` arrays will be 1.
- *
- * Calling conditions (for each `id` and `amount` pair):
- *
- * - `amount` will always be and must be equal to 1.
- * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * of token type `id` will be transferred to `to`.
- * - When `from` is zero, `amount` tokens of token type `id` will be minted
- * for `to`.
- * - When `to` is zero, `amount` of ``from``'s tokens of token type `id`
- * will be burned.
- * - `from` and `to` are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _beforeTokenTransfer(
- address operator,
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) internal virtual {}
-
- /**
- * @dev Hook that is called after any token transfer. This includes minting
- * and burning, as well as batched variants.
- *
- * The same hook is called on both single and batched variants. For single
- * transfers, the length of the `id` and `amount` arrays will be 1.
- *
- * Calling conditions (for each `id` and `amount` pair):
- *
- * - `amount` will always be and must be equal to 1.
- * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * of token type `id` will be transferred to `to`.
- * - When `from` is zero, `amount` tokens of token type `id` will be minted
- * for `to`.
- * - When `to` is zero, `amount` of ``from``'s tokens of token type `id`
- * will be burned.
- * - `from` and `to` are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _afterTokenTransfer(
- address operator,
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) internal virtual {}
-
- /**
- * @dev Hook that is called before any batched token transfer. This includes minting
- * and burning, as well as batched variants.
- *
- * The same hook is called on both single and batched variants. For single
- * transfers, the length of the `id` and `amount` arrays will be 1.
- *
- * Calling conditions (for each `id` and `amount` pair):
- *
- * - `amount` will always be and must be equal to 1.
- * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * of token type `id` will be transferred to `to`.
- * - When `from` is zero, `amount` tokens of token type `id` will be minted
- * for `to`.
- * - When `to` is zero, `amount` of ``from``'s tokens of token type `id`
- * will be burned.
- * - `from` and `to` are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _beforeBatchedTokenTransfer(
- address operator,
- address from,
- address[] memory to,
- uint256 id,
- bytes memory data
- ) internal virtual {}
-
- /**
- * @dev Hook that is called after any batched token transfer. This includes minting
- * and burning, as well as batched variants.
- *
- * The same hook is called on both single and batched variants. For single
- * transfers, the length of the `id` and `amount` arrays will be 1.
- *
- * Calling conditions (for each `id` and `amount` pair):
- *
- * - `amount` will always be and must be equal to 1.
- * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
- * of token type `id` will be transferred to `to`.
- * - When `from` is zero, `amount` tokens of token type `id` will be minted
- * for `to`.
- * - When `to` is zero, `amount` of ``from``'s tokens of token type `id`
- * will be burned.
- * - `from` and `to` are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _afterBatchedTokenTransfer(
- address operator,
- address from,
- address[] memory to,
- uint256 id,
- bytes memory data
- ) internal virtual {}
-
- /**
- * @dev Hook that is called before any token claim.
- +
- * Calling conditions (for each `action` and `id` pair):
- *
- * - A token under `id` must exist.
- * - When `action` is non-zero, a token under `id` will now be claimed and owned by`operator`.
- * - When `action` is false, a token under `id` will now be rejected.
- *
- */
- function _beforeTokenClaim(
- address operator,
- address account,
- bool[] memory actions,
- uint256[] memory ids
- ) internal virtual {}
-
- /**
- * @dev Hook that is called after any token claim.
- +
- * Calling conditions (for each `action` and `id` pair):
- *
- * - A token under `id` must exist.
- * - When `action` is non-zero, a token under `id` is now owned by`operator`.
- * - When `action` is false, a token under `id` was rejected.
- *
- */
- function _afterTokenClaim(
- address operator,
- address account,
- bool[] memory actions,
- uint256[] memory ids
- ) internal virtual {}
-
- function _asSingletonArray(uint256 element)
- private
- pure
- returns (uint256[] memory)
- {
- uint256[] memory array = new uint256[](1);
- array[0] = element;
-
- return array;
- }
-
- /**
- * @dev see {ERC1155-_doSafeTransferAcceptanceCheck, IERC1155Receivable}
- */
- function _doSafeTransferAcceptanceCheck(
- address operator,
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) private {
- if (to.isContract()) {
- try
- IERC1155Receiver(to).onERC1155Received(
- operator,
- from,
- id,
- amount,
- data
- )
- returns (bytes4 response) {
- if (response != IERC1155Receiver.onERC1155Received.selector) {
- revert("ERC1155: ERC1155Receiver rejected tokens");
- }
- } catch Error(string memory reason) {
- revert(reason);
- } catch {
- revert("ERC1155: transfer to non-ERC1155Receiver implementer");
- }
- }
- }
-
- /**
- * @dev Unused/Deprecated function
- * @dev See {IERC1155-safeBatchTransferFrom}.
- */
- function safeBatchTransferFrom(
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) public virtual override {}
-}
diff --git a/assets/eip-5516/IERC5516.sol b/assets/eip-5516/IERC5516.sol
deleted file mode 100644
index a827f95..0000000
--- a/assets/eip-5516/IERC5516.sol
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.4;
-
-/**
- @title Soulbound, Multi-Token standard.
- @notice Interface of the EIP-5516
- Note: The ERC-165 identifier for this interface is 0x8314f22b.
- */
-
-interface IERC5516 {
- /**
- * @dev Emitted when `account` claims or rejects pending tokens under `ids[]`.
- */
- event TokenClaimed(
- address indexed operator,
- address indexed account,
- bool[] actions,
- uint256[] ids
- );
-
- /**
- * @dev Emitted when `from` transfers token under `id` to every address at `to[]`.
- */
- event TransferMulti(
- address indexed operator,
- address indexed from,
- address[] to,
- uint256 amount,
- uint256 id
- );
-
- /**
- * @dev Get tokens owned by a given address.
- */
- function tokensFrom(address from) external view returns (uint256[] memory);
-
- /**
- * @dev Get tokens awaiting to be claimed by a given address.
- */
- function pendingFrom(address from) external view returns (uint256[] memory);
-
- /**
- * @dev Claims or Reject pending `id`.
- *
- * Requirements:
- * - `account` must have a pending token under `id` at the moment of call.
- * - `account` must not own a token under `id` at the moment of call.
- *
- * Emits a {TokenClaimed} event.
- *
- */
- function claimOrReject(
- address account,
- uint256 id,
- bool action
- ) external;
-
- /**
- * @dev Claims or Reject pending tokens under `ids[]`.
- *
- * Requirements for each `id` `action` pair:
- * - `account` must have a pending token under `id` at the moment of call.
- * - `account` must not own a token under `id` at the moment of call.
- *
- * Emits a {TokenClaimed} event.
- *
- */
- function claimOrRejectBatch(
- address account,
- uint256[] memory ids,
- bool[] memory actions
- ) external;
-
- /**
- * @dev Transfers `id` token from `from` to every address at `to[]`.
- *
- * Requirements:
- *
- * - `from` MUST be the creator(minter) of `id`.
- * - All addresses in `to[]` MUST be non-zero.
- * - All addresses in `to[]` MUST have the token `id` under `_pendings`.
- * - All addresses in `to[]` MUST not own a token type under `id`.
- *
- * Emits a {TransfersMulti} event.
- *
- */
- function batchTransfer(
- address from,
- address[] memory to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) external;
-
-}
diff --git a/assets/eip-5528/ERC20Mockup.sol b/assets/eip-5528/ERC20Mockup.sol
deleted file mode 100644
index d5dd437..0000000
--- a/assets/eip-5528/ERC20Mockup.sol
+++ /dev/null
@@ -1,55 +0,0 @@
-pragma solidity ^0.4.24;
-
-
-
-
-contract ERC20Mockup {
- mapping(address => uint256) _balances;
- uint256 _totalSupply;
- address _owner;
-
- constructor(address initialAccount, uint256 initialBalance) {
- _owner = initialAccount;
- _totalSupply = initialBalance;
- _balances[initialAccount] = initialBalance;
- }
-
- function balanceOf(address account) public view returns (uint256) {
- return _balances[account];
- }
- function transfer(address to, uint256 amount) public returns (bool) {
- address owner = msg.sender;
- _transfer(owner, to, amount);
- return true;
- }
-
- function _transfer(
- address from,
- address to,
- uint256 amount
- ) internal {
- require(from != address(0), "ERC20: transfer from the zero address");
- require(to != address(0), "ERC20: transfer to the zero address");
-
- uint256 fromBalance = _balances[from];
- require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
- _balances[from] = fromBalance - amount;
- _balances[to] += amount;
- }
- /*
- From there, escrow related function
- */
- function escrowFund(address to, uint256 amount) public returns (bool) {
- bool res = ERC20Mockup(to).escrowFund(msg.sender, amount);
- require(res, "Fund Failed");
- _transfer(msg.sender, to, amount);
-
- return true;
- }
- function escrowRefund(address to, uint256 amount) public returns (bool) {
- bool res = ERC20Mockup(to).escrowRefund(msg.sender, amount);
- require(res, "Refund Failed");
- _transfer(to, msg.sender, amount);
- return true;
- }
-}
diff --git a/assets/eip-5528/EscrowContractAccount.sol b/assets/eip-5528/EscrowContractAccount.sol
deleted file mode 100644
index 99ae11b..0000000
--- a/assets/eip-5528/EscrowContractAccount.sol
+++ /dev/null
@@ -1,171 +0,0 @@
-pragma solidity ^0.4.24;
-
-import "./ERC20Mockup.sol";
-
-
-contract ErcEscrowAccount {
- struct BalanceData {
- uint256 seller;
- uint256 buyer;
- }
-
- enum State { Inited, Running, Success, Failed }
-
- struct EscrowStatus {
- uint256 numberOfBuyer;
- uint256 fundTotal;
- uint256 fundFilled;
- State state;
- }
- mapping(address => BalanceData) _balances;
-
- address _addrSeller;
- address _addrBuyer;
- address _addrEscrow;
- address _addrCreator;
-
- EscrowStatus _status;
-
- constructor(uint256 fundAmount, address sellerContract, address buyerContract) {
-
- //require(sellerContract.code.length > 0, "seller is not contract");
- //require(buyerContract.code.length > 0, "buyer is not contract");
-
- _addrBuyer = buyerContract;
- _addrSeller = sellerContract;
-
- _status.numberOfBuyer = 0;
- _status.fundTotal = fundAmount;
- _status.fundFilled = 0;
-
- _addrEscrow = address(this);
- _addrCreator = msg.sender;
- _status.state = State.Inited;
- }
-
-
- function helper_bigInt256(uint256 _u256Val) public view returns (uint256) {
- return _u256Val;
- }
-
- function helper_numberOfBuyers() public view returns (uint256) {
- return _status.numberOfBuyer;
- }
-
- function _updateRunningState() {
- if(_status.state == State.Running){
- if(_status.numberOfBuyer == 2){
- _status.state = State.Success;
- }
- }
- }
-
- function escrowStatus() public view returns (string) {
- if(_status.state == State.Inited){
- return "init";
- }else if(_status.state == State.Running){
- return "Running";
- }else if(_status.state == State.Success){
- return "Success";
- }else if(_status.state == State.Failed){
- return "Failed";
- }
- return "unknown state";
- }
-
-
- function balanceOf(address account) public view returns (uint256) {
- return _balances[account].buyer;
- }
-
- function escrowBalanceOf(address account) public view returns (uint256 o_buyer, uint256 o_seller) {
- o_buyer = _balances[account].buyer;
- o_seller = _balances[account].seller;
- }
-
- function escrowFund(address to, uint256 amount) public returns (bool) {
- require(amount > 0, "amount is too small");
- if(msg.sender == _addrSeller){
-
- require(_status.state == State.Inited, "must be init state");
- require(to == _addrCreator, "to is only with creator");
- require(amount == _status.fundTotal, "amount must be total fund");
- require(_status.fundFilled == 0, "fund filled must be zero");
-
- _status.fundFilled = amount;
-
- _balances[to].seller = _balances[to].seller + amount;
- _balances[to].buyer = 0;
- _status.state = State.Running;
-
- }else if(msg.sender == _addrBuyer){
- require(_status.state == State.Running, "must be running state");
- require(_status.fundTotal > 0, "escrow might be not started or already finished");
- require(_status.fundFilled == _status.fundTotal, "fund does not filled yet");
-
- // TODO: this logic is only for 1:1 exchange rate
- require(amount <= _balances[_addrCreator].seller, "no more token left to exchange");
-
- _balances[_addrCreator].seller = _balances[_addrCreator].seller - amount;
- _balances[_addrCreator].buyer = _balances[_addrCreator].buyer + amount;
-
- if(_balances[to].seller == 0){
- _status.numberOfBuyer = _status.numberOfBuyer + 1;
- }
- _balances[to].seller = _balances[to].seller + amount;
- _balances[to].buyer = _balances[to].buyer + amount;
-
- _updateRunningState();
- }else{
- require(false, "Todo other cases");
- }
-
-
-
- return true;
- }
-
- function escrowRefund(address to, uint256 amount) public returns (bool) {
- require(amount > 0, "amount is too small");
- require(_status.state == State.Running || _status.state == State.Failed, "must be running state to refund");
- require(msg.sender == _addrBuyer, "must be buyer contract to refund");
- require(_balances[to].buyer >= amount, "buyer fund is not enough to refund");
-
-
- _balances[to].buyer = _balances[to].buyer - amount;
- _balances[to].seller = _balances[to].seller - amount;
-
- _balances[_addrCreator].seller = _balances[_addrCreator].seller + amount;
- _balances[_addrCreator].buyer = _balances[_addrCreator].buyer - amount;
-
- if(_balances[to].buyer == 0){
- _status.numberOfBuyer = _status.numberOfBuyer - 1;
- }
-
- _updateRunningState();
- return true;
- }
-
- function escrowWithdraw() public returns (bool) {
- address from = msg.sender;
-
- if(from == _addrCreator){
- if(_status.state == State.Success){
- ERC20Mockup(_addrBuyer).transfer(from, _balances[from].buyer);
- ERC20Mockup(_addrSeller).transfer(from, _balances[from].seller);
-
- }else if(_status.state == State.Failed){
- ERC20Mockup(_addrSeller).transfer(from, _status.fundFilled);
- }else{
- require(false, "invalid state for seller withdraw");
- }
- }else{
- require(_status.state == State.Success, "withdraw is only in success, otherwise use refund");
- ERC20Mockup(_addrSeller).transfer(from, _balances[from].seller);
- }
-
- delete _balances[from];
- return true;
- }
-
-}
diff --git a/assets/eip-5528/truffule-test.js b/assets/eip-5528/truffule-test.js
deleted file mode 100644
index 3247e8e..0000000
--- a/assets/eip-5528/truffule-test.js
+++ /dev/null
@@ -1,115 +0,0 @@
-const EscrowContractAccount = artifacts.require('./EscrowContractAccount')
-const ERC20Mockup = artifacts.require('./ERC20Mockup')
-
-const util = require('util')
-contract('ERCEscrowMockup', accounts => {
- const [userCreator, userSeller, userBuyer01, userBuyer02, ...others] = accounts
-
- let contracts
-
- const BNConst = {
- totalFund: 100,
- user1: 10,
- user2: 33,
- zero: 0,
- DigOne: 1,
- DigTwo: 2,
- }
-
- before(async () => {
- const seller = await ERC20Mockup.new(userCreator, 10000)
- await seller.transfer(userSeller, 1000, {from: userCreator})
-
- const buyer = await ERC20Mockup.new(userCreator, 10000)
- await buyer.transfer(userBuyer01, 1000, {from: userCreator})
- await buyer.transfer(userBuyer02, 1000, {from: userCreator})
-
- const escrow = await EscrowContractAccount.new(BNConst.totalFund, seller.address, buyer.address, {from: userSeller})
-
- contracts = {
- escrow,
- seller,
- buyer,
- }
- for (const key in BNConst) {
- const v = BNConst[key]
- BNConst[key] = {
- origin: v,
- bn: await escrow.helper_bigInt256(v),
- }
- }
- //console.log('-check point-1-', util.inspect(contracts, false, null, true))
- })
-
- it('escrow start', async () => {
- const result = await contracts.seller.escrowFund(contracts.escrow.address, BNConst.totalFund.origin, {
- from: userSeller,
- })
- const [buyer, seller] = await contracts.escrow.escrowBalanceOf(userSeller)
- const state = await contracts.escrow.escrowStatus()
- //console.log('---check00000', state)
- //console.log('-check point-1-', util.inspect(result, false, null, true))
- //console.log('--balance---', {buyer, seller, bigNumberPrefix})
- assert(buyer.eq(BNConst.zero.bn))
- assert(seller.eq(BNConst.totalFund.bn))
- })
-
- it('purchase first buyer', async () => {
- await contracts.buyer.escrowFund(contracts.escrow.address, BNConst.user1.origin, {from: userBuyer01})
- const [buyer, seller] = await contracts.escrow.escrowBalanceOf(userBuyer01)
- })
- it('first buyer refund and purchase', async () => {
- await contracts.buyer.escrowRefund(contracts.escrow.address, BNConst.user1.origin, {from: userBuyer01})
- let result = await contracts.escrow.helper_numberOfBuyers()
- //console.log('-----1----', result)
- assert(result.eq(BNConst.zero.bn))
-
- await contracts.buyer.escrowFund(contracts.escrow.address, BNConst.user1.origin, {from: userBuyer01})
- result = await contracts.escrow.helper_numberOfBuyers()
- //console.log('-----1----', result)
- assert(result.eq(BNConst.DigOne.bn))
- })
- it('send buyer purchase can finialize fund', async () => {
- await contracts.buyer.escrowFund(contracts.escrow.address, BNConst.user2.origin, {from: userBuyer02})
- let result = await contracts.escrow.helper_numberOfBuyers()
- //console.log('-----1----', result)
- assert(result.eq(BNConst.DigTwo.bn))
- result = await contracts.escrow.escrowStatus()
- //console.log('-----2----', result)
- assert(result === 'Success')
- })
- it('check balance of seller and buyer', async () => {
- const balance = {
- sellerToken: {
- issuer: await contracts.seller.balanceOf(userSeller),
- b01: await contracts.seller.balanceOf(userBuyer01),
- b02: await contracts.seller.balanceOf(userBuyer02),
- },
- buyerToken: {
- issuer: await contracts.buyer.balanceOf(userSeller),
- b01: await contracts.buyer.balanceOf(userBuyer01),
- b02: await contracts.buyer.balanceOf(userBuyer02),
- },
- }
- //console.log('-check point-1-', util.inspect(balance, false, null, true))
- })
-
- it('check balance after withdraw', async () => {
- await contracts.escrow.escrowWithdraw({from: userSeller})
- await contracts.escrow.escrowWithdraw({from: userBuyer01})
- await contracts.escrow.escrowWithdraw({from: userBuyer02})
- const balance = {
- sellerToken: {
- issuer: await contracts.seller.balanceOf(userSeller),
- b01: await contracts.seller.balanceOf(userBuyer01),
- b02: await contracts.seller.balanceOf(userBuyer02),
- },
- buyerToken: {
- issuer: await contracts.buyer.balanceOf(userSeller),
- b01: await contracts.buyer.balanceOf(userBuyer01),
- b02: await contracts.buyer.balanceOf(userBuyer02),
- },
- }
- //console.log('-check point-1-', util.inspect(balance, false, null, true))
- })
-})
diff --git a/assets/eip-5564/minimal_poc.ipynb b/assets/eip-5564/minimal_poc.ipynb
deleted file mode 100644
index c7e589d..0000000
--- a/assets/eip-5564/minimal_poc.ipynb
+++ /dev/null
@@ -1,639 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "d2c6b4cd",
- "metadata": {},
- "outputs": [],
- "source": [
- "# PoC using scaning and spending keys"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 2,
- "id": "6bcea120",
- "metadata": {},
- "outputs": [],
- "source": [
- "import hashlib\n",
- "from py_ecc.secp256k1 import *\n",
- "import sha3\n",
- "from eth_account import Account"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "4e25cb04",
- "metadata": {},
- "source": [
- "## Sender"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "22ca0bf7",
- "metadata": {},
- "source": [
- "$S = G*s$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 3,
- "id": "bb9355a0",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(22246744184454969143801186698733154500632648736073949898323976612504587645286,\n",
- " 110772761940586493986212935445517909380300793379795289150161960681985511655321)"
- ]
- },
- "execution_count": 3,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# privkey: 0xd952fe0740d9d14011fc8ead3ab7de3c739d3aa93ce9254c10b0134d80d26a30\n",
- "# address: 0x3CB39EA2f14B16B69B451719A7BEd55e0aFEcE8F\n",
- "s = int(0xd952fe0740d9d14011fc8ead3ab7de3c739d3aa93ce9254c10b0134d80d26a30) # private key\n",
- "S = secp256k1.privtopub(s.to_bytes(32, \"big\")) # public key\n",
- "S"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "c8240f67",
- "metadata": {},
- "source": [
- "## Recipient"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "6895e603",
- "metadata": {},
- "source": [
- "$P = G*p$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 4,
- "id": "c8e2d6ad",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "((89565891926547004231252920425935692360644145829622209833684329913297188986597,\n",
- " 12158399299693830322967808612713398636155367887041628176798871954788371653930),\n",
- " (112711660439710606056748659173929673102114977341539408544630613555209775888121,\n",
- " 25583027980570883691656905877401976406448868254816295069919888960541586679410))"
- ]
- },
- "execution_count": 4,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# privkey: 0x0000000000000000000000000000000000000000000000000000000000000001\n",
- "# address: 0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf\n",
- "p_scan = int(0x0000000000000000000000000000000000000000000000000000000000000002) # private key\n",
- "p_spend = int(0x0000000000000000000000000000000000000000000000000000000000000003) # private key\n",
- "\n",
- "P_scan = secp256k1.privtopub(p_scan.to_bytes(32, \"big\")) # public key\n",
- "P_spend = secp256k1.privtopub(p_spend.to_bytes(32, \"big\")) # public key\n",
- "P_scan, P_spend"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "174929d7",
- "metadata": {},
- "source": [
- "## Calculate Stealth Address: $P_{spend} + G*hash(Q)$"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8b39ed39",
- "metadata": {},
- "source": [
- "$Q = S * p_{scan}$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 5,
- "id": "63a022d7",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(65311808848028536848162101908966111079795231803322390815513763038079235257196,\n",
- " 43767810034999830518515787564234053904327508763526333662117780420755425490082)"
- ]
- },
- "execution_count": 5,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Q = secp256k1.multiply(P_scan, s)\n",
- "Q"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "d79c69fc",
- "metadata": {},
- "source": [
- "$Q = S * p_{scan} = P_{scan} * s$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 6,
- "id": "5f5fbcf4",
- "metadata": {},
- "outputs": [],
- "source": [
- "assert Q == secp256k1.multiply(S, p_scan)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "0d5803ff",
- "metadata": {},
- "source": [
- "$h(Q)$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 7,
- "id": "f1b38cb0",
- "metadata": {},
- "outputs": [],
- "source": [
- "Q_hex = sha3.keccak_256(Q[0].to_bytes(32, \"big\") \n",
- " + Q[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()\n",
- "Q_hased = bytearray.fromhex(Q_hex)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "a0647821",
- "metadata": {},
- "source": [
- "$ stA = h(Q) * G + P_{spend}$"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "865e7f72",
- "metadata": {},
- "source": [
- "#### Sender sends funds to..."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 8,
- "id": "d9dd755f",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'0xfed69df0a27f1dae0d7430ead82aaedfad6332bb'"
- ]
- },
- "execution_count": 8,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "stP = secp256k1.add(P_spend, secp256k1.privtopub(Q_hased))\n",
- "stA = \"0x\"+ sha3.keccak_256(stP[0].to_bytes(32, \"big\")\n",
- " +stP[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()[-40:]\n",
- "stA"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "38e69080",
- "metadata": {},
- "source": [
- "#### Sender broadcasts"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 9,
- "id": "cdf57fef",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "((22246744184454969143801186698733154500632648736073949898323976612504587645286,\n",
- " 110772761940586493986212935445517909380300793379795289150161960681985511655321),\n",
- " '0xfed69df0a27f1dae0d7430ead82aaedfad6332bb')"
- ]
- },
- "execution_count": 9,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "S, stA"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "588ccc7c",
- "metadata": {},
- "source": [
- "## Parse received funds"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "462f8c8d",
- "metadata": {},
- "source": [
- "* Note that $p_{scan}$ and $P_{spend}$ can be shared with a trusted party\n",
- "* There may be many S to be parsed"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8ba2a295",
- "metadata": {},
- "source": [
- "$h(p_{scan}*S)*G + P_{spend} => toAddress$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 10,
- "id": "50b63208",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'0xfed69df0a27f1dae0d7430ead82aaedfad6332bb'"
- ]
- },
- "execution_count": 10,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Q = secp256k1.multiply(S, p_scan)\n",
- "Q_hex = sha3.keccak_256(Q[0].to_bytes(32, \"big\")+Q[1].to_bytes(32, \"big\")).hexdigest()\n",
- "Q_hased = bytearray.fromhex(Q_hex)\n",
- "\n",
- "P_stealth = secp256k1.add(P_spend, secp256k1.privtopub(Q_hased))\n",
- "P_stealthAddress = \"0x\"+ sha3.keccak_256(stP[0].to_bytes(32, \"big\")\n",
- " + stP[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()[-40:]\n",
- "P_stealthAddress"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8055d075",
- "metadata": {},
- "source": [
- "logged stealth address $stA$ equals the derived stealth address $P_stealthAddress$"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "26758ea5",
- "metadata": {},
- "source": [
- "$stA==stA_d$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 11,
- "id": "3faed6a3",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 11,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "P_stealthAddress == stA"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "050e346c",
- "metadata": {},
- "source": [
- "## Derive private key"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "44801516",
- "metadata": {},
- "source": [
- "#### Only the recipient has access to $p_{spend}$"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "7673e439",
- "metadata": {},
- "source": [
- "$p_{stealth}=p_{spend}+hash(Q)$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 12,
- "id": "4013b57e",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "39153944482575822531387237249775711740128993925789544779866399859639729033274"
- ]
- },
- "execution_count": 12,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Q = secp256k1.multiply(S, p_scan)\n",
- "Q_hex = sha3.keccak_256(Q[0].to_bytes(32, \"big\")+Q[1].to_bytes(32, \"big\")).hexdigest()\n",
- "p_stealth = p_spend + int(Q_hex, 16)\n",
- "p_stealth"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "dc31c1aa",
- "metadata": {},
- "source": [
- "$P_{stealth} = p_{stealth}*G$"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 13,
- "id": "09b5ccc2",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "(67663851387124608323744162645277269585638670865381831245083336172545348387042,\n",
- " 80449904826544093817252981338261706033086352950841917067356875711772573870404)"
- ]
- },
- "execution_count": 13,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "# Recipient has private key to ...\n",
- "P_stealth = secp256k1.privtopub(p_stealth.to_bytes(32, \"big\"))\n",
- "P_stealth"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 14,
- "id": "a3ead30e",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'0xfed69df0a27f1dae0d7430ead82aaedfad6332bb'"
- ]
- },
- "execution_count": 14,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "P_stealthAddress_d = \"0x\"+ sha3.keccak_256(P_stealth[0].to_bytes(32, \"big\")\n",
- " + P_stealth[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()[-40:]\n",
- "P_stealthAddress_d"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 15,
- "id": "2712c07b",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'0xfEd69Df0a27F1daE0D7430EAd82aaEdfAD6332bb'"
- ]
- },
- "execution_count": 15,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Account.from_key((p_stealth).to_bytes(32, \"big\")).address"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "74f0325e",
- "metadata": {},
- "source": [
- "## Additionally add view tags"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "ac45bb87",
- "metadata": {},
- "source": [
- "In addition to S and stA, the sender also broadcasts the first byte of h(Q)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 16,
- "id": "9645b880",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "86"
- ]
- },
- "execution_count": 16,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "Q_hased[0]"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "8788f2f5",
- "metadata": {},
- "source": [
- "The recipient can do the the same a before without one EC Multiplication, one EC Addition and on Public Key to Address Conversion in order to check being a potential recipient."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 17,
- "id": "bb9f5852",
- "metadata": {},
- "outputs": [],
- "source": [
- "Q_derived = secp256k1.multiply(S, p_scan)\n",
- "Q_hex_derived = sha3.keccak_256(Q_derived[0].to_bytes(32, \"big\")\n",
- " +Q_derived[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()\n",
- "Q_hashed_derived = bytearray.fromhex(Q_hex_derived)"
- ]
- },
- {
- "cell_type": "markdown",
- "id": "f7dc4624",
- "metadata": {},
- "source": [
- "Check view tag"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 18,
- "id": "953bf07d",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 18,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "run = Q_hased[0] == Q_hashed_derived[0] \n",
- "run"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 19,
- "id": "e11ec134",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "'0xfed69df0a27f1dae0d7430ead82aaedfad6332bb'"
- ]
- },
- "execution_count": 19,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "if run:\n",
- " P_stealth = secp256k1.add(P_spend, secp256k1.privtopub(Q_hased))\n",
- " P_stealthAddress = \"0x\"+ sha3.keccak_256(stP[0].to_bytes(32, \"big\")\n",
- " + stP[1].to_bytes(32, \"big\")\n",
- " ).hexdigest()[-40:]\n",
- "P_stealthAddress"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": 20,
- "id": "bd06ffc5",
- "metadata": {},
- "outputs": [
- {
- "data": {
- "text/plain": [
- "True"
- ]
- },
- "execution_count": 20,
- "metadata": {},
- "output_type": "execute_result"
- }
- ],
- "source": [
- "P_stealthAddress==stA"
- ]
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "hackathon",
- "language": "python",
- "name": "hackathon"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.10.8"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
diff --git a/assets/eip-5564/scheme_ids.md b/assets/eip-5564/scheme_ids.md
deleted file mode 100644
index 090da4a..0000000
--- a/assets/eip-5564/scheme_ids.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# EIP-5564 - Scheme Id Mapping
-
-
-Last edited 07.02.2023
-
-| ID | Scheme | EIP | Added |
-|---|---|---|---|
-| 0 | SECP256k1, with view tags. | [EIP-5564](https://eips.ethereum.org/EIPS/eip-5564) | 07.02.2023 |
diff --git a/assets/eip-5606/contracts/MultiverseNFT.sol b/assets/eip-5606/contracts/MultiverseNFT.sol
deleted file mode 100644
index b250619..0000000
--- a/assets/eip-5606/contracts/MultiverseNFT.sol
+++ /dev/null
@@ -1,421 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.9;
-
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/utils/math/SafeMath.sol";
-import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
-import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Supply.sol";
-import "@openzeppelin/contracts/access/AccessControl.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
-import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
-
-contract ERC721Full is ERC721Enumerable, ERC721URIStorage {
- /// @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
- /// @param name is a non-empty string
- /// @param symbol is a non-empty string
- constructor(string memory name, string memory symbol)
- ERC721(name, symbol)
- {}
-
- /// @dev Hook that is called before any token transfer. This includes minting and burning. `from`'s `tokenId` will be transferred to `to`
- /// @param from is an non-zero address
- /// @param to is an non-zero address
- /// @param tokenId is an uint256 which determine token transferred from `from` to `to`
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual override(ERC721Enumerable, ERC721) {
- ERC721Enumerable._beforeTokenTransfer(from, to, tokenId);
- }
-
- /// @notice Interface of the ERC165 standard
- /// @param interfaceId is a byte4 which determine interface used
- /// @return true if this contract implements the interface defined by `interfaceId`
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(ERC721Enumerable, ERC721)
- returns (bool)
- {
- return
- ERC721.supportsInterface(interfaceId) ||
- ERC721Enumerable.supportsInterface(interfaceId);
- }
-
- /// @notice the Uniform Resource Identifier (URI) for `tokenId` token
- /// @param tokenId is unit256
- /// @return string of (URI) for `tokenId` token
- function tokenURI(uint256 tokenId)
- public
- view
- virtual
- override(ERC721URIStorage, ERC721)
- returns (string memory)
- {
- return ERC721URIStorage.tokenURI(tokenId);
- }
-
- function _burn(uint256 tokenId)
- internal
- override(ERC721, ERC721URIStorage)
- {}
-}
-
-/**
- * @dev Interface of the Multiverse NFT standard as defined in the EIP.
- */
-interface IMultiverseNFT {
- /**
- * @dev struct to store delegate token details
- *
- */
- struct DelegateData {
- address contractAddress;
- uint256 tokenId;
- uint256 quantity;
- }
-
- /**
- * @dev Emitted when one or more new delegate NFTs are added to a Multiverse NFT
- *
- */
- event Bundled(
- uint256 multiverseTokenID,
- DelegateData[] delegateData,
- address ownerAddress
- );
-
- /**
- * @dev Emitted when one or more delegate NFTs are removed from a Multiverse NFT
- */
- event Unbundled(uint256 multiverseTokenID, DelegateData[] delegateData);
-
- /**
- * @dev Accepts the tokenId of the Multiverse NFT and returns an array of delegate token data
- */
- function delegateTokens(uint256 multiverseTokenID)
- external
- view
- returns (DelegateData[] memory);
-
- /**
- * @dev Removes one or more delegate NFTs from a Multiverse NFT
- * This function accepts the delegate NFT details, and transfer those NFTs out of the Multiverse NFT contract to the owner's wallet
- */
- function unbundle(
- DelegateData[] memory delegateData,
- uint256 multiverseTokenID
- ) external;
-
- /**
- * @dev Adds one or more delegate NFTs to a Multiverse NFT
- * This function accepts the delegate NFT details, and transfers those NFTs to the Multiverse NFT contract
- * Need to ensure that approval is given to this Multiverse NFT contract for the delegate NFTs so that they can be transferred programmatically
- */
- function bundle(
- DelegateData[] memory delegateData,
- uint256 multiverseTokenID
- ) external;
-
- /**
- * @dev Initializes a new bundle, mints a Multiverse NFT and assigns it to msg.sender
- * Returns the token ID of a new Multiverse NFT
- * Note - When a new Multiverse NFT is initialized, it is empty, it does not contain any delegate NFTs
- */
- function initBundle(DelegateData[] memory delegateData) external;
-}
-
-abstract contract MultiverseNFT is
- IMultiverseNFT,
- Ownable,
- ERC721Full,
- IERC1155Receiver,
- AccessControl
-{
- using SafeMath for uint256;
- bytes32 public constant BUNDLER_ROLE = keccak256("BUNDLER_ROLE");
-
- uint256 currentMultiverseTokenID;
-
- mapping(uint256 => DelegateData[]) public multiverseNFTDelegateData;
- mapping(uint256 => mapping(address => mapping(uint256 => uint256)))
- public tokenBalances;
-
- constructor(address bundlerAddress) {
- _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
- _setupRole(BUNDLER_ROLE, msg.sender);
- _setRoleAdmin(BUNDLER_ROLE, DEFAULT_ADMIN_ROLE);
- _setupRole(BUNDLER_ROLE, bundlerAddress);
- }
-
- function delegateTokens(uint256 multiverseTokenID)
- external
- view
- returns (DelegateData[] memory)
- {
- return multiverseNFTDelegateData[multiverseTokenID];
- }
-
- function initBundle(DelegateData[] memory delegateData) external {
- uint256 tokenId = currentMultiverseTokenID.add(1);
- for (uint256 i = 0; i < delegateData.length; i = i.add(1)) {
- bool isERC721 = _isERC721(delegateData[i].contractAddress);
- if (isERC721) {
- require(
- delegateData[i].quantity == 1,
- "ERC721 quantity must be 1"
- );
- }
- multiverseNFTDelegateData[tokenId].push(delegateData[i]);
- }
-
- _incrementMultiverseTokenID();
- _safeMint(msg.sender, tokenId);
- }
-
- function bundle(
- DelegateData[] memory delegateData,
- uint256 multiverseTokenID
- ) external {
- require(
- hasRole(BUNDLER_ROLE, msg.sender) ||
- ownerOf(multiverseTokenID) == msg.sender,
- "msg.sender neither have bundler role nor multiversetoken owner"
- );
- _bundle(delegateData, multiverseTokenID);
- }
-
- function unbundle(
- DelegateData[] memory delegateData,
- uint256 multiverseTokenID
- ) external {
- require(
- ownerOf(multiverseTokenID) == msg.sender,
- "msg.sender is not a multiversetoken owner"
- );
- for (uint256 i = 0; i < delegateData.length; i = i.add(1)) {
- require(
- _ensureDelegateBelongsToMultiverseNFT(
- delegateData[i],
- multiverseTokenID
- ),
- "delegate not assigned to multiverse token"
- );
- uint256 balance = tokenBalances[multiverseTokenID][
- delegateData[i].contractAddress
- ][delegateData[i].tokenId];
- require(
- delegateData[i].quantity <= balance,
- "quantity exceeds balance"
- );
- require(
- _ensureMultiverseContractOwnsDelegate(delegateData[i]),
- "delegate not owned by contract"
- );
-
- address contractAddress = delegateData[i].contractAddress;
- uint256 tokenId = delegateData[i].tokenId;
- uint256 quantity = delegateData[i].quantity;
-
- _updateDelegateBalances(delegateData[i], multiverseTokenID);
-
- if (_isERC721(contractAddress)) {
- ERC721Full erc721Instance = ERC721Full(contractAddress);
- erc721Instance.transferFrom(address(this), msg.sender, tokenId);
- } else if (_isERC1155(contractAddress)) {
- ERC1155Supply erc1155Instance = ERC1155Supply(contractAddress);
- erc1155Instance.safeTransferFrom(
- address(this),
- msg.sender,
- tokenId,
- quantity,
- ""
- );
- }
- }
- emit Unbundled(multiverseTokenID, delegateData);
- }
-
- function supportsInterface(bytes4 interfaceId)
- public
- view
- override(AccessControl, ERC721Full, IERC165)
- returns (bool)
- {
- return
- AccessControl.supportsInterface(interfaceId) ||
- ERC721Full.supportsInterface(interfaceId);
- }
-
- function _bundle(
- DelegateData[] memory delegateData,
- uint256 multiverseTokenID
- ) internal {
- for (uint256 i = 0; i < delegateData.length; i = i.add(1)) {
- require(
- _ensureDelegateBelongsToMultiverseNFT(
- delegateData[i],
- multiverseTokenID
- ),
- "delegate not assigned to multiversetoken"
- );
- require(
- _ensureDelegateQuantityLimitForMMultiverseNFT(
- delegateData[i],
- multiverseTokenID
- ),
- "delegate quantity assigned to multiversetoken exceeds"
- );
-
- address contractAddress = delegateData[i].contractAddress;
- uint256 tokenId = delegateData[i].tokenId;
- uint256 quantity = delegateData[i].quantity;
-
- tokenBalances[multiverseTokenID][contractAddress][
- tokenId
- ] = tokenBalances[multiverseTokenID][contractAddress][tokenId].add(
- quantity
- );
-
- if (_isERC721(contractAddress)) {
- require(
- quantity == 1,
- "ERC721 cannot have quantity more than 1"
- );
- ERC721Full erc721Instance = ERC721Full(contractAddress);
- erc721Instance.transferFrom(msg.sender, address(this), tokenId);
- } else if (_isERC1155(contractAddress)) {
- ERC1155Supply erc1155Instance = ERC1155Supply(contractAddress);
- erc1155Instance.safeTransferFrom(
- msg.sender,
- address(this),
- tokenId,
- quantity,
- ""
- );
- }
- }
- emit Bundled(
- multiverseTokenID,
- delegateData,
- ownerOf(multiverseTokenID)
- );
- }
-
- function _ensureDelegateBelongsToMultiverseNFT(
- DelegateData memory delegateData,
- uint256 multiverseTokenID
- ) internal view returns (bool) {
- DelegateData[] memory storedData = multiverseNFTDelegateData[
- multiverseTokenID
- ];
- for (uint256 i = 0; i < storedData.length; i = i.add(1)) {
- if (
- delegateData.contractAddress == storedData[i].contractAddress &&
- delegateData.tokenId == storedData[i].tokenId
- ) {
- return true;
- }
- }
- return false;
- }
-
- function _ensureMultiverseContractOwnsDelegate(
- DelegateData memory delegateData
- ) internal view returns (bool) {
- if (_isERC721(delegateData.contractAddress)) {
- ERC721Full erc721Instance = ERC721Full(
- delegateData.contractAddress
- );
- if (address(this) == erc721Instance.ownerOf(delegateData.tokenId)) {
- return true;
- }
- } else if (_isERC1155(delegateData.contractAddress)) {
- ERC1155Supply erc1155Instance = ERC1155Supply(
- delegateData.contractAddress
- );
- if (
- erc1155Instance.balanceOf(
- address(this),
- delegateData.tokenId
- ) >= delegateData.quantity
- ) {
- return true;
- }
- }
- return false;
- }
-
- function _ensureDelegateQuantityLimitForMMultiverseNFT(
- DelegateData memory delegateData,
- uint256 multiverseTokenID
- ) internal view returns (bool) {
- DelegateData[] memory storedData = multiverseNFTDelegateData[
- multiverseTokenID
- ];
- for (uint256 i = 0; i < storedData.length; i = i.add(1)) {
- if (
- delegateData.contractAddress == storedData[i].contractAddress &&
- delegateData.tokenId == storedData[i].tokenId
- ) {
- uint256 balance = tokenBalances[multiverseTokenID][
- delegateData.contractAddress
- ][delegateData.tokenId];
- if (
- balance.add(delegateData.quantity) <= storedData[i].quantity
- ) {
- return true;
- }
- return false;
- }
- }
- }
-
- function _updateDelegateBalances(
- DelegateData memory delegateData,
- uint256 multiverseTokenID
- ) internal returns (uint256) {
- address contractAddress = delegateData.contractAddress;
- uint256 tokenId = delegateData.tokenId;
- tokenBalances[multiverseTokenID][contractAddress][
- tokenId
- ] = tokenBalances[multiverseTokenID][contractAddress][tokenId].sub(
- delegateData.quantity
- );
- return tokenBalances[multiverseTokenID][contractAddress][tokenId];
- }
-
- function onERC1155Received(
- address operator,
- address from,
- uint256 id,
- uint256 value,
- bytes calldata data
- ) external pure override returns (bytes4) {
- return this.onERC1155Received.selector;
- }
-
- function onERC1155BatchReceived(
- address operator,
- address from,
- uint256[] calldata ids,
- uint256[] calldata values,
- bytes calldata data
- ) external pure override returns (bytes4) {
- return this.onERC1155BatchReceived.selector;
- }
-
- function _isERC1155(address contractAddress) internal view returns (bool) {
- return IERC1155(contractAddress).supportsInterface(0xd9b67a26);
- }
-
- function _isERC721(address contractAddress) internal view returns (bool) {
- return IERC721(contractAddress).supportsInterface(0x80ac58cd);
- }
-
- function _incrementMultiverseTokenID() internal {
- currentMultiverseTokenID = currentMultiverseTokenID.add(1);
- }
-}
diff --git a/assets/eip-5633/contracts/ERC5633.sol b/assets/eip-5633/contracts/ERC5633.sol
deleted file mode 100644
index 121f6bf..0000000
--- a/assets/eip-5633/contracts/ERC5633.sol
+++ /dev/null
@@ -1,54 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
-import "./IERC5633.sol";
-
-/**
- * @dev Extension of ERC1155 that adds soulbound property per token id.
- *
- */
-abstract contract ERC5633 is ERC1155, IERC5633 {
- mapping(uint256 => bool) private _soulbounds;
-
- /// @dev See {IERC165-supportsInterface}.
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155) returns (bool) {
- return interfaceId == type(IERC5633).interfaceId || super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev Returns true if a token type `id` is soulbound.
- */
- function isSoulbound(uint256 id) public view virtual returns (bool) {
- return _soulbounds[id];
- }
-
- function _setSoulbound(uint256 id, bool soulbound) internal {
- _soulbounds[id] = soulbound;
- emit Soulbound(id, soulbound);
- }
-
- /**
- * @dev See {ERC1155-_beforeTokenTransfer}.
- */
- function _beforeTokenTransfer(
- address operator,
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) internal virtual override {
- super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
-
- for (uint256 i = 0; i < ids.length; ++i) {
- if (isSoulbound(ids[i])) {
- require(
- from == address(0) || to == address(0),
- "ERC5633: Soulbound, Non-Transferable"
- );
- }
- }
- }
-}
\ No newline at end of file
diff --git a/assets/eip-5633/contracts/ERC5633Demo.sol b/assets/eip-5633/contracts/ERC5633Demo.sol
deleted file mode 100644
index 8427d37..0000000
--- a/assets/eip-5633/contracts/ERC5633Demo.sol
+++ /dev/null
@@ -1,55 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-import "@openzeppelin/contracts/token/ERC1155/ERC1155.sol";
-import "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Burnable.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-
-import "./ERC5633.sol";
-
-contract ERC5633Demo is ERC1155, ERC1155Burnable, Ownable, ERC5633 {
- constructor() ERC1155("") ERC5633() {}
-
- function mint(address account, uint256 id, uint256 amount, bytes memory data)
- public
- onlyOwner
- {
- _mint(account, id, amount, data);
- }
-
- function mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
- public
- onlyOwner
- {
- _mintBatch(to, ids, amounts, data);
- }
-
- function setSoulbound(uint256 id, bool soulbound)
- public
- onlyOwner
- {
- _setSoulbound(id, soulbound);
- }
-
- // The following functions are overrides required by Solidity.
- function supportsInterface(bytes4 interfaceId)
- public
- view
- override(ERC1155, ERC5633)
- returns (bool)
- {
- return super.supportsInterface(interfaceId);
- }
-
- function _beforeTokenTransfer(address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data)
- internal
- override(ERC1155, ERC5633)
- {
- super._beforeTokenTransfer(operator, from, to, ids, amounts, data);
- }
-
- function getInterfaceId() public view returns (bytes4) {
- return type(IERC5633).interfaceId;
- }
-}
diff --git a/assets/eip-5633/contracts/IERC5633.sol b/assets/eip-5633/contracts/IERC5633.sol
deleted file mode 100644
index 3496ea5..0000000
--- a/assets/eip-5633/contracts/IERC5633.sol
+++ /dev/null
@@ -1,14 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-
-interface IERC5633 {
- /**
- * @dev Emitted when a token type `id` is set or cancel to soulbound, according to `bounded`.
- */
- event Soulbound(uint256 indexed id, bool bounded);
-
- /**
- * @dev Returns true if a token type `id` is soulbound.
- */
- function isSoulbound(uint256 id) external view returns (bool);
-}
\ No newline at end of file
diff --git a/assets/eip-5633/hardhat.config.js b/assets/eip-5633/hardhat.config.js
deleted file mode 100644
index 7a30b5c..0000000
--- a/assets/eip-5633/hardhat.config.js
+++ /dev/null
@@ -1,14 +0,0 @@
-require("@nomicfoundation/hardhat-toolbox");
-
-/** @type import('hardhat/config').HardhatUserConfig */
-module.exports = {
- solidity: {
- version: "0.8.9",
- settings: {
- optimizer: {
- enabled: true,
- runs: 200
- }
- }
- },
-};
diff --git a/assets/eip-5633/package.json b/assets/eip-5633/package.json
deleted file mode 100644
index c3dbe0a..0000000
--- a/assets/eip-5633/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "name": "eip-5633",
- "devDependencies": {
- "@ethersproject/providers": "^5.7.0",
- "@nomicfoundation/hardhat-chai-matchers": "^1.0.3",
- "@nomicfoundation/hardhat-network-helpers": "^1.0.6",
- "@nomicfoundation/hardhat-toolbox": "^1.0.2",
- "@nomiclabs/hardhat-ethers": "^2.1.1",
- "@nomiclabs/hardhat-etherscan": "^3.1.0",
- "@openzeppelin/contracts": "^4.7.3",
- "@typechain/ethers-v5": "^10.1.0",
- "@typechain/hardhat": "^6.1.2",
- "@types/chai": "^4.3.3",
- "@types/mocha": "^9.1.1",
- "chai": "^4.3.6",
- "ethers": "^5.7.0",
- "hardhat": "^2.11.0",
- "hardhat-gas-reporter": "^1.0.9",
- "solidity-coverage": "^0.7.22",
- "ts-node": "^10.9.1",
- "typechain": "^8.1.0",
- "typescript": "^4.8.3"
- }
-}
diff --git a/assets/eip-5633/test/test.js b/assets/eip-5633/test/test.js
deleted file mode 100644
index 089f559..0000000
--- a/assets/eip-5633/test/test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const { expect } = require("chai");
-const { ethers } = require("hardhat");
-
-describe("ERC5633Demo contract", function () {
-
- it("InterfaceId should equals 0x911ec470", async function () {
- const [owner, addr1, addr2] = await ethers.getSigners();
-
- const ERC5633Demo = await ethers.getContractFactory("ERC5633Demo");
-
- const demo = await ERC5633Demo.deploy();
- await demo.deployed();
-
- expect(await demo.getInterfaceId()).equals("0x911ec470");
- });
-
- it("Test soulbound", async function () {
- const [owner, addr1, addr2] = await ethers.getSigners();
-
- const ERC5633Demo = await ethers.getContractFactory("ERC5633Demo");
-
- const demo = await ERC5633Demo.deploy();
- await demo.deployed();
-
- await demo.setSoulbound(1, true);
- expect(await demo.isSoulbound(1)).to.equal(true);
- expect(await demo.isSoulbound(2)).to.equal(false);
-
- await demo.mint(addr1.address, 1, 2, "0x");
- await demo.mint(addr1.address, 2, 2, "0x");
-
- await expect(demo.connect(addr1).safeTransferFrom(addr1.address, addr2.address, 1, 1, "0x")).to.be.revertedWith(
- "ERC5633: Soulbound, Non-Transferable"
- );
- await expect(demo.connect(addr1).safeBatchTransferFrom(addr1.address, addr2.address, [1], [1], "0x")).to.be.revertedWith(
- "ERC5633: Soulbound, Non-Transferable"
- );
- await expect(demo.connect(addr1).safeBatchTransferFrom(addr1.address, addr2.address, [1,2], [1,1], "0x")).to.be.revertedWith(
- "ERC5633: Soulbound, Non-Transferable"
- );
-
- await demo.mint(addr1.address, 2, 1, "0x");
- demo.connect(addr1).safeTransferFrom(addr1.address, addr2.address, 2, 1, "0x");
- demo.connect(addr1).safeBatchTransferFrom(addr1.address, addr2.address, [2], [1], "0x");
-
- await demo.connect(addr1).burn(addr1.address, 1, 1);
- await demo.connect(addr1).burnBatch(addr1.address, [1], [1]);
- await demo.connect(addr2).burn(addr2.address, 2, 1);
- await demo.connect(addr2).burnBatch(addr2.address, [2], [1]);
- });
-});
diff --git a/assets/eip-5639/DelegationRegistry.sol b/assets/eip-5639/DelegationRegistry.sol
deleted file mode 100644
index b48fa00..0000000
--- a/assets/eip-5639/DelegationRegistry.sol
+++ /dev/null
@@ -1,449 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IDelegationRegistry} from "./IDelegationRegistry.sol";
-import {EnumerableSet} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
-import {ERC165} from "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol";
-
-/**
- * @title DelegationRegistry
- * @custom:version 0.2
- * @notice An immutable registry contract to be deployed as a standalone primitive.
- * New project launches can read previous cold wallet -> hot wallet delegations
- * from here and integrate those permissions into their flow.
- * @custom:coauthor foobar (0xfoobar)
- * @custom:coauthor wwchung (manifoldxyz)
- * @custom:coauthor purplehat (artblocks)
- * @custom:coauthor ryley-o (artblocks)
- * @custom:coauthor andy8052 (tessera)
- * @custom:coauthor punk6529 (open metaverse)
- * @custom:coauthor loopify (loopiverse)
- * @custom:coauthor emiliano (nftrentals)
- * @custom:coauthor arran (proof)
- * @custom:coauthor james (collabland)
- * @custom:coauthor john (gnosis safe)
- * @custom:coauthor 0xrusowsky
- */
-contract DelegationRegistry is IDelegationRegistry, ERC165 {
- using EnumerableSet for EnumerableSet.AddressSet;
- using EnumerableSet for EnumerableSet.Bytes32Set;
-
- /// @notice The global mapping and single source of truth for delegations
- /// @dev vault -> vaultVersion -> delegationHash
- mapping(address => mapping(uint256 => EnumerableSet.Bytes32Set)) internal delegations;
-
- /// @notice A mapping of wallets to versions (for cheap revocation)
- mapping(address => uint256) internal vaultVersion;
-
- /// @notice A mapping of wallets to delegates to versions (for cheap revocation)
- mapping(address => mapping(address => uint256)) internal delegateVersion;
-
- /// @notice A secondary mapping to return onchain enumerability of delegations that a given address can perform
- /// @dev delegate -> delegationHashes
- mapping(address => EnumerableSet.Bytes32Set) internal delegationHashes;
-
- /// @notice A secondary mapping used to return delegation information about a delegation
- /// @dev delegationHash -> DelegateInfo
- mapping(bytes32 => IDelegationRegistry.DelegationInfo) internal delegationInfo;
-
- /**
- * @inheritdoc ERC165
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override (ERC165) returns (bool) {
- return interfaceId == type(IDelegationRegistry).interfaceId || super.supportsInterface(interfaceId);
- }
-
- /**
- * ----------- WRITE -----------
- */
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function delegateForAll(address delegate, bool value) external override {
- bytes32 delegationHash = _computeAllDelegationHash(msg.sender, delegate);
- _setDelegationValues(
- delegate, delegationHash, value, IDelegationRegistry.DelegationType.ALL, msg.sender, address(0), 0
- );
- emit IDelegationRegistry.DelegateForAll(msg.sender, delegate, value);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function delegateForContract(address delegate, address contract_, bool value) external override {
- bytes32 delegationHash = _computeContractDelegationHash(msg.sender, delegate, contract_);
- _setDelegationValues(
- delegate, delegationHash, value, IDelegationRegistry.DelegationType.CONTRACT, msg.sender, contract_, 0
- );
- emit IDelegationRegistry.DelegateForContract(msg.sender, delegate, contract_, value);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function delegateForToken(address delegate, address contract_, uint256 tokenId, bool value) external override {
- bytes32 delegationHash = _computeTokenDelegationHash(msg.sender, delegate, contract_, tokenId);
- _setDelegationValues(
- delegate, delegationHash, value, IDelegationRegistry.DelegationType.TOKEN, msg.sender, contract_, tokenId
- );
- emit IDelegationRegistry.DelegateForToken(msg.sender, delegate, contract_, tokenId, value);
- }
-
- /**
- * @dev Helper function to set all delegation values and enumeration sets
- */
- function _setDelegationValues(
- address delegate,
- bytes32 delegateHash,
- bool value,
- IDelegationRegistry.DelegationType type_,
- address vault,
- address contract_,
- uint256 tokenId
- )
- internal
- {
- if (value) {
- delegations[vault][vaultVersion[vault]].add(delegateHash);
- delegationHashes[delegate].add(delegateHash);
- delegationInfo[delegateHash] =
- DelegationInfo({vault: vault, delegate: delegate, type_: type_, contract_: contract_, tokenId: tokenId});
- } else {
- delegations[vault][vaultVersion[vault]].remove(delegateHash);
- delegationHashes[delegate].remove(delegateHash);
- delete delegationInfo[delegateHash];
- }
- }
-
- /**
- * @dev Helper function to compute delegation hash for wallet delegation
- */
- function _computeAllDelegationHash(address vault, address delegate) internal view returns (bytes32) {
- uint256 vaultVersion_ = vaultVersion[vault];
- uint256 delegateVersion_ = delegateVersion[vault][delegate];
- return keccak256(abi.encode(delegate, vault, vaultVersion_, delegateVersion_));
- }
-
- /**
- * @dev Helper function to compute delegation hash for contract delegation
- */
- function _computeContractDelegationHash(address vault, address delegate, address contract_)
- internal
- view
- returns (bytes32)
- {
- uint256 vaultVersion_ = vaultVersion[vault];
- uint256 delegateVersion_ = delegateVersion[vault][delegate];
- return keccak256(abi.encode(delegate, vault, contract_, vaultVersion_, delegateVersion_));
- }
-
- /**
- * @dev Helper function to compute delegation hash for token delegation
- */
- function _computeTokenDelegationHash(address vault, address delegate, address contract_, uint256 tokenId)
- internal
- view
- returns (bytes32)
- {
- uint256 vaultVersion_ = vaultVersion[vault];
- uint256 delegateVersion_ = delegateVersion[vault][delegate];
- return keccak256(abi.encode(delegate, vault, contract_, tokenId, vaultVersion_, delegateVersion_));
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function revokeAllDelegates() external override {
- ++vaultVersion[msg.sender];
- emit IDelegationRegistry.RevokeAllDelegates(msg.sender);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function revokeDelegate(address delegate) external override {
- _revokeDelegate(delegate, msg.sender);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function revokeSelf(address vault) external override {
- _revokeDelegate(msg.sender, vault);
- }
-
- /**
- * @dev Revoke the `delegate` hotwallet from the `vault` coldwallet.
- */
- function _revokeDelegate(address delegate, address vault) internal {
- ++delegateVersion[vault][delegate];
- // For enumerations, filter in the view functions
- emit IDelegationRegistry.RevokeDelegate(vault, msg.sender);
- }
-
- /**
- * ----------- READ -----------
- */
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getDelegationsByDelegate(address delegate)
- external
- view
- returns (IDelegationRegistry.DelegationInfo[] memory info)
- {
- EnumerableSet.Bytes32Set storage potentialDelegationHashes = delegationHashes[delegate];
- uint256 potentialDelegationHashesLength = potentialDelegationHashes.length();
- uint256 delegationCount = 0;
- info = new IDelegationRegistry.DelegationInfo[](potentialDelegationHashesLength);
- for (uint256 i = 0; i < potentialDelegationHashesLength;) {
- bytes32 delegateHash = potentialDelegationHashes.at(i);
- IDelegationRegistry.DelegationInfo memory delegationInfo_ = delegationInfo[delegateHash];
- address vault = delegationInfo_.vault;
- IDelegationRegistry.DelegationType type_ = delegationInfo_.type_;
- bool valid = false;
- if (type_ == IDelegationRegistry.DelegationType.ALL) {
- if (delegateHash == _computeAllDelegationHash(vault, delegate)) {
- valid = true;
- }
- } else if (type_ == IDelegationRegistry.DelegationType.CONTRACT) {
- if (delegateHash == _computeContractDelegationHash(vault, delegate, delegationInfo_.contract_)) {
- valid = true;
- }
- } else if (type_ == IDelegationRegistry.DelegationType.TOKEN) {
- if (
- delegateHash
- == _computeTokenDelegationHash(vault, delegate, delegationInfo_.contract_, delegationInfo_.tokenId)
- ) {
- valid = true;
- }
- }
- if (valid) {
- info[delegationCount++] = delegationInfo_;
- }
- unchecked {
- ++i;
- }
- }
- if (potentialDelegationHashesLength > delegationCount) {
- assembly {
- let decrease := sub(potentialDelegationHashesLength, delegationCount)
- mstore(info, sub(mload(info), decrease))
- }
- }
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getDelegatesForAll(address vault) external view returns (address[] memory delegates) {
- return _getDelegatesForLevel(vault, IDelegationRegistry.DelegationType.ALL, address(0), 0);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getDelegatesForContract(address vault, address contract_)
- external
- view
- override
- returns (address[] memory delegates)
- {
- return _getDelegatesForLevel(vault, IDelegationRegistry.DelegationType.CONTRACT, contract_, 0);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getDelegatesForToken(address vault, address contract_, uint256 tokenId)
- external
- view
- override
- returns (address[] memory delegates)
- {
- return _getDelegatesForLevel(vault, IDelegationRegistry.DelegationType.TOKEN, contract_, tokenId);
- }
-
- function _getDelegatesForLevel(
- address vault,
- IDelegationRegistry.DelegationType delegationType,
- address contract_,
- uint256 tokenId
- )
- internal
- view
- returns (address[] memory delegates)
- {
- EnumerableSet.Bytes32Set storage delegationHashes_ = delegations[vault][vaultVersion[vault]];
- uint256 potentialDelegatesLength = delegationHashes_.length();
- uint256 delegatesCount = 0;
- delegates = new address[](potentialDelegatesLength);
- for (uint256 i = 0; i < potentialDelegatesLength;) {
- bytes32 delegationHash = delegationHashes_.at(i);
- DelegationInfo storage delegationInfo_ = delegationInfo[delegationHash];
- if (delegationInfo_.type_ == delegationType) {
- if (delegationType == IDelegationRegistry.DelegationType.ALL) {
- // check delegate version by validating the hash
- if (delegationHash == _computeAllDelegationHash(vault, delegationInfo_.delegate)) {
- delegates[delegatesCount++] = delegationInfo_.delegate;
- }
- } else if (delegationType == IDelegationRegistry.DelegationType.CONTRACT) {
- if (delegationInfo_.contract_ == contract_) {
- // check delegate version by validating the hash
- if (
- delegationHash == _computeContractDelegationHash(vault, delegationInfo_.delegate, contract_)
- ) {
- delegates[delegatesCount++] = delegationInfo_.delegate;
- }
- }
- } else if (delegationType == IDelegationRegistry.DelegationType.TOKEN) {
- if (delegationInfo_.contract_ == contract_ && delegationInfo_.tokenId == tokenId) {
- // check delegate version by validating the hash
- if (
- delegationHash
- == _computeTokenDelegationHash(vault, delegationInfo_.delegate, contract_, tokenId)
- ) {
- delegates[delegatesCount++] = delegationInfo_.delegate;
- }
- }
- }
- }
- unchecked {
- ++i;
- }
- }
- if (potentialDelegatesLength > delegatesCount) {
- assembly {
- let decrease := sub(potentialDelegatesLength, delegatesCount)
- mstore(delegates, sub(mload(delegates), decrease))
- }
- }
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getContractLevelDelegations(address vault)
- external
- view
- returns (IDelegationRegistry.ContractDelegation[] memory contractDelegations)
- {
- EnumerableSet.Bytes32Set storage delegationHashes_ = delegations[vault][vaultVersion[vault]];
- uint256 potentialLength = delegationHashes_.length();
- uint256 delegationCount = 0;
- contractDelegations = new IDelegationRegistry.ContractDelegation[](potentialLength);
- for (uint256 i = 0; i < potentialLength;) {
- bytes32 delegationHash = delegationHashes_.at(i);
- DelegationInfo storage delegationInfo_ = delegationInfo[delegationHash];
- if (delegationInfo_.type_ == IDelegationRegistry.DelegationType.CONTRACT) {
- // check delegate version by validating the hash
- if (
- delegationHash
- == _computeContractDelegationHash(vault, delegationInfo_.delegate, delegationInfo_.contract_)
- ) {
- contractDelegations[delegationCount++] = IDelegationRegistry.ContractDelegation({
- contract_: delegationInfo_.contract_,
- delegate: delegationInfo_.delegate
- });
- }
- }
- unchecked {
- ++i;
- }
- }
- if (potentialLength > delegationCount) {
- assembly {
- let decrease := sub(potentialLength, delegationCount)
- mstore(contractDelegations, sub(mload(contractDelegations), decrease))
- }
- }
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function getTokenLevelDelegations(address vault)
- external
- view
- returns (IDelegationRegistry.TokenDelegation[] memory tokenDelegations)
- {
- EnumerableSet.Bytes32Set storage delegationHashes_ = delegations[vault][vaultVersion[vault]];
- uint256 potentialLength = delegationHashes_.length();
- uint256 delegationCount = 0;
- tokenDelegations = new IDelegationRegistry.TokenDelegation[](potentialLength);
- for (uint256 i = 0; i < potentialLength;) {
- bytes32 delegationHash = delegationHashes_.at(i);
- DelegationInfo storage delegationInfo_ = delegationInfo[delegationHash];
- if (delegationInfo_.type_ == IDelegationRegistry.DelegationType.TOKEN) {
- // check delegate version by validating the hash
- if (
- delegationHash
- == _computeTokenDelegationHash(
- vault, delegationInfo_.delegate, delegationInfo_.contract_, delegationInfo_.tokenId
- )
- ) {
- tokenDelegations[delegationCount++] = IDelegationRegistry.TokenDelegation({
- contract_: delegationInfo_.contract_,
- tokenId: delegationInfo_.tokenId,
- delegate: delegationInfo_.delegate
- });
- }
- }
- unchecked {
- ++i;
- }
- }
- if (potentialLength > delegationCount) {
- assembly {
- let decrease := sub(potentialLength, delegationCount)
- mstore(tokenDelegations, sub(mload(tokenDelegations), decrease))
- }
- }
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function checkDelegateForAll(address delegate, address vault) public view override returns (bool) {
- bytes32 delegateHash =
- keccak256(abi.encode(delegate, vault, vaultVersion[vault], delegateVersion[vault][delegate]));
- return delegations[vault][vaultVersion[vault]].contains(delegateHash);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function checkDelegateForContract(address delegate, address vault, address contract_)
- public
- view
- override
- returns (bool)
- {
- bytes32 delegateHash =
- keccak256(abi.encode(delegate, vault, contract_, vaultVersion[vault], delegateVersion[vault][delegate]));
- return
- delegations[vault][vaultVersion[vault]].contains(delegateHash)
- ? true
- : checkDelegateForAll(delegate, vault);
- }
-
- /**
- * @inheritdoc IDelegationRegistry
- */
- function checkDelegateForToken(address delegate, address vault, address contract_, uint256 tokenId)
- public
- view
- override
- returns (bool)
- {
- bytes32 delegateHash = keccak256(
- abi.encode(delegate, vault, contract_, tokenId, vaultVersion[vault], delegateVersion[vault][delegate])
- );
- return
- delegations[vault][vaultVersion[vault]].contains(delegateHash)
- ? true
- : checkDelegateForContract(delegate, vault, contract_);
- }
-}
diff --git a/assets/eip-5639/IDelegationRegistry.sol b/assets/eip-5639/IDelegationRegistry.sol
deleted file mode 100644
index bbdcb41..0000000
--- a/assets/eip-5639/IDelegationRegistry.sol
+++ /dev/null
@@ -1,184 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/**
- * @title An immutable registry contract to be deployed as a standalone primitive
- * @dev New project launches can read previous cold wallet -> hot wallet delegations
- * from here and integrate those permissions into their flow
- */
-interface IDelegationRegistry {
- /// @notice Delegation type
- enum DelegationType {
- NONE,
- ALL,
- CONTRACT,
- TOKEN
- }
-
- /// @notice Info about a single delegation, used for onchain enumeration
- struct DelegationInfo {
- DelegationType type_;
- address vault;
- address delegate;
- address contract_;
- uint256 tokenId;
- }
-
- /// @notice Info about a single contract-level delegation
- struct ContractDelegation {
- address contract_;
- address delegate;
- }
-
- /// @notice Info about a single token-level delegation
- struct TokenDelegation {
- address contract_;
- uint256 tokenId;
- address delegate;
- }
-
- /// @notice Emitted when a user delegates their entire wallet
- event DelegateForAll(address vault, address delegate, bool value);
-
- /// @notice Emitted when a user delegates a specific contract
- event DelegateForContract(address vault, address delegate, address contract_, bool value);
-
- /// @notice Emitted when a user delegates a specific token
- event DelegateForToken(address vault, address delegate, address contract_, uint256 tokenId, bool value);
-
- /// @notice Emitted when a user revokes all delegations
- event RevokeAllDelegates(address vault);
-
- /// @notice Emitted when a user revoes all delegations for a given delegate
- event RevokeDelegate(address vault, address delegate);
-
- /**
- * ----------- WRITE -----------
- */
-
- /**
- * @notice Allow the delegate to act on your behalf for all contracts
- * @param delegate The hotwallet to act on your behalf
- * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking
- */
- function delegateForAll(address delegate, bool value) external;
-
- /**
- * @notice Allow the delegate to act on your behalf for a specific contract
- * @param delegate The hotwallet to act on your behalf
- * @param contract_ The address for the contract you're delegating
- * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking
- */
- function delegateForContract(address delegate, address contract_, bool value) external;
-
- /**
- * @notice Allow the delegate to act on your behalf for a specific token
- * @param delegate The hotwallet to act on your behalf
- * @param contract_ The address for the contract you're delegating
- * @param tokenId The token id for the token you're delegating
- * @param value Whether to enable or disable delegation for this address, true for setting and false for revoking
- */
- function delegateForToken(address delegate, address contract_, uint256 tokenId, bool value) external;
-
- /**
- * @notice Revoke all delegates
- */
- function revokeAllDelegates() external;
-
- /**
- * @notice Revoke a specific delegate for all their permissions
- * @param delegate The hotwallet to revoke
- */
- function revokeDelegate(address delegate) external;
-
- /**
- * @notice Remove yourself as a delegate for a specific vault
- * @param vault The vault which delegated to the msg.sender, and should be removed
- */
- function revokeSelf(address vault) external;
-
- /**
- * ----------- READ -----------
- */
-
- /**
- * @notice Returns all active delegations a given delegate is able to claim on behalf of
- * @param delegate The delegate that you would like to retrieve delegations for
- * @return info Array of DelegationInfo structs
- */
- function getDelegationsByDelegate(address delegate) external view returns (DelegationInfo[] memory);
-
- /**
- * @notice Returns an array of wallet-level delegates for a given vault
- * @param vault The cold wallet who issued the delegation
- * @return addresses Array of wallet-level delegates for a given vault
- */
- function getDelegatesForAll(address vault) external view returns (address[] memory);
-
- /**
- * @notice Returns an array of contract-level delegates for a given vault and contract
- * @param vault The cold wallet who issued the delegation
- * @param contract_ The address for the contract you're delegating
- * @return addresses Array of contract-level delegates for a given vault and contract
- */
- function getDelegatesForContract(address vault, address contract_) external view returns (address[] memory);
-
- /**
- * @notice Returns an array of contract-level delegates for a given vault's token
- * @param vault The cold wallet who issued the delegation
- * @param contract_ The address for the contract holding the token
- * @param tokenId The token id for the token you're delegating
- * @return addresses Array of contract-level delegates for a given vault's token
- */
- function getDelegatesForToken(address vault, address contract_, uint256 tokenId)
- external
- view
- returns (address[] memory);
-
- /**
- * @notice Returns all contract-level delegations for a given vault
- * @param vault The cold wallet who issued the delegations
- * @return delegations Array of ContractDelegation structs
- */
- function getContractLevelDelegations(address vault)
- external
- view
- returns (ContractDelegation[] memory delegations);
-
- /**
- * @notice Returns all token-level delegations for a given vault
- * @param vault The cold wallet who issued the delegations
- * @return delegations Array of TokenDelegation structs
- */
- function getTokenLevelDelegations(address vault) external view returns (TokenDelegation[] memory delegations);
-
- /**
- * @notice Returns true if the address is delegated to act on the entire vault
- * @param delegate The hotwallet to act on your behalf
- * @param vault The cold wallet who issued the delegation
- */
- function checkDelegateForAll(address delegate, address vault) external view returns (bool);
-
- /**
- * @notice Returns true if the address is delegated to act on your behalf for a token contract or an entire vault
- * @param delegate The hotwallet to act on your behalf
- * @param contract_ The address for the contract you're delegating
- * @param vault The cold wallet who issued the delegation
- */
- function checkDelegateForContract(address delegate, address vault, address contract_)
- external
- view
- returns (bool);
-
- /**
- * @notice Returns true if the address is delegated to act on your behalf for a specific token, the token's contract or an entire vault
- * @param delegate The hotwallet to act on your behalf
- * @param contract_ The address for the contract you're delegating
- * @param tokenId The token id for the token you're delegating
- * @param vault The cold wallet who issued the delegation
- */
- function checkDelegateForToken(address delegate, address vault, address contract_, uint256 tokenId)
- external
- view
- returns (bool);
-}
diff --git a/assets/eip-5646/support-per-abi.png b/assets/eip-5646/support-per-abi.png
deleted file mode 100644
index d9efc72..0000000
Binary files a/assets/eip-5646/support-per-abi.png and /dev/null differ
diff --git a/assets/eip-5646/support-per-eip.png b/assets/eip-5646/support-per-eip.png
deleted file mode 100644
index b985faa..0000000
Binary files a/assets/eip-5646/support-per-eip.png and /dev/null differ
diff --git a/assets/eip-5700/erc1155/ERC1155.sol b/assets/eip-5700/erc1155/ERC1155.sol
deleted file mode 100644
index 652ebb7..0000000
--- a/assets/eip-5700/erc1155/ERC1155.sol
+++ /dev/null
@@ -1,192 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
-
-import {IERC1155Errors} from "../interfaces/IERC1155Errors.sol";
-
-/// @title Dopamine Minimal ERC-1155 Contract
-/// @notice This is a minimal ERC-1155 implementation that
-contract ERC1155 is IERC1155, IERC1155Errors {
-
- /// @notice Checks for an owner if an address is an authorized operator.
- mapping(address => mapping(address => bool)) public isApprovedForAll;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC1155_INTERFACE_ID = 0xd9b67a26;
-
- /// @notice Gets an address' number of tokens owned of a specific type.
- mapping(address => mapping(uint256 => uint256)) public _balanceOf;
-
- /// @notice Transfers `amount` tokens of id `id` from address `from` to
- /// address `to`, while ensuring `to` is capable of receiving the token.
- /// @dev Safety checks are only performed if `to` is a smart contract.
- /// @param from The existing owner address of the token to be transferred.
- /// @param to The new owner address of the token being transferred.
- /// @param id The id of the token being transferred.
- /// @param amount The number of tokens being transferred.
- /// @param data Additional transfer data to pass to the receiving contract.
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes memory data
- ) public virtual {
- if (msg.sender != from && !isApprovedForAll[from][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- _balanceOf[from][id] -= amount;
- _balanceOf[to][id] += amount;
-
- emit TransferSingle(msg.sender, from, to, id, amount);
-
- if (
- to.code.length != 0 &&
- IERC1155Receiver(to).onERC1155Received(
- msg.sender,
- address(0),
- id,
- amount,
- data
- ) !=
- IERC1155Receiver.onERC1155Received.selector
- ) {
- revert SafeTransferUnsupported();
- } else if (to == address(0)) {
- revert ReceiverInvalid();
- }
- }
-
- /// @notice Transfers tokens `ids` in corresponding batches `amounts` from
- /// address `from` to address `to`, while ensuring `to` can receive tokens.
- /// @dev Safety checks are only performed if `to` is a smart contract.
- /// @param from The existing owner address of the token to be transferred.
- /// @param to The new owner address of the token being transferred.
- /// @param ids A list of the token ids being transferred.
- /// @param amounts A list of the amounts of each token id being transferred.
- /// @param data Additional transfer data to pass to the receiving contract.
- function safeBatchTransferFrom(
- address from,
- address to,
- uint256[] memory ids,
- uint256[] memory amounts,
- bytes memory data
- ) public virtual {
- if (ids.length != amounts.length) {
- revert ArityMismatch();
- }
-
- if (msg.sender != from && !isApprovedForAll[from][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- uint256 id;
- uint256 amount;
-
- for (uint256 i = 0; i < ids.length; ) {
- id = ids[i];
- amount = amounts[i];
- _balanceOf[from][id] -= amount;
- _balanceOf[to][id] += amount;
- unchecked {
- ++i;
- }
- }
-
- emit TransferBatch(msg.sender, from, to, ids, amounts);
-
- if (
- to.code.length != 0 &&
- IERC1155Receiver(to).onERC1155BatchReceived(
- msg.sender,
- from,
- ids,
- amounts,
- data
- ) !=
- IERC1155Receiver.onERC1155BatchReceived.selector
- ) {
- revert SafeTransferUnsupported();
- } else if (to == address(0)) {
- revert ReceiverInvalid();
- }
- }
-
- /// @notice Retrieves balance of address `owner` for token of id `id`.
- /// @param owner The token owner's address.
- /// @param id The id of the token being queried.
- /// @return The number of tokens address `owner` owns of type `id`.
- function balanceOf(address owner, uint256 id) public view virtual returns (uint256) {
- return _balanceOf[owner][id];
- }
-
- /// @notice Retrieves balances of multiple owner / token type pairs.
- /// @param owners List of token owner addresses.
- /// @param ids List of token type identifiers.
- /// @return balances List of balances corresponding to the owner / id pairs.
- function balanceOfBatch(address[] memory owners, uint256[] memory ids)
- public
- view
- virtual
- returns (uint256[] memory balances)
- {
- if (owners.length != ids.length) {
- revert ArityMismatch();
- }
-
- balances = new uint256[](owners.length);
-
- unchecked {
- for (uint256 i = 0; i < owners.length; ++i) {
- balances[i] = _balanceOf[owners[i]][ids[i]];
- }
- }
- }
-
- /// @notice Sets the operator for the sender address.
- function setApprovalForAll(address operator, bool approved) public virtual {
- isApprovedForAll[msg.sender][operator] = approved;
- }
-
- /// @notice Checks if interface of identifier `id` is supported.
- /// @param id The ERC-165 interface identifier.
- /// @return True if interface id `id` is supported, False otherwise.
- function supportsInterface(bytes4 id) public pure virtual returns (bool) {
- return
- id == _ERC165_INTERFACE_ID ||
- id == _ERC1155_INTERFACE_ID;
- }
-
- /// @notice Mints token of id `id` to address `to`.
- /// @param to Address receiving the minted NFT.
- /// @param id The id of the token type being minted.
- function _mint(address to, uint256 id) internal virtual {
- unchecked {
- ++_balanceOf[to][id];
- }
-
- emit TransferSingle(msg.sender, address(0), to, id, 1);
-
- if (
- to.code.length != 0 &&
- IERC1155Receiver(to).onERC1155Received(
- msg.sender,
- address(0),
- id,
- 1,
- ""
- ) !=
- IERC1155Receiver.onERC1155Received.selector
- ) {
- revert SafeTransferUnsupported();
- } else if (to == address(0)) {
- revert ReceiverInvalid();
- }
- }
-
-}
-
diff --git a/assets/eip-5700/erc1155/ERC1155Bindable.sol b/assets/eip-5700/erc1155/ERC1155Bindable.sol
deleted file mode 100644
index d7615a2..0000000
--- a/assets/eip-5700/erc1155/ERC1155Bindable.sol
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import {IERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";
-
-import {ERC1155} from "./ERC1155.sol";
-import {IERC1155Bindable} from "../interfaces/IERC1155Bindable.sol";
-import {IERC1155Binder} from "../interfaces/IERC1155Binder.sol";
-
-/// @title ERC-1155 Bindable Reference Implementation.
-/// @dev Only supports the "delegated" binding mode.
-contract ERC1155Bindable is ERC1155, IERC1155Bindable {
-
- /// @notice Tracks the bound balance of an asset for a specific token type.
- mapping(address => mapping(uint256 => mapping(uint256 => uint256))) public boundBalanceOf;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC1155_BINDER_INTERFACE_ID = 0x2ac2d2bc;
- bytes4 private constant _ERC1155_BINDABLE_INTERFACE_ID = 0xd92c3ff0;
-
- /// @inheritdoc IERC1155Bindable
- function boundBalanceOfBatch(
- address bindAddress,
- uint256[] calldata bindIds,
- uint256[] calldata tokenIds
- ) public view returns (uint256[] memory balances) {
- if (bindIds.length != tokenIds.length) {
- revert ArityMismatch();
- }
-
- balances = new uint256[](bindIds.length);
-
- unchecked {
- for (uint256 i = 0; i < bindIds.length; ++i) {
- balances[i] = boundBalanceOf[bindAddress][bindIds[i]][tokenIds[i]];
- }
- }
- }
-
- /// @inheritdoc IERC1155Bindable
- function bind(
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) public {
- if (msg.sender != from && !isApprovedForAll[from][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- IERC1155Binder binder = IERC1155Binder(bindAddress);
- if (to != bindAddress) {
- revert BinderInvalid();
- }
-
- boundBalanceOf[bindAddress][bindId][tokenId] += amount;
- _balanceOf[from][tokenId] -= amount;
- _balanceOf[to][tokenId] += amount;
-
- emit Bind(msg.sender, from, bindAddress, tokenId, amount, bindId, bindAddress);
- emit TransferSingle(msg.sender, from, bindAddress, tokenId, amount);
-
- if (
- binder.onERC1155Bind(msg.sender, from, to, tokenId, amount, bindId, data)
- !=
- IERC1155Binder.onERC1155Bind.selector
- ) {
- revert BindInvalid();
- }
-
- }
-
- /// @inheritdoc IERC1155Bindable
- function batchBind(
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- address bindAddress,
- bytes calldata data
- ) public {
- if (msg.sender != from && !isApprovedForAll[from][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- IERC1155Binder binder = IERC1155Binder(bindAddress);
- if (to != bindAddress) {
- revert BinderInvalid();
- }
-
- if (tokenIds.length != amounts.length || tokenIds.length != bindIds.length) {
- revert ArityMismatch();
- }
-
- for (uint256 i = 0; i < tokenIds.length; i++) {
-
- boundBalanceOf[bindAddress][bindIds[i]][tokenIds[i]] += amounts[i];
- _balanceOf[from][tokenIds[i]] -= amounts[i];
- _balanceOf[to][tokenIds[i]] += amounts[i];
- }
-
- emit BindBatch(msg.sender, from, bindAddress, tokenIds, amounts, bindIds, bindAddress);
- emit TransferBatch(msg.sender, from, bindAddress, tokenIds, amounts);
-
- if (
- binder.onERC1155BatchBind(msg.sender, from, to, tokenIds, amounts, bindIds, data)
- !=
- IERC1155Binder.onERC1155Bind.selector
- ) {
- revert BindInvalid();
- }
-
- }
-
- /// @inheritdoc IERC1155Bindable
- function unbind(
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) public {
- IERC1155Binder binder = IERC1155Binder(bindAddress);
- if (
- binder.ownerOf(bindId) != from
- ) {
- revert BinderInvalid();
- }
-
- if (
- msg.sender != from &&
- !binder.isApprovedForAll(from, msg.sender)
- ) {
- revert SenderUnauthorized();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- _balanceOf[to][tokenId] += amount;
- _balanceOf[from][tokenId] -= amount;
- boundBalanceOf[bindAddress][bindId][tokenId] -= amount;
-
- emit Bind(msg.sender, bindAddress, to, tokenId, amount, bindId, bindAddress);
- emit TransferSingle(msg.sender, bindAddress, to, tokenId, amount);
-
- if (
- binder.onERC1155Unbind(msg.sender, from, to, tokenId, amount, bindId, data)
- !=
- IERC1155Binder.onERC1155Unbind.selector
- ) {
- revert BindInvalid();
- }
-
- if (
- to.code.length != 0 &&
- IERC1155Receiver(to).onERC1155Received(msg.sender, from, amount, tokenId, "")
- !=
- IERC1155Receiver.onERC1155Received.selector
- ) {
- revert SafeTransferUnsupported();
- }
-
- }
-
- /// @inheritdoc IERC1155Bindable
- function batchUnbind(
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- address bindAddress,
- bytes calldata data
- ) public {
- IERC1155Binder binder = IERC1155Binder(bindAddress);
-
- if (
- msg.sender != from &&
- !binder.isApprovedForAll(from, msg.sender)
- ) {
- revert SenderUnauthorized();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- if (tokenIds.length != amounts.length || tokenIds.length != bindIds.length) {
- revert ArityMismatch();
- }
-
- for (uint256 i = 0; i < tokenIds.length; i++) {
-
- if (binder.ownerOf(bindIds[i]) != from) {
- revert BinderInvalid();
- }
-
- _balanceOf[to][tokenIds[i]] += amounts[i];
- _balanceOf[from][tokenIds[i]] -= amounts[i];
- boundBalanceOf[bindAddress][bindIds[i]][tokenIds[i]] -= amounts[i];
- }
-
- emit UnbindBatch(msg.sender, from, bindAddress, tokenIds, amounts, bindIds, bindAddress);
- emit TransferBatch(msg.sender, from, bindAddress, tokenIds, amounts);
-
- if (
- binder.onERC1155BatchUnbind(msg.sender, from, to, tokenIds, amounts, bindIds, data)
- !=
- IERC1155Binder.onERC1155BatchUnbind.selector
- ) {
- revert BindInvalid();
- }
-
- if (
- to.code.length != 0 &&
- IERC1155Receiver(to).onERC1155BatchReceived(msg.sender, from, tokenIds, amounts, "")
- !=
- IERC1155Receiver.onERC1155BatchReceived.selector
- ) {
- revert SafeTransferUnsupported();
- }
- }
-
-
- function supportsInterface(bytes4 id) public pure override(ERC1155, IERC165) returns (bool) {
- return super.supportsInterface(id) || id == _ERC1155_BINDABLE_INTERFACE_ID;
- }
-
-}
diff --git a/assets/eip-5700/erc1155/ERC1155Binder.sol b/assets/eip-5700/erc1155/ERC1155Binder.sol
deleted file mode 100644
index 2ac1dcb..0000000
--- a/assets/eip-5700/erc1155/ERC1155Binder.sol
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-
-import {IERC1155Bindable} from "../interfaces/IERC1155Bindable.sol";
-import {IERC1155Binder} from "../interfaces/IERC1155Binder.sol";
-
-/// @title ERC-1155 Binder Reference Implementation
-contract ERC1155Binder is IERC1155Binder {
-
- struct Bindable {
- address tokenAddress;
- uint256 tokenId;
- }
-
- /// @notice Checks for an owner if an address is an authorized operator.
- mapping(address => mapping(address => bool)) public _isApprovedForAll;
-
- /// @notice Tracks ownership of bound assets.
- mapping(uint256 => address) _ownerOf;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC1155_BINDER_INTERFACE_ID = 0x2ac2d2bc;
- bytes4 private constant _ERC1155_BINDABLE_INTERFACE_ID = 0xd92c3ff0;
-
- /// @inheritdoc IERC1155Binder
- function isApprovedForAll(address owner, address operator) external view override returns (bool) {
- return _isApprovedForAll[owner][operator];
- }
-
- /// @inheritdoc IERC1155Binder
- function ownerOf(uint256 id) public view returns (address) {
- return _ownerOf[id];
- }
-
- /// @inheritdoc IERC1155Binder
- function onERC1155Bind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- bytes calldata data
- ) public returns (bytes4) {
- return IERC1155Binder.onERC1155Bind.selector;
- }
-
- /// @inheritdoc IERC1155Binder
- function onERC1155BatchBind(
- address operator,
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- bytes calldata data
- ) public returns (bytes4) {
- return IERC1155Binder.onERC1155BatchBind.selector;
- }
-
- /// @inheritdoc IERC1155Binder
- function onERC1155Unbind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- bytes calldata data
- ) public returns (bytes4) {
- return IERC1155Binder.onERC1155Unbind.selector;
- }
-
- /// @inheritdoc IERC1155Binder
- function onERC1155BatchUnbind(
- address operator,
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- bytes calldata data
- ) public returns (bytes4) {
- return IERC1155Binder.onERC1155BatchUnbind.selector;
- }
-
- function supportsInterface(bytes4 id) external pure returns (bool) {
- return id == _ERC165_INTERFACE_ID || id == _ERC1155_BINDER_INTERFACE_ID;
- }
-
- /// @notice Mints a new asset identified by `id` to address `to`.
- function _mint(address to, uint256 id) internal {
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- if (_ownerOf[id] != address(0)) {
- revert AssetAlreadyMinted();
- }
-
- _ownerOf[id] = to;
- }
-
-}
diff --git a/assets/eip-5700/erc721/ERC721.sol b/assets/eip-5700/erc721/ERC721.sol
deleted file mode 100644
index c3f50d9..0000000
--- a/assets/eip-5700/erc721/ERC721.sol
+++ /dev/null
@@ -1,232 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
-
-import {IERC721Errors} from "../interfaces/IERC721Errors.sol";
-
-/// @title Reference Minimal ERC-721 Contract
-contract ERC721 is IERC721, IERC721Errors {
-
- /// @notice The total number of NFTs in circulation.
- uint256 public totalSupply;
-
- /// @notice Gets the approved address for an NFT.
- /// @dev This implementation does not throw for zero-address queries.
- mapping(uint256 => address) public getApproved;
-
- /// @notice Gets the number of NFTs owned by an address.
- mapping(address => uint256) internal _balanceOf;
-
- /// @dev Tracks the assigned owner of an address.
- mapping(uint256 => address) internal _ownerOf;
-
- /// @dev Checks for an owner if an address is an authorized operator.
- mapping(address => mapping(address => bool)) internal _operatorApprovals;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC721_INTERFACE_ID = 0x80ac58cd;
-
- /// @notice Gets the assigned owner for token `id`.
- /// @param id The id of the NFT being queried.
- /// @return The address of the owner of the NFT of id `id`.
- function ownerOf(uint256 id) external view virtual returns (address) {
- return _ownerOf[id];
- }
-
- /// @notice Gets number of NFTs owned by address `owner`.
- /// @param owner The address whose balance is being queried.
- /// @return The number of NFTs owned by address `owner`.
- function balanceOf(address owner) external view virtual returns (uint256) {
- return _balanceOf[owner];
- }
-
- /// @notice Sets approved address of NFT of id `id` to address `approved`.
- /// @param approved The new approved address for the NFT.
- /// @param id The id of the NFT to approve.
- function approve(address approved, uint256 id) external virtual {
- address owner = _ownerOf[id];
-
- if (msg.sender != owner && !_operatorApprovals[owner][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- getApproved[id] = approved;
- emit Approval(owner, approved, id);
- }
-
- /// @notice Checks if `operator` is an authorized operator for `owner`.
- /// @param owner The address of the owner.
- /// @param operator The address of the owner's operator.
- /// @return True if `operator` is approved operator of `owner`, else False.
- function isApprovedForAll(address owner, address operator)
- external
- view
- virtual returns (bool)
- {
- return _operatorApprovals[owner][operator];
- }
-
- /// @notice Sets the operator for `msg.sender` to `operator`.
- /// @param operator The operator address that will manage the sender's NFTs.
- /// @param approved Whether operator is allowed to operate sender's NFTs.
- function setApprovalForAll(address operator, bool approved) external virtual {
- _operatorApprovals[msg.sender][operator] = approved;
- emit ApprovalForAll(msg.sender, operator, approved);
- }
-
- /// @notice Checks if interface of identifier `id` is supported.
- /// @param id The ERC-165 interface identifier.
- /// @return True if interface id `id` is supported, false otherwise.
- function supportsInterface(bytes4 id) public pure virtual returns (bool) {
- return
- id == _ERC165_INTERFACE_ID ||
- id == _ERC721_INTERFACE_ID;
- }
-
- /// @notice Transfers NFT of id `id` from address `from` to address `to`,
- /// with safety checks ensuring `to` is capable of receiving the NFT.
- /// @dev Safety checks are only performed if `to` is a smart contract.
- /// @param from The existing owner address of the NFT to be transferred.
- /// @param to The new owner address of the NFT being transferred.
- /// @param id The id of the NFT being transferred.
- /// @param data Additional transfer data to pass to the receiving contract.
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- bytes memory data
- ) public virtual {
- transferFrom(from, to, id);
-
- if (
- to.code.length != 0 &&
- IERC721Receiver(to).onERC721Received(msg.sender, from, id, data)
- !=
- IERC721Receiver.onERC721Received.selector
- ) {
- revert SafeTransferUnsupported();
- }
- }
-
- /// @notice Transfers NFT of id `id` from address `from` to address `to`,
- /// with safety checks ensuring `to` is capable of receiving the NFT.
- /// @dev Safety checks are only performed if `to` is a smart contract.
- /// @param from The existing owner address of the NFT to be transferred.
- /// @param to The new owner address of the NFT being transferred.
- /// @param id The id of the NFT being transferred.
- function safeTransferFrom(
- address from,
- address to,
- uint256 id
- ) public virtual {
- transferFrom(from, to, id);
-
- if (
- to.code.length != 0 &&
- IERC721Receiver(to).onERC721Received(msg.sender, from, id, "")
- !=
- IERC721Receiver.onERC721Received.selector
- ) {
- revert SafeTransferUnsupported();
- }
- }
-
- /// @notice Transfers NFT of id `id` from address `from` to address `to`,
- /// without performing any safety checks.
- /// @dev Existence of an NFT is inferred by having a non-zero owner address.
- /// Transfers clear owner approvals, but `Approval` events are omitted.
- /// @param from The existing owner address of the NFT being transferred.
- /// @param to The new owner address of the NFT being transferred.
- /// @param id The id of the NFT being transferred.
- function transferFrom(
- address from,
- address to,
- uint256 id
- ) public virtual {
- if (from != _ownerOf[id]) {
- revert OwnerInvalid();
- }
-
- if (
- msg.sender != from &&
- msg.sender != getApproved[id] &&
- !_operatorApprovals[from][msg.sender]
- ) {
- revert SenderUnauthorized();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- _beforeTokenTransfer(from, to, id);
-
- delete getApproved[id];
-
- unchecked {
- _balanceOf[from]--;
- _balanceOf[to]++;
- }
-
- _ownerOf[id] = to;
- emit Transfer(from, to, id);
- }
-
- /// @dev Mints NFT of id `id` to address `to`. To save gas, it is assumed
- /// that `maxSupply` < `type(uint256).max` (ex. for tabs, cap is very low).
- /// @param to Address receiving the minted NFT.
- /// @param id Identifier of the NFT being minted.
- /// @return The id of the minted NFT.
- function _mint(address to, uint256 id) internal virtual returns (uint256) {
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
- if (_ownerOf[id] != address(0)) {
- revert TokenAlreadyMinted();
- }
-
- _beforeTokenTransfer(address(0), to, id);
-
- unchecked {
- totalSupply++;
- _balanceOf[to]++;
- }
-
- _ownerOf[id] = to;
- emit Transfer(address(0), to, id);
- return id;
- }
-
- /// @dev Burns NFT of id `id`, removing it from existence.
- /// @param id Identifier of the NFT being burned
- function _burn(uint256 id) internal virtual {
- address owner = _ownerOf[id];
-
- if (owner == address(0)) {
- revert TokenNonExistent();
- }
-
- _beforeTokenTransfer(owner, address(0), id);
-
- unchecked {
- totalSupply--;
- _balanceOf[owner]--;
- }
-
- delete _ownerOf[id];
- emit Transfer(owner, address(0), id);
- }
-
- /// @notice Pre-transfer hook for embedding additional transfer behavior.
- /// @param from The address of the existing owner of the NFT.
- /// @param to The address of the new owner of the NFT.
- /// @param id The id of the NFT being transferred.
- function _beforeTokenTransfer(address from, address to, uint256 id)
- internal
- virtual
- {}
-
-}
diff --git a/assets/eip-5700/erc721/ERC721Bindable.sol b/assets/eip-5700/erc721/ERC721Bindable.sol
deleted file mode 100644
index d772721..0000000
--- a/assets/eip-5700/erc721/ERC721Bindable.sol
+++ /dev/null
@@ -1,210 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
-
-import {ERC721} from "./ERC721.sol";
-import {IERC721Bindable} from "../interfaces/IERC721Bindable.sol";
-import {IERC721Binder} from "../interfaces/IERC721Binder.sol";
-
-/// @title ERC-721 Bindable Reference Implementation.
-/// @dev Supports both "legacy" and "delegated" binding modes.
-contract ERC721Bindable is ERC721, IERC721Bindable {
-
- /// @notice Encapsulates a bound asset contract address and identifier.
- struct Binder {
- address bindAddress;
- uint256 bindId;
- }
-
- /// @notice Tracks the bound balance of a specific asset.
- mapping(address => mapping(uint256 => uint256)) public boundBalanceOf;
-
- /// @notice Tracks bound assets of an NFT.
- mapping(uint256 => Binder) internal _bound;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC721_BINDER_INTERFACE_ID = 0x2ac2d2bc;
- bytes4 private constant _ERC721_BINDABLE_INTERFACE_ID = 0xd92c3ff0;
-
- /// @inheritdoc IERC721Bindable
- function binderOf(uint256 tokenId) public returns (address, uint256) {
- Binder memory bound = _bound[tokenId];
- return (bound.bindAddress, bound.bindId);
- }
-
- /// @inheritdoc IERC721Bindable
- function bind(
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) public {
- if (_bound[tokenId].bindAddress != address(0)) {
- revert BindExistent();
- }
-
- if (from != _ownerOf[tokenId]) {
- revert OwnerInvalid();
- }
-
- IERC721Binder binder = IERC721Binder(bindAddress);
- address assetOwner = binder.ownerOf(bindId);
- if (to != assetOwner && to != bindAddress) {
- revert BinderInvalid();
- }
-
- if (
- msg.sender != from &&
- msg.sender != getApproved[tokenId] &&
- !_operatorApprovals[from][msg.sender]
- ) {
- revert SenderUnauthorized();
- }
-
- delete getApproved[tokenId];
-
- unchecked {
- _balanceOf[from]--;
- _balanceOf[bindAddress]++;
- _balanceOf[assetOwner]++;
- boundBalanceOf[bindAddress][bindId]++;
- }
-
- _ownerOf[tokenId] = to;
- _bound[tokenId] = Binder(bindAddress, bindId);
-
- emit Bind(msg.sender, from, to, tokenId, bindId, bindAddress);
- emit Transfer(from, to, tokenId);
-
- if (
- binder.onERC721Bind(msg.sender, from, to, tokenId, bindId, "")
- !=
- IERC721Binder.onERC721Bind.selector
- ) {
- revert BindInvalid();
- }
-
- }
-
- /// @inheritdoc IERC721Bindable
- function unbind(
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) public {
- Binder memory bound = _bound[tokenId];
- if (bound.bindAddress != address(0)) {
- revert BindNonexistent();
- }
-
- IERC721Binder binder = IERC721Binder(bindAddress);
- if (
- bound.bindAddress != bindAddress ||
- bound.bindId != bindId ||
- binder.ownerOf(bindId) != from
- ) {
- revert BinderInvalid();
- }
-
- if (
- msg.sender != from &&
- !binder.isApprovedForAll(from, msg.sender)
- ) {
- revert SenderUnauthorized();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- address delegatedOwner = _ownerOf[tokenId];
-
- delete getApproved[tokenId];
-
- unchecked {
- _balanceOf[to]++;
- _balanceOf[from]--;
- _balanceOf[bindAddress]--;
- boundBalanceOf[bindAddress][bindId]--;
- }
-
- _ownerOf[tokenId] = to;
- delete _bound[tokenId];
-
- emit Bind(msg.sender, from, to, tokenId, bindId, bindAddress);
- emit Transfer(delegatedOwner, to, tokenId);
-
- if (
- binder.onERC721Unbind(msg.sender, from, to, tokenId, bindId, "")
- !=
- IERC721Binder.onERC721Unbind.selector
- ) {
- revert BindInvalid();
- }
-
- if (
- to.code.length != 0 &&
- IERC721Receiver(to).onERC721Received(msg.sender, delegatedOwner, tokenId, "")
- !=
- IERC721Receiver.onERC721Received.selector
- ) {
- revert SafeTransferUnsupported();
- }
-
- }
-
- /// @inheritdoc IERC721
- function transferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public override(IERC721, ERC721) {
-
- address bindAddress = _bound[tokenId].bindAddress;
- uint256 bindId = _bound[tokenId].bindId;
-
- if (bindAddress == address(0)) {
- return super.transferFrom(from, to, tokenId);
- }
-
- if (msg.sender != bindAddress) {
- revert BindExistent();
- }
-
- IERC721Binder binder = IERC721Binder(bindAddress);
-
- if (
- binder.ownerOf(bindId) != from
- ) {
- revert BinderInvalid();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- delete getApproved[tokenId];
-
- uint256 bindBal = boundBalanceOf[bindAddress][bindId];
- unchecked {
- _balanceOf[from] -= bindBal;
- _balanceOf[to] += bindBal;
- }
-
- emit Transfer(from, to, tokenId);
- }
-
- function supportsInterface(bytes4 id) public pure override(ERC721, IERC165) returns (bool) {
- return super.supportsInterface(id) || id == _ERC721_BINDABLE_INTERFACE_ID;
- }
-
-}
diff --git a/assets/eip-5700/erc721/ERC721Binder.sol b/assets/eip-5700/erc721/ERC721Binder.sol
deleted file mode 100644
index e8f939a..0000000
--- a/assets/eip-5700/erc721/ERC721Binder.sol
+++ /dev/null
@@ -1,135 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-import {ERC721} from "./ERC721.sol";
-import {IERC721Bindable} from "../interfaces/IERC721Bindable.sol";
-import {IERC721Binder} from "../interfaces/IERC721Binder.sol";
-
-/// @title ERC-721 Binder Reference Implementation
-contract ERC721Binder is IERC721Binder {
-
- struct Bindable {
- address tokenAddress;
- uint256 tokenId;
- }
-
- /// @notice Checks for an owner if an address is an authorized operator.
- mapping(address => mapping(address => bool)) public _isApprovedForAll;
-
- /// @notice Tracks ownership of bound assets.
- mapping(uint256 => address) _ownerOf;
-
- /// @notice Maps an asset to a list of all bound bindables.
- mapping(uint256 => Bindable[]) _boundTokens;
-
- /// @notice Maps a token address and identifier to the bound tokens index.
- mapping(address => mapping(uint256 => uint256)) _boundIndexes;
-
- /// @dev EIP-165 identifiers for all supported interfaces.
- bytes4 private constant _ERC165_INTERFACE_ID = 0x01ffc9a7;
- bytes4 private constant _ERC721_BINDER_INTERFACE_ID = 0x2ac2d2bc;
- bytes4 private constant _ERC721_BINDABLE_INTERFACE_ID = 0xd92c3ff0;
-
- /// @inheritdoc IERC721Binder
- function isApprovedForAll(address owner, address operator) external view override returns (bool) {
- return _isApprovedForAll[owner][operator];
- }
-
- /// @inheritdoc IERC721Binder
- function ownerOf(uint256 id) public view returns (address) {
- return _ownerOf[id];
- }
-
- /// @inheritdoc IERC721Binder
- function onERC721Bind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- bytes calldata data
- ) public returns (bytes4) {
- if (_ownerOf[bindId] != to) {
- revert OwnerInvalid();
- }
-
- if (_boundIndexes[msg.sender][tokenId] != 0) {
- revert BindExistent();
- }
-
- if (!IERC721Bindable(msg.sender).supportsInterface(_ERC721_BINDABLE_INTERFACE_ID)) {
- revert BindInvalid();
- }
-
- _boundIndexes[msg.sender][tokenId] = _boundTokens[bindId].length;
- _boundTokens[bindId].push(Bindable(msg.sender, tokenId));
-
- return IERC721Binder.onERC721Bind.selector;
- }
-
- /// @inheritdoc IERC721Binder
- function onERC721Unbind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- bytes calldata data
- ) public returns (bytes4) {
- if (_ownerOf[bindId] != from) {
- revert OwnerInvalid();
- }
-
- if (_boundIndexes[msg.sender][tokenId] == 0) {
- revert BindNonexistent();
- }
-
- uint256 boundLastIndex = _boundTokens[bindId].length - 1;
- uint256 boundIndex = _boundIndexes[msg.sender][tokenId];
-
- if (boundIndex != boundLastIndex) {
- Bindable memory bindable = _boundTokens[bindId][boundLastIndex];
- _boundTokens[bindId][boundIndex] = bindable;
- _boundIndexes[bindable.tokenAddress][bindable.tokenId] = boundIndex;
- }
-
- delete _boundIndexes[msg.sender][tokenId];
- delete _boundTokens[bindId][boundLastIndex];
-
- return IERC721Binder.onERC721Unbind.selector;
- }
-
- /// @notice Transfers an asset from address `from` to address `to`.
- function transfer(
- address from,
- address to,
- uint256 bindId
- ) public {
- if (msg.sender != from && !_isApprovedForAll[from][msg.sender]) {
- revert SenderUnauthorized();
- }
-
- if (from != _ownerOf[bindId]) {
- revert OwnerInvalid();
- }
-
- if (to == address(0)) {
- revert ReceiverInvalid();
- }
-
- _ownerOf[bindId] = to;
-
- Bindable[] memory bindables = _boundTokens[bindId];
- for (uint256 i = 0; i < bindables.length; ++i) {
- IERC721Bindable(bindables[i].tokenAddress).transferFrom(from, to, bindables[i].tokenId);
- }
-
- }
-
- function supportsInterface(bytes4 id) external pure returns (bool) {
- return id == _ERC165_INTERFACE_ID || id == _ERC721_BINDER_INTERFACE_ID;
- }
-
-}
diff --git a/assets/eip-5700/interfaces/IERC1155Bindable.sol b/assets/eip-5700/interfaces/IERC1155Bindable.sol
deleted file mode 100644
index c4d491a..0000000
--- a/assets/eip-5700/interfaces/IERC1155Bindable.sol
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
-
-import {IERC1155BindableErrors} from "./IERC1155BindableErrors.sol";
-
-/// @title ERC-1155 Bindable Token Standard
-/// @dev See https://eips.ethereum.org/EIPS/eip-5656
-/// Note: the ERC-165 identifier for this interface is 0xd0d555c6.
-interface IERC1155Bindable is IERC1155, IERC1155BindableErrors {
-
- /// @notice The `Bind` event MUST emit when token ownership is delegated
- /// through an asset and when minting tokens bound to an existing asset.
- /// @dev When minting bound tokens, `from` MUST be set to the zero address.
- /// @param operator The address calling the bind (SHOULD be `msg.sender`).
- /// @param from The address which owns the unbound token(s).
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the token type being bound.
- /// @param amount The number of tokens of type `tokenId` being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- event Bind(
- address indexed operator,
- address indexed from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address indexed bindAddress
- );
-
- /// @notice The `BindBatch` event MUST emit when token ownership of
- /// different token types are delegated through different assets at once
- /// and when minting multiple token types bound to existing assets at once.
- /// @dev When minting bound tokens, `from` MUST be set to the zero address.
- /// @param operator The address calling the bind (SHOULD be `msg.sender`).
- /// @param from The address which owns the unbound token(s).
- /// @param to The address which owns the asset being bound to.
- /// @param tokenIds The identifiers of the token types being bound.
- /// @param amounts The number of tokens for each token type being bound.
- /// @param bindIds The identifiers of the assets being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- event BindBatch(
- address indexed operator,
- address indexed from,
- address to,
- uint256[] tokenIds,
- uint256[] amounts,
- uint256[] bindIds,
- address indexed bindAddress
- );
-
- /// @notice The `Unbind` event MUST emit when asset-delegated token
- /// ownership is revoked and when burning tokens bound to existing assets.
- /// @dev When burning bound tokens, `to` MUST be set to the zero address.
- /// @param operator The address calling the unbind (SHOULD be `msg.sender`).
- /// @param from The address which owns the asset the token(s) are bound to.
- /// @param to The address which will own the token(s) once unbound.
- /// @param tokenId The identifier of the token type being unbound.
- /// @param amount The number of tokens of type `tokenId` being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- event Unbind(
- address indexed operator,
- address indexed from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address indexed bindAddress
- );
-
- /// @notice The `UnbindBatch` event MUST emit when asset-delegated token
- /// ownership is revoked for multiple token types at once and when burning
- /// multiple token types bound to existing assets at once.
- /// @dev When burning bound tokens, `to` MUST be set to the zero address.
- /// @param operator The address calling the unbind (SHOULD be `msg.sender`).
- /// @param from The address which owns the asset the token(s) are bound to.
- /// @param to The address which will own the token(s) once unbound.
- /// @param tokenIds The identifiers of the token types being unbound.
- /// @param amounts The number of tokens for each token type being unbound.
- /// @param bindIds The identifier of the assets being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- event UnbindBatch(
- address indexed operator,
- address indexed from,
- address to,
- uint256[] tokenIds,
- uint256[] amounts,
- uint256[] bindIds,
- address indexed bindAddress
- );
-
- /// @notice Delegates ownership of `amount` tokens of type `tokenId` from
- /// address `from` through asset `bindId` owned by address `to`.
- /// @dev The function MUST throw unless `msg.sender` is an approved operator
- /// for `from`. The function also MUST throw if `from` owns fewer than
- /// `amount` unbound tokens, or if `to` is not the asset owner. After
- /// delegation of ownership, the function MUST check if `bindAddress` is a
- /// valid contract (code size > 0), and if so, call `onERC1155Bind` on the
- /// contract, throwing if the wrong identifier is returned (see "Binding
- /// Rules") or if the contract is invalid. On bind completion, the function
- /// MUST emit both `Bind` and IERC-1155 `TransferSingle` events to reflect
- /// delegated ownership change.
- /// @param from The address which owns the unbound token(s).
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the token type being bound.
- /// @param amount The number of tokens of type `tokenId` being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- /// @param data Additional data sent with the `onERC1155Bind` hook.
- function bind(
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @notice Delegates ownership of `amounts` tokens of types `tokenIds` from
- /// address `from` through assets `bindIds` owned by address `to`.
- /// @dev The function MUST throw unless `msg.sender` is an approved operator
- /// for `from`. The function also MUST throw if length of `amounts` is not
- /// the same as `tokenIds` or `bindIds`, if any unbound balances of
- /// `tokenIds` for `from` is less than that of `amounts`, or if `to` is not
- /// the asset owner. After delegating ownership, the function MUST check if
- /// `bindAddress` is a valid contract (code size > 0), and if so, call
- /// `onERC1155BatchBind` on the contract, throwing if the wrong identifier
- /// is returned (see "Binding Rules") or if the contract is invalid. On
- /// bind completion, the function MUST emit both `BindBatch` and IERC-1155
- /// `TransferBatch` events to reflect delegated ownership changes.
- /// @param from The address which owns the unbound tokens.
- /// @param to The address which owns the assets being bound to.
- /// @param tokenIds The identifiers of the token types being bound.
- /// @param amounts The number of tokens for each token type being bound.
- /// @param bindIds The identifiers of the assets being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- /// @param data Additional data sent with the `onERC1155BatchBind` hook.
- function batchBind(
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @notice Revokes delegated ownership of `amount` tokens of type `tokenId`
- /// owned by `from` bound to `bindId`, binding direct ownership to `to`.
- /// @dev The function MUST throw unless `msg.sender` is an approved operator
- /// or owner of the delegated asset `tokenId` is bound to. It also MUST
- /// throw if `from` owns fewer than `amount` bound tokens, or if `to` is
- /// the zero address. Once delegated ownership is revoked, the function
- /// MUST check if `bindAddress` is a valid contract (code size > 0), and if
- /// so, call `onERC1155Unbind` on the contract, throwing if the wrong
- /// identifier is returned (see "Binding Rules") or if the contract is
- /// invalid. The function also MUST check if `to` is a contract, and if so,
- /// call on it `onERC1155Received`, throwing if the wrong identifier is
- /// returned. On unbind completion, the function MUST emit both `Unbind`
- /// and IERC-1155 `TransferSingle` events to reflect delegated ownership change.
- /// @param from The address which owns the asset the token(s) are bound to.
- /// @param to The address which will own the tokens once unbound.
- /// @param tokenId The identifier of the token type being unbound.
- /// @param amount The number of tokens of type `tokenId` being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @param data Additional data sent with the `onERC1155Unbind` hook.
- function unbind(
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @notice Revokes delegated ownership of `amounts` tokens of `tokenIds`
- /// bound to assets `bindIds`, binding direct ownership to `to`.
- /// @dev The function MUST throw unless `msg.sender` is an approved operator
- /// or owner of all delegated assets `tokenIds` are bound to. It also MUST
- /// throw if the length of `amounts` is not the same as `tokenIds` or
- /// `bindIds`, if any bound balances of `tokenId` for `from` is less than
- /// that of `amounts`, or if `to` is the zero address. Once delegated
- /// ownership is revoked, the function MUST check if `bindAddress` is a
- /// valid contract (code size > 0), and if so, call onERC1155BatchUnbind`
- /// on it, throwing if a wrong identifier is returned (see "Binding Rules")
- /// or if the contract is invalid. The function also MUST check if `to` is
- /// a valid contract, and if so, call `onERC1155BatchReceived`, throwing if
- /// the wrong identifier is returned. On unbind completion, the function
- /// MUST emit the `BatchUnbind` and IERC-1155 `TransferBatch` events to
- /// reflect delegated ownership changes.
- /// @param from The address which owns the asset the tokens are bound to.
- /// @param to The address which will own the tokens once unbound.
- /// @param tokenIds The identifiers of the token types being unbound.
- /// @param amounts The number of tokens for each token type being unbound.
- /// @param bindIds The identifier of the assets being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @param data Additional data sent with the `onERC1155BatchUnbind` hook.
- function batchUnbind(
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @notice Gets the balance of bound tokens of type `tokenId` bound to the
- /// asset `bindId` at address `bindAddress`.
- /// @param bindId The identifier of the bound asset.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @param tokenId The identifier of the bound token type being counted.
- /// @return The total number of NFTs bound to the asset.
- function boundBalanceOf(
- address bindAddress,
- uint256 bindId,
- uint256 tokenId
- ) external returns (uint256);
-
- /// @notice Gets the balance of bound tokens for multiple token types given
- /// by `tokenIds` bound to assets `bindIds` at address `bindAddress`.
- /// @notice Retrieves bound balances of multiple asset / token type pairs.
- /// @param bindIds List of bound asset identifiers.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @param tokenIds The identifiers of the token type being counted.
- /// @return balances The bound balances for each asset / token type pair.
- function boundBalanceOfBatch(
- address bindAddress,
- uint256[] calldata bindIds,
- uint256[] calldata tokenIds
- ) external returns (uint256[] memory balances);
-
-}
diff --git a/assets/eip-5700/interfaces/IERC1155BindableErrors.sol b/assets/eip-5700/interfaces/IERC1155BindableErrors.sol
deleted file mode 100644
index 4b6aefa..0000000
--- a/assets/eip-5700/interfaces/IERC1155BindableErrors.sol
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-1155 Bindable Errors Interface
-interface IERC1155BindableErrors {
-
- /// @notice Bind is not valid.
- error BindInvalid();
-
- /// @notice Bound asset or bound asset owner is not valid.
- error BinderInvalid();
-
-}
diff --git a/assets/eip-5700/interfaces/IERC1155Binder.sol b/assets/eip-5700/interfaces/IERC1155Binder.sol
deleted file mode 100644
index 4466ae7..0000000
--- a/assets/eip-5700/interfaces/IERC1155Binder.sol
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-import {IERC1155BinderErrors} from "./IERC1155BinderErrors.sol";
-
-/// @dev Note: the ERC-165 identifier for this interface is 0x6fc97e78.
-interface IERC1155Binder is IERC165, IERC1155BinderErrors {
-
- /// @notice Handles binding of an IERC1155Bindable-compliant token type.
- /// @dev An IERC1155Bindable-compliant smart contract MUST call this
- /// function at the end of a `bind` after delegating ownership to the asset
- /// owner. The function MUST revert if `to` is not the asset owner of
- /// `bindId`, or if `bindId` is not a valid asset. The function MUST revert
- /// if it rejects the bind. If accepting the bind, the function MUST return
- /// `bytes4(keccak256("onERC1155Bind(address,address,address,uint256,uint256,uint256,bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the binding token is `msg.sender`.
- /// @param operator The address responsible for binding.
- /// @param from The address which owns the unbound tokens.
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the token type being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param data Additional data sent along with no specified format.
- /// @return `bytes4(keccak256("onERC1155Bind(address,address,address,uint256,uint256,uint256,bytes)"))`
- function onERC1155Bind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Handles binding of multiple IERC1155Bindable-compliant tokens
- /// `tokenIds` to multiple assets `bindIds`.
- /// @dev An IERC1155Bindable-compliant smart contract MUST call this
- /// function at the end of a `batchBind` after delegating ownership of
- /// multiple token types to the asset owner. The function MUST revert if
- /// `to` is not the asset owner of `bindId`, or if `bindId` is not a valid
- /// asset. The function MUST revert if it rejects the binds. If accepting
- /// the binds, the function MUST return `bytes4(keccak256("onERC1155BatchBind(address,address,address,uint256[],uint256[],uint256[],bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the binding token is `msg.sender`.
- /// @param operator The address responsible for performing the binds.
- /// @param from The address which owns the unbound tokens.
- /// @param to The address which owns the assets being bound to.
- /// @param tokenIds The list of token types being bound.
- /// @param amounts The number of tokens for each token type being bound.
- /// @param bindIds The identifiers of the assets being bound to.
- /// @param data Additional data sent along with no specified format.
- /// @return `bytes4(keccak256("onERC1155Bind(address,address,address,uint256[],uint256[],uint256[],bytes)"))`
- function onERC1155BatchBind(
- address operator,
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Handles unbinding of an IERC1155Bindable-compliant token type.
- /// @dev An IERC1155Bindable-compliant contract MUST call this function at
- /// the end of an `unbind` after revoking delegated asset ownership. The
- /// function MUST revert if `from` is not the asset owner of `bindId`,
- /// or if `bindId` is not a valid asset. The function MUST revert if it
- /// rejects the unbind. If accepting the unbind, the function MUST return
- /// `bytes4(keccak256("onERC1155Unbind(address,address,address,uint256,uint256,uint256,bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the unbinding token is `msg.sender`.
- /// @param operator The address responsible for performing the unbind.
- /// @param from The address which owns the asset the token type is bound to.
- /// @param to The address which will own the tokens once unbound.
- /// @param tokenId The token type being unbound.
- /// @param amount The number of tokens of type `tokenId` being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param data Additional data sent along with no specified format.
- /// @return `bytes4(keccak256("onERC1155Unbind(address,address,address,uint256,uint256,uint256,bytes)"))`
- function onERC1155Unbind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 amount,
- uint256 bindId,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Handles unbinding of multiple IERC1155Bindable-compliant token types.
- /// @dev An IERC1155Bindable-compliant contract MUST call this function at
- /// the end of an `batchUnbind` after revoking delegated asset ownership.
- /// The function MUST revert if `from` is not the asset owner of `bindId`,
- /// or if `bindId` is not a valid asset. The function MUST revert if it
- /// rejects the unbinds. If accepting the unbinds, the function MUST return
- /// `bytes4(keccak256("onERC1155Unbind(address,address,address,uint256[],uint256[],uint256[],bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the unbinding token is `msg.sender`.
- /// @param operator The address responsible for performing the unbinds.
- /// @param from The address which owns the assets being unbound from.
- /// @param to The address which will own the tokens once unbound.
- /// @param tokenIds The list of token types being unbound.
- /// @param amounts The number of tokens for each token type being unbound.
- /// @param bindIds The identifiers of the assets being unbound from.
- /// @param data Additional data sent along with no specified format.
- /// @return `bytes4(keccak256("onERC1155Unbind(address,address,address,uint256[],uint256[],uint256[],bytes)"))`
- function onERC1155BatchUnbind(
- address operator,
- address from,
- address to,
- uint256[] calldata tokenIds,
- uint256[] calldata amounts,
- uint256[] calldata bindIds,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Gets the owner address of the asset represented by id `bindId`.
- /// @param bindId The identifier of the asset whose owner is being queried.
- /// @return The address of the owner of the asset.
- function ownerOf(uint256 bindId) external view returns (address);
-
- /// @notice Checks if an operator can act on behalf of an asset owner.
- /// @param owner The address that owns an asset.
- /// @param operator The address that acts on behalf of owner `owner`.
- /// @return True if `operator` can act on behalf of `owner`, else False.
- function isApprovedForAll(address owner, address operator) external view returns (bool);
-
-}
diff --git a/assets/eip-5700/interfaces/IERC1155BinderErrors.sol b/assets/eip-5700/interfaces/IERC1155BinderErrors.sol
deleted file mode 100644
index 9c43833..0000000
--- a/assets/eip-5700/interfaces/IERC1155BinderErrors.sol
+++ /dev/null
@@ -1,13 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-1155 Binder Errors Interface
-interface IERC1155BinderErrors {
-
- /// @notice Asset has already minted.
- error AssetAlreadyMinted();
-
- /// @notice Receiving address cannot be the zero address.
- error ReceiverInvalid();
-
-}
diff --git a/assets/eip-5700/interfaces/IERC1155Errors.sol b/assets/eip-5700/interfaces/IERC1155Errors.sol
deleted file mode 100644
index d3f0712..0000000
--- a/assets/eip-5700/interfaces/IERC1155Errors.sol
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-1155 Errors Interface
-interface IERC1155Errors {
-
- /// @notice Arity mismatch between two arrays.
- error ArityMismatch();
-
- /// @notice Originating address does not own the NFT.
- error OwnerInvalid();
-
- /// @notice Receiving address cannot be the zero address.
- error ReceiverInvalid();
-
- /// @notice Receiving contract does not implement the ERC-1155 wallet interface.
- error SafeTransferUnsupported();
-
- /// @notice Sender is not NFT owner, approved address, or owner operator.
- error SenderUnauthorized();
-
- /// @notice Token has already minted.
- error TokenAlreadyMinted();
-
- /// @notice NFT does not exist.
- error TokenNonExistent();
-
-}
diff --git a/assets/eip-5700/interfaces/IERC721Bindable.sol b/assets/eip-5700/interfaces/IERC721Bindable.sol
deleted file mode 100644
index f8ac283..0000000
--- a/assets/eip-5700/interfaces/IERC721Bindable.sol
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-
-import {IERC721BindableErrors} from "./IERC721BindableErrors.sol";
-
-/// @title ERC-721 Bindable Token Standard
-/// @dev See https://eips.ethereum.org/EIPS/eip-5700
-/// Note: the ERC-165 identifier for this interface is 0x82a34a7d.
-interface IERC721Bindable is IERC721, IERC721BindableErrors {
-
- /// @notice The `Bind` event MUST emit when NFT ownership is delegated
- /// through an asset and when minting an NFT bound to an existing asset.
- /// @dev When minting bound NFTs, `from` MUST be set to the zero address.
- /// @param operator The address calling the bind (SHOULD be `msg.sender`).
- /// @param from The address which owns the unbound NFT.
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the NFT being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- event Bind(
- address indexed operator,
- address indexed from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address indexed bindAddress
- );
-
- /// @notice The `Unbind` event MUST emit when asset-delegated NFT ownership
- /// is revoked, as well as when burning an NFT bound to an existing asset.
- /// @dev When burning bound NFTs, `to` MUST be set to the zero address.
- /// @param operator The address calling the unbind (SHOULD be `msg.sender`).
- /// @param from The address which owns the asset the NFT is bound to.
- /// @param to The address which will own the NFT once unbound.
- /// @param tokenId The identifier of the NFT being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- event Unbind(
- address indexed operator,
- address indexed from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address indexed bindAddress
- );
-
- /// @notice Delegates NFT ownership of NFT `tokenId` from address `from`
- /// through the asset `bindId` owned by address `to`.
- /// @dev The function MUST throw unless `msg.sender` is the current owner,
- /// an authorized operator, or the approved address for the NFT. It also
- /// MUST throw if NFT `tokenId` is already bound, if `from` is not the NFT
- /// owner, or if `to` is not the asset owner. After ownership delegation,
- /// the function MUST check if `bindAddress` is a valid contract (code size
- /// > 0), and if so, call `onERC721Bind` on the contract, throwing if the
- /// wrong identifier is returned (see "Binding Rules") or if the contract
- /// is invalid. On bind completion, the function MUST emit both `Bind` and
- /// IERC-721 `Transfer` events to reflect delegated ownership change.
- /// @param from The address which owns the unbound NFT.
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the NFT being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param bindAddress The contract address handling asset ownership.
- /// @param data Additional data sent with the `onERC721Bind` hook.
- function bind(
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @dev The function MUST throw unless `msg.sender` is an approved operator
- /// or owner of the delegated asset of `tokenId`. It also MUST throw if NFT
- /// `tokenId` is not bound, if `from` is not the asset owner, or if `to`
- /// is the zero address. After ownership transition, the function MUST
- /// check if `bindAddress` is a valid contract (code size > 0), and if so,
- /// call `onERC721Unbind` the contract, throwing if the wrong identifier is
- /// returned (see "Binding Rules") or if the contract is invalid.
- /// The function also MUST check if `to` is a valid contract, and if so,
- /// call `onERC721Received`, throwing if the wrong identifier is returned.
- /// On unbind completion, the function MUST emit both `Unbind` and IERC-721
- /// `Transfer` events to reflect delegated ownership change.
- /// @param from The address which owns the asset the NFT is bound to.
- /// @param to The address which will own the NFT once unbound.
- /// @param tokenId The identifier of the NFT being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @param data Additional data sent with the `onERC721Unbind` hook.
- function unbind(
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- address bindAddress,
- bytes calldata data
- ) external;
-
- /// @notice Gets the asset identifier and address which a token is bound to.
- /// @param tokenId The identifier of the NFT being queried.
- /// @return The bound asset identifier and contract address.
- function binderOf(uint256 tokenId) external returns (address, uint256);
-
- /// @notice Counts NFTs bound to asset `bindId` at address `bindAddress`.
- /// @param bindId The identifier of the bound asset.
- /// @param bindAddress The contract address handling bound asset ownership.
- /// @return The total number of NFTs bound to the asset.
- function boundBalanceOf(address bindAddress, uint256 bindId) external returns (uint256);
-
-}
diff --git a/assets/eip-5700/interfaces/IERC721BindableErrors.sol b/assets/eip-5700/interfaces/IERC721BindableErrors.sol
deleted file mode 100644
index 1124932..0000000
--- a/assets/eip-5700/interfaces/IERC721BindableErrors.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-721 Bindable Errors Interface
-interface IERC721BindableErrors {
-
- /// @notice Bind already exists.
- error BindExistent();
-
- /// @notice Bind does not exist.
- error BindNonexistent();
-
- /// @notice Bind is not valid.
- error BindInvalid();
-
- /// @notice Bound asset or bound asset owner is not valid.
- error BinderInvalid();
-
-}
diff --git a/assets/eip-5700/interfaces/IERC721Binder.sol b/assets/eip-5700/interfaces/IERC721Binder.sol
deleted file mode 100644
index 93426e2..0000000
--- a/assets/eip-5700/interfaces/IERC721Binder.sol
+++ /dev/null
@@ -1,72 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
-
-import {IERC721BinderErrors} from "./IERC721BinderErrors.sol";
-
-/// @dev Note: the ERC-165 identifier for this interface is 0x2ac2d2bc.
-interface IERC721Binder is IERC165, IERC721BinderErrors {
-
- /// @notice Handles the binding of an IERC721Bindable-compliant NFT.
- /// @dev An IERC721Bindable-compliant smart contract MUST call this function
- /// at the end of a `bind` after delegating ownership to the asset owner.
- /// The function MUST revert if `to` is not the asset owner of `bindId` or
- /// if asset `bindId` is not a valid asset. The function MUST revert if it
- /// rejects the bind. If accepting the bind, the function MUST return
- /// `bytes4(keccak256("onERC721Bind(address,address,address,uint256,uint256,bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the binding NFT is `msg.sender`.
- /// @param operator The address responsible for initiating the bind.
- /// @param from The address which owns the unbound NFT.
- /// @param to The address which owns the asset being bound to.
- /// @param tokenId The identifier of the NFT being bound.
- /// @param bindId The identifier of the asset being bound to.
- /// @param data Additional data sent along with no specified format.
- /// @return `bytes4(keccak256("onERC721Bind(address,address,address,uint256,uint256,bytes)"))`
- function onERC721Bind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Handles the unbinding of an IERC721Bindable-compliant NFT.
- /// @dev An IERC721Bindable-compliant smart contract MUST call this function
- /// at the end of an `unbind` after revoking delegated asset ownership.
- /// The function MUST revert if `from` is not the asset owner of `bindId`
- /// or if `bindId` is not a valid asset. The function MUST revert if it
- /// rejects the unbind. If accepting the unbind, the function MUST return
- /// `bytes4(keccak256("onERC721Unbind(address,address,address,uint256,uint256,bytes)"))`
- /// Caller MUST revert the transaction if the above value is not returned.
- /// Note: The contract address of the unbinding NFT is `msg.sender`.
- /// @param from The address which owns the asset the NFT is bound to.
- /// @param to The address which will own the NFT once unbound.
- /// @param tokenId The identifier of the NFT being unbound.
- /// @param bindId The identifier of the asset being unbound from.
- /// @param data Additional data with no specified format.
- /// @return `bytes4(keccak256("onERC721Unbind(address,address,address,uint256,uint256,bytes)"))`
- function onERC721Unbind(
- address operator,
- address from,
- address to,
- uint256 tokenId,
- uint256 bindId,
- bytes calldata data
- ) external returns (bytes4);
-
- /// @notice Gets the owner address of the asset represented by id `bindId`.
- /// @dev Queries for assets assigned to the zero address MUST throw.
- /// @param bindId The identifier of the asset whose owner is being queried.
- /// @return The address of the owner of the asset.
- function ownerOf(uint256 bindId) external view returns (address);
-
- /// @notice Checks if an operator can act on behalf of an asset owner.
- /// @param owner The address that owns an asset.
- /// @param operator The address that acts on behalf of owner `owner`.
- /// @return True if `operator` can act on behalf of `owner`, else False.
- function isApprovedForAll(address owner, address operator) external view returns (bool);
-
-}
diff --git a/assets/eip-5700/interfaces/IERC721BinderErrors.sol b/assets/eip-5700/interfaces/IERC721BinderErrors.sol
deleted file mode 100644
index c949e6e..0000000
--- a/assets/eip-5700/interfaces/IERC721BinderErrors.sol
+++ /dev/null
@@ -1,25 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-721 Binder Errors Interface
-interface IERC721BinderErrors {
-
- /// @notice Asset binding already exists.
- error BindExistent();
-
- /// @notice Asset binding is not valid.
- error BindInvalid();
-
- /// @notice Asset binding does not exist.
- error BindNonexistent();
-
- /// @notice Originating address does not own the asset.
- error OwnerInvalid();
-
- /// @notice Receiving address cannot be the zero address.
- error ReceiverInvalid();
-
- /// @notice Sender is not NFT owner, approved address, or owner operator.
- error SenderUnauthorized();
-
-}
diff --git a/assets/eip-5700/interfaces/IERC721Errors.sol b/assets/eip-5700/interfaces/IERC721Errors.sol
deleted file mode 100644
index 2fc6494..0000000
--- a/assets/eip-5700/interfaces/IERC721Errors.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.16;
-
-/// @title ERC-721 Errors Interface
-interface IERC721Errors {
-
- /// @notice Originating address does not own the NFT.
- error OwnerInvalid();
-
- /// @notice Receiving address cannot be the zero address.
- error ReceiverInvalid();
-
- /// @notice Receiving contract does not implement the ERC-721 wallet interface.
- error SafeTransferUnsupported();
-
- /// @notice Sender is not NFT owner, approved address, or owner operator.
- error SenderUnauthorized();
-
- /// @notice NFT supply has hit maximum capacity.
- error SupplyMaxCapacity();
-
- /// @notice Token has already minted.
- error TokenAlreadyMinted();
-
- /// @notice NFT does not exist.
- error TokenNonExistent();
-
-}
-
diff --git a/assets/eip-5725/README.md b/assets/eip-5725/README.md
deleted file mode 100644
index 65bfb82..0000000
--- a/assets/eip-5725/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# EIP-5725: Transferrable Vesting NFT - Reference Implementation
-This repository serves as a reference implementation for **EIP-5725 Transferrable Vesting NFT Standard**. A Non-Fungible Token (NFT) standard used to vest tokens (ERC-20 or otherwise) over a vesting release curve.
-
-## Contents
-- [EIP-5725 Specification](./contracts/IERC5725.sol): Interface and definitions for the EIP-5725 specification.
-- [ERC-5725 Implementation (abstract)](./contracts/ERC5725.sol): ERC-5725 contract which can be extended to implement the specification.
-- [VestingNFT Implementation](./contracts/reference/LinearVestingNFT.sol): Full ERC-5725 implementation using cliff vesting curve.
-- [LinearVestingNFT Implementation](./contracts/reference/VestingNFT.sol): Full ERC-5725 implementation using linear vesting curve.
\ No newline at end of file
diff --git a/assets/eip-5725/contracts/ERC5725.sol b/assets/eip-5725/contracts/ERC5725.sol
deleted file mode 100644
index ff030b1..0000000
--- a/assets/eip-5725/contracts/ERC5725.sol
+++ /dev/null
@@ -1,163 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.17;
-
-import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
-import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
-import "@openzeppelin/contracts/access/Ownable.sol";
-import "@openzeppelin/contracts/utils/Counters.sol";
-import "./IERC5725.sol";
-
-abstract contract ERC5725 is IERC5725, ERC721 {
- using SafeERC20 for IERC20;
-
- /// @dev mapping for claimed payouts
- mapping(uint256 => uint256) /*tokenId*/ /*claimed*/
- internal _payoutClaimed;
-
- /**
- * @notice Checks if the tokenId exists and its valid
- * @param tokenId The NFT token id
- */
- modifier validToken(uint256 tokenId) {
- require(_exists(tokenId), "ERC5725: invalid token ID");
- _;
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function claim(uint256 tokenId) external override(IERC5725) validToken(tokenId) {
- require(ownerOf(tokenId) == msg.sender, "Not owner of NFT");
- uint256 amountClaimed = claimablePayout(tokenId);
- require(amountClaimed > 0, "ERC5725: No pending payout");
-
- emit PayoutClaimed(tokenId, msg.sender, amountClaimed);
-
- _payoutClaimed[tokenId] += amountClaimed;
- IERC20(payoutToken(tokenId)).safeTransfer(msg.sender, amountClaimed);
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function vestedPayout(uint256 tokenId) public view override(IERC5725) returns (uint256 payout) {
- return vestedPayoutAtTime(tokenId, block.timestamp);
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)
- public
- view
- virtual
- override(IERC5725)
- returns (uint256 payout);
-
- /**
- * @dev See {IERC5725}.
- */
- function vestingPayout(uint256 tokenId)
- public
- view
- override(IERC5725)
- validToken(tokenId)
- returns (uint256 payout)
- {
- return _payout(tokenId) - vestedPayout(tokenId);
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function claimablePayout(uint256 tokenId)
- public
- view
- override(IERC5725)
- validToken(tokenId)
- returns (uint256 payout)
- {
- return vestedPayout(tokenId) - _payoutClaimed[tokenId];
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function claimedPayout(uint256 tokenId)
- public
- view
- override(IERC5725)
- validToken(tokenId)
- returns (uint256 payout)
- {
- return _payoutClaimed[tokenId];
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function vestingPeriod(uint256 tokenId)
- public
- view
- override(IERC5725)
- validToken(tokenId)
- returns (uint256 vestingStart, uint256 vestingEnd)
- {
- return (_startTime(tokenId), _endTime(tokenId));
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function payoutToken(uint256 tokenId) public view override(IERC5725) validToken(tokenId) returns (address token) {
- return _payoutToken(tokenId);
- }
-
- /**
- * @dev See {IERC165-supportsInterface}.
- * IERC5725 interfaceId = 0x7c89676d
- */
- function supportsInterface(bytes4 interfaceId)
- public
- view
- virtual
- override(ERC721, IERC165)
- returns (bool supported)
- {
- return interfaceId == type(IERC5725).interfaceId || super.supportsInterface(interfaceId);
- }
-
- /**
- * @dev Internal function to get the payout token of a given vesting NFT
- *
- * @param tokenId on which to check the payout token address
- * @return address payout token address
- */
- function _payoutToken(uint256 tokenId) internal view virtual returns (address);
-
- /**
- * @dev Internal function to get the total payout of a given vesting NFT.
- * @dev This is the total that will be paid out to the NFT owner, including historical tokens.
- *
- * @param tokenId to check
- * @return uint256 the total payout of a given vesting NFT
- */
- function _payout(uint256 tokenId) internal view virtual returns (uint256);
-
- /**
- * @dev Internal function to get the start time of a given vesting NFT
- *
- * @param tokenId to check
- * @return uint256 the start time in epoch timestamp
- */
- function _startTime(uint256 tokenId) internal view virtual returns (uint256);
-
- /**
- * @dev Internal function to get the end time of a given vesting NFT
- *
- * @param tokenId to check
- * @return uint256 the end time in epoch timestamp
- */
- function _endTime(uint256 tokenId) internal view virtual returns (uint256);
-}
diff --git a/assets/eip-5725/contracts/IERC5725.sol b/assets/eip-5725/contracts/IERC5725.sol
deleted file mode 100644
index d7b0196..0000000
--- a/assets/eip-5725/contracts/IERC5725.sol
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-
-/**
- * @title Non-Fungible Vesting Token Standard
- * @notice A non-fungible token standard used to vest tokens (ERC-20 or otherwise) over a vesting release curve
- * scheduled using timestamps.
- * @dev Because this standard relies on timestamps for the vesting schedule, it's important to keep track of the
- * tokens claimed per Vesting NFT so that a user cannot withdraw more tokens than alloted for a specific Vesting NFT.
- */
-interface IERC5725 is IERC721 {
- /**
- * This event is emitted when the payout is claimed through the claim function
- * @param tokenId the NFT tokenId of the assets being claimed.
- * @param recipient The address which is receiving the payout.
- * @param claimAmount The amount of tokens being claimed.
- */
- event PayoutClaimed(uint256 indexed tokenId, address indexed recipient, uint256 claimAmount);
-
- /**
- * @notice Claim the pending payout for the NFT
- * @dev MUST grant the claimablePayout value at the time of claim being called
- * MUST revert if not called by the token owner or approved users
- * MUST emit PayoutClaimed
- * SHOULD revert if there is nothing to claim
- * @param tokenId The NFT token id
- */
- function claim(uint256 tokenId) external;
-
- /**
- * @notice Number of tokens for the NFT which have been claimed at the current timestamp
- * @param tokenId The NFT token id
- * @return payout The total amount of payout tokens claimed for this NFT
- */
- function claimedPayout(uint256 tokenId) external view returns (uint256 payout);
-
- /**
- * @notice Number of tokens for the NFT which can be claimed at the current timestamp
- * @dev It is RECOMMENDED that this is calculated as the `vestedPayout()` subtracted from `payoutClaimed()`.
- * @param tokenId The NFT token id
- * @return payout The amount of unlocked payout tokens for the NFT which have not yet been claimed
- */
- function claimablePayout(uint256 tokenId) external view returns (uint256 payout);
-
- /**
- * @notice Total amount of tokens which have been vested at the current timestamp.
- * This number also includes vested tokens which have been claimed.
- * @dev It is RECOMMENDED that this function calls `vestedPayoutAtTime` with
- * `block.timestamp` as the `timestamp` parameter.
- * @param tokenId The NFT token id
- * @return payout Total amount of tokens which have been vested at the current timestamp.
- */
- function vestedPayout(uint256 tokenId) external view returns (uint256 payout);
-
- /**
- * @notice Total amount of vested tokens at the provided timestamp.
- * This number also includes vested tokens which have been claimed.
- * @dev `timestamp` MAY be both in the future and in the past.
- * Zero MUST be returned if the timestamp is before the token was minted.
- * @param tokenId The NFT token id
- * @param timestamp The timestamp to check on, can be both in the past and the future
- * @return payout Total amount of tokens which have been vested at the provided timestamp
- */
- function vestedPayoutAtTime(uint256 tokenId, uint256 timestamp) external view returns (uint256 payout);
-
- /**
- * @notice Number of tokens for an NFT which are currently vesting.
- * @dev The sum of vestedPayout and vestingPayout SHOULD always be the total payout.
- * @param tokenId The NFT token id
- * @return payout The number of tokens for the NFT which are vesting until a future date.
- */
- function vestingPayout(uint256 tokenId) external view returns (uint256 payout);
-
- /**
- * @notice The start and end timestamps for the vesting of the provided NFT
- * MUST return the timestamp where no further increase in vestedPayout occurs for `vestingEnd`.
- * @param tokenId The NFT token id
- * @return vestingStart The beginning of the vesting as a unix timestamp
- * @return vestingEnd The ending of the vesting as a unix timestamp
- */
- function vestingPeriod(uint256 tokenId) external view returns (uint256 vestingStart, uint256 vestingEnd);
-
- /**
- * @notice Token which is used to pay out the vesting claims
- * @param tokenId The NFT token id
- * @return token The token which is used to pay out the vesting claims
- */
- function payoutToken(uint256 tokenId) external view returns (address token);
-}
diff --git a/assets/eip-5725/contracts/mocks/ERC20Mock.sol b/assets/eip-5725/contracts/mocks/ERC20Mock.sol
deleted file mode 100644
index c006a24..0000000
--- a/assets/eip-5725/contracts/mocks/ERC20Mock.sol
+++ /dev/null
@@ -1,26 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity 0.8.17;
-
-import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
-
-contract ERC20Mock is ERC20 {
- uint8 private _decimals;
-
- constructor(
- uint256 supply_,
- uint8 decimals_,
- string memory name_,
- string memory symbol_
- ) ERC20(name_, symbol_) {
- _mint(msg.sender, supply_);
- _decimals = decimals_;
- }
-
- function mint(uint256 amount, address to) public {
- _mint(to, amount);
- }
-
- function decimals() public view virtual override returns (uint8) {
- return _decimals;
- }
-}
diff --git a/assets/eip-5725/contracts/reference/LinearVestingNFT.sol b/assets/eip-5725/contracts/reference/LinearVestingNFT.sol
deleted file mode 100644
index a87fd9e..0000000
--- a/assets/eip-5725/contracts/reference/LinearVestingNFT.sol
+++ /dev/null
@@ -1,119 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.17;
-
-import "../ERC5725.sol";
-
-contract LinearVestingNFT is ERC5725 {
- using SafeERC20 for IERC20;
-
- struct VestDetails {
- IERC20 payoutToken; /// @dev payout token
- uint256 payout; /// @dev payout token remaining to be paid
- uint128 startTime; /// @dev when vesting starts
- uint128 endTime; /// @dev when vesting end
- uint128 cliff; /// @dev duration in seconds of the cliff in which tokens will be begin releasing
- }
- mapping(uint256 => VestDetails) public vestDetails; /// @dev maps the vesting data with tokenIds
-
- /// @dev tracker of current NFT id
- uint256 private _tokenIdTracker;
-
- /**
- * @dev See {IERC5725}.
- */
- constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
-
- /**
- * @notice Creates a new vesting NFT and mints it
- * @dev Token amount should be approved to be transferred by this contract before executing create
- * @param to The recipient of the NFT
- * @param amount The total assets to be locked over time
- * @param startTime When the vesting starts in epoch timestamp
- * @param duration The vesting duration in seconds
- * @param cliff The cliff duration in seconds
- * @param token The ERC20 token to vest over time
- */
- function create(
- address to,
- uint256 amount,
- uint128 startTime,
- uint128 duration,
- uint128 cliff,
- IERC20 token
- ) public virtual {
- require(startTime >= block.timestamp, "startTime cannot be on the past");
- require(to != address(0), "to cannot be address 0");
- require(cliff <= duration, "duration needs to be more than cliff");
-
- uint256 newTokenId = _tokenIdTracker;
-
- vestDetails[newTokenId] = VestDetails({
- payoutToken: token,
- payout: amount,
- startTime: startTime,
- endTime: startTime + duration,
- cliff: startTime + cliff
- });
-
- _tokenIdTracker++;
- _mint(to, newTokenId);
- IERC20(payoutToken(newTokenId)).safeTransferFrom(msg.sender, address(this), amount);
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)
- public
- view
- override(ERC5725)
- validToken(tokenId)
- returns (uint256 payout)
- {
- if (timestamp < _cliff(tokenId)) {
- return 0;
- }
- if (timestamp > _endTime(tokenId)) {
- return _payout(tokenId);
- }
- return (_payout(tokenId) * (timestamp - _startTime(tokenId))) / (_endTime(tokenId) - _startTime(tokenId));
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _payoutToken(uint256 tokenId) internal view override returns (address) {
- return address(vestDetails[tokenId].payoutToken);
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _payout(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].payout;
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _startTime(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].startTime;
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _endTime(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].endTime;
- }
-
- /**
- * @dev Internal function to get the cliff time of a given linear vesting NFT
- *
- * @param tokenId to check
- * @return uint256 the cliff time in seconds
- */
- function _cliff(uint256 tokenId) internal view returns (uint256) {
- return vestDetails[tokenId].cliff;
- }
-}
diff --git a/assets/eip-5725/contracts/reference/VestingNFT.sol b/assets/eip-5725/contracts/reference/VestingNFT.sol
deleted file mode 100644
index 1b50d85..0000000
--- a/assets/eip-5725/contracts/reference/VestingNFT.sol
+++ /dev/null
@@ -1,99 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.17;
-
-import "../ERC5725.sol";
-
-contract VestingNFT is ERC5725 {
- using SafeERC20 for IERC20;
-
- struct VestDetails {
- IERC20 payoutToken; /// @dev payout token
- uint256 payout; /// @dev payout token remaining to be paid
- uint128 startTime; /// @dev when vesting starts
- uint128 endTime; /// @dev when vesting end
- }
- mapping(uint256 => VestDetails) public vestDetails; /// @dev maps the vesting data with tokenIds
-
- /// @dev tracker of current NFT id
- uint256 private _tokenIdTracker;
-
- /**
- * @dev Initializes the contract by setting a `name` and a `symbol` to the token.
- */
- constructor(string memory name, string memory symbol) ERC721(name, symbol) {}
-
- /**
- * @notice Creates a new vesting NFT and mints it
- * @dev Token amount should be approved to be transferred by this contract before executing create
- * @param to The recipient of the NFT
- * @param amount The total assets to be locked over time
- * @param releaseTimestamp When the full amount of tokens get released
- * @param token The ERC20 token to vest over time
- */
- function create(
- address to,
- uint256 amount,
- uint128 releaseTimestamp,
- IERC20 token
- ) public virtual {
- require(to != address(0), "to cannot be address 0");
- require(releaseTimestamp > block.timestamp, "release must be in future");
-
- uint256 newTokenId = _tokenIdTracker;
-
- vestDetails[newTokenId] = VestDetails({
- payoutToken: token,
- payout: amount,
- startTime: uint128(block.timestamp),
- endTime: releaseTimestamp
- });
-
- _tokenIdTracker++;
- _mint(to, newTokenId);
- IERC20(payoutToken(newTokenId)).safeTransferFrom(msg.sender, address(this), amount);
- }
-
- /**
- * @dev See {IERC5725}.
- */
- function vestedPayoutAtTime(uint256 tokenId, uint256 timestamp)
- public
- view
- override(ERC5725)
- validToken(tokenId)
- returns (uint256 payout)
- {
- if (timestamp >= _endTime(tokenId)) {
- return _payout(tokenId);
- }
- return 0;
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _payoutToken(uint256 tokenId) internal view override returns (address) {
- return address(vestDetails[tokenId].payoutToken);
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _payout(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].payout;
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _startTime(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].startTime;
- }
-
- /**
- * @dev See {ERC5725}.
- */
- function _endTime(uint256 tokenId) internal view override returns (uint256) {
- return vestDetails[tokenId].endTime;
- }
-}
diff --git a/assets/eip-5725/test/LinearVestingNFT.test.ts b/assets/eip-5725/test/LinearVestingNFT.test.ts
deleted file mode 100644
index 7d1b23c..0000000
--- a/assets/eip-5725/test/LinearVestingNFT.test.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-import { ethers } from 'hardhat'
-import { Signer } from 'ethers'
-import { expect } from 'chai'
-import { increaseTime } from './helpers/time'
-// typechain
-import {
- ERC20Mock__factory,
- ERC20Mock,
- LinearVestingNFT__factory,
- LinearVestingNFT,
-} from '../typechain-types'
-
-const testValues = {
- payout: '1000000000',
- lockTime: 60,
- buffer: 10,
- totalLock: 70,
-}
-
-describe('LinearVestingNFT', function () {
- let accounts: Signer[]
- let linearVestingNFT: LinearVestingNFT
- let mockToken: ERC20Mock
- let receiverAccount: string
- let unlockTime: number
-
- beforeEach(async function () {
- const LinearVestingNFT = (await ethers.getContractFactory(
- 'LinearVestingNFT'
- )) as LinearVestingNFT__factory
- linearVestingNFT = await LinearVestingNFT.deploy('LinearVestingNFT', 'TLV')
- await linearVestingNFT.deployed()
-
- const ERC20Mock = (await ethers.getContractFactory(
- 'ERC20Mock'
- )) as ERC20Mock__factory
- mockToken = await ERC20Mock.deploy(
- '1000000000000000000000',
- 18,
- 'LockedToken',
- 'LOCK'
- )
- await mockToken.deployed()
- await mockToken.approve(linearVestingNFT.address, '1000000000000000000000')
-
- accounts = await ethers.getSigners()
- receiverAccount = await accounts[1].getAddress()
- unlockTime = await createVestingNft(
- linearVestingNFT,
- receiverAccount,
- mockToken
- )
- })
-
- it('Returns a valid vested payout', async function () {
- // TODO: More extensive testing of linear vesting functionality
- const totalPayout = await linearVestingNFT.vestedPayoutAtTime(0, unlockTime)
- expect(await linearVestingNFT.vestedPayout(0)).to.equal(0)
- await increaseTime(testValues.totalLock)
- expect(await linearVestingNFT.vestedPayout(0)).to.equal(totalPayout)
- })
-
- it('Reverts when creating to account 0', async function () {
- const latestBlock = await ethers.provider.getBlock('latest')
- await expect(
- linearVestingNFT.create(
- '0x0000000000000000000000000000000000000000',
- testValues.payout,
- latestBlock.timestamp + testValues.buffer,
- testValues.lockTime,
- 0,
- mockToken.address
- )
- ).to.revertedWith('to cannot be address 0')
- })
-
- it('Reverts when creating to past start date 0', async function () {
- await expect(
- linearVestingNFT.create(
- receiverAccount,
- testValues.payout,
- 0,
- testValues.lockTime,
- 0,
- mockToken.address
- )
- ).to.revertedWith('startTime cannot be on the past')
- })
-
- it('Reverts when duration is less than cliff', async function () {
- const latestBlock = await ethers.provider.getBlock('latest')
- await expect(
- linearVestingNFT.create(
- receiverAccount,
- testValues.payout,
- latestBlock.timestamp + testValues.buffer,
- testValues.lockTime,
- 100,
- mockToken.address
- )
- ).to.revertedWith('duration needs to be more than cliff')
- })
-})
-
-async function createVestingNft(
- linearVestingNFT: LinearVestingNFT,
- receiverAccount: string,
- mockToken: ERC20Mock
-) {
- const latestBlock = await ethers.provider.getBlock('latest')
- const unlockTime =
- latestBlock.timestamp + testValues.lockTime + testValues.buffer
- const txReceipt = await linearVestingNFT.create(
- receiverAccount,
- testValues.payout,
- latestBlock.timestamp + testValues.buffer,
- testValues.lockTime,
- 0,
- mockToken.address
- )
- await txReceipt.wait()
- return unlockTime
-}
diff --git a/assets/eip-5725/test/VestingNFT.test.ts b/assets/eip-5725/test/VestingNFT.test.ts
deleted file mode 100644
index cc2893e..0000000
--- a/assets/eip-5725/test/VestingNFT.test.ts
+++ /dev/null
@@ -1,175 +0,0 @@
-import { ethers } from 'hardhat'
-import { Signer } from 'ethers'
-import { expect } from 'chai'
-import { increaseTime } from './helpers/time'
-// typechain
-import { ERC20Mock, VestingNFT } from '../typechain-types'
-
-const testValues = {
- payout: '1000000000',
- lockTime: 60,
-}
-
-describe('VestingNFT', function () {
- let accounts: Signer[]
- let vestingNFT: VestingNFT
- let mockToken: ERC20Mock
- let receiverAccount: string
- let unlockTime: number
-
- beforeEach(async function () {
- const VestingNFT = await ethers.getContractFactory('VestingNFT')
- vestingNFT = await VestingNFT.deploy('VestingNFT', 'TLV')
- await vestingNFT.deployed()
-
- const ERC20Mock = await ethers.getContractFactory('ERC20Mock')
- mockToken = await ERC20Mock.deploy(
- '1000000000000000000000',
- 18,
- 'LockedToken',
- 'LOCK'
- )
- await mockToken.deployed()
- await mockToken.approve(vestingNFT.address, '1000000000000000000000')
-
- accounts = await ethers.getSigners()
- receiverAccount = await accounts[1].getAddress()
- unlockTime = await createVestingNft(vestingNFT, receiverAccount, mockToken)
- })
-
- it('Supports ERC721 and IERC5725 interfaces', async function () {
- expect(await vestingNFT.supportsInterface('0x80ac58cd')).to.equal(true)
-
- /**
- * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified
- * // Solidity export interface id:
- * bytes4 public constant IID_ITEST = type(IERC5725).interfaceId;
- * // Pull out the interfaceId in tests
- * const interfaceId = await vestingNFT.IID_ITEST();
- */
- // Vesting NFT Interface ID
- expect(await vestingNFT.supportsInterface('0xf8600f8b')).to.equal(true)
- })
-
- it('Returns a valid vested payout', async function () {
- const totalPayout = await vestingNFT.vestedPayoutAtTime(0, unlockTime)
- expect(await vestingNFT.vestedPayout(0)).to.equal(0)
- await increaseTime(testValues.lockTime)
- expect(await vestingNFT.vestedPayout(0)).to.equal(totalPayout)
- })
-
- it('Reverts with invalid ID', async function () {
- await expect(vestingNFT.vestedPayout(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.vestedPayoutAtTime(1, unlockTime)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.vestingPayout(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.claimablePayout(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.vestingPeriod(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.payoutToken(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- await expect(vestingNFT.claim(1)).to.revertedWith(
- 'VestingNFT: invalid token ID'
- )
- // NOTE: Removed claimTo from spec
- // await expect(vestingNFT.claimTo(1, receiverAccount)).to.revertedWith(
- // "VestingNFT: invalid token ID"
- // );
- })
-
- it('Returns a valid pending payout', async function () {
- expect(await vestingNFT.vestingPayout(0)).to.equal(testValues.payout)
- })
-
- it('Returns a valid releasable payout', async function () {
- const totalPayout = await vestingNFT.vestedPayoutAtTime(0, unlockTime)
- expect(await vestingNFT.claimablePayout(0)).to.equal(0)
- await increaseTime(testValues.lockTime)
- expect(await vestingNFT.claimablePayout(0)).to.equal(totalPayout)
- })
-
- it('Returns a valid vesting period', async function () {
- const vestingPeriod = await vestingNFT.vestingPeriod(0)
- expect(vestingPeriod.vestingEnd).to.equal(unlockTime)
- })
-
- it('Returns a valid payout token', async function () {
- expect(await vestingNFT.payoutToken(0)).to.equal(mockToken.address)
- })
-
- it('Is able to claim', async function () {
- const connectedVestingNft = vestingNFT.connect(accounts[1])
- await increaseTime(testValues.lockTime)
- const txReceipt = await connectedVestingNft.claim(0)
- await txReceipt.wait()
- expect(await mockToken.balanceOf(receiverAccount)).to.equal(
- testValues.payout
- )
- })
-
- it('Reverts claim when payout is 0', async function () {
- const connectedVestingNft = vestingNFT.connect(accounts[1])
- await expect(connectedVestingNft.claim(0)).to.revertedWith(
- 'VestingNFT: No pending payout'
- )
- })
-
- it('Reverts claim when payout is not from owner', async function () {
- const connectedVestingNft = vestingNFT.connect(accounts[2])
- await expect(connectedVestingNft.claim(0)).to.revertedWith(
- 'Not owner of NFT'
- )
- })
-
- // NOTE: Removed claimTo from spec
- // it("Is able to claim to other account", async function () {
- // const connectedVestingNft = vestingNFT.connect(accounts[1]);
- // const otherReceiverAddress = await accounts[2].getAddress();
- // await increaseTime(testValues.lockTime);
- // const txReceipt = await connectedVestingNft.claimTo(
- // 0,
- // otherReceiverAddress
- // );
- // await txReceipt.wait();
- // expect(await mockToken.balanceOf(otherReceiverAddress)).to.equal(
- // testValues.payout
- // );
- // });
-
- it('Reverts when creating to account 0', async function () {
- await expect(
- vestingNFT.create(
- '0x0000000000000000000000000000000000000000',
- testValues.payout,
- unlockTime,
- mockToken.address
- )
- ).to.revertedWith('to cannot be address 0')
- })
-})
-
-async function createVestingNft(
- vestingNFT: VestingNFT,
- receiverAccount: string,
- mockToken: ERC20Mock
-) {
- const latestBlock = await ethers.provider.getBlock('latest')
- const unlockTime = latestBlock.timestamp + testValues.lockTime
- const txReceipt = await vestingNFT.create(
- receiverAccount,
- testValues.payout,
- unlockTime,
- mockToken.address
- )
- await txReceipt.wait()
- return unlockTime
-}
diff --git a/assets/eip-5725/test/helpers/time.ts b/assets/eip-5725/test/helpers/time.ts
deleted file mode 100644
index 6e99622..0000000
--- a/assets/eip-5725/test/helpers/time.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import { ethers } from 'hardhat'
-
-async function mineNBlocks(n: number) {
- for (let index = 0; index < n; index++) {
- await ethers.provider.send('evm_mine', [])
- }
-}
-
-export async function increaseTime(seconds: number) {
- await ethers.provider.send('evm_increaseTime', [seconds])
- await mineNBlocks(1)
-}
diff --git a/assets/eip-5773/contracts/IERC5773.sol b/assets/eip-5773/contracts/IERC5773.sol
deleted file mode 100644
index d864585..0000000
--- a/assets/eip-5773/contracts/IERC5773.sol
+++ /dev/null
@@ -1,92 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5773 {
- event AssetSet(uint64 assetId);
-
- event AssetAddedToTokens(
- uint256[] tokenId,
- uint64 indexed assetId,
- uint64 indexed replacesId
- );
-
- event AssetAccepted(
- uint256 indexed tokenId,
- uint64 indexed assetId,
- uint64 indexed replacesId
- );
-
- event AssetRejected(uint256 indexed tokenId, uint64 indexed assetId);
-
- event AssetPrioritySet(uint256 indexed tokenId);
-
- event ApprovalForAssets(
- address indexed owner,
- address indexed approved,
- uint256 indexed tokenId
- );
-
- event ApprovalForAllForAssets(
- address indexed owner,
- address indexed operator,
- bool approved
- );
-
- function acceptAsset(
- uint256 tokenId,
- uint256 index,
- uint64 assetId
- ) external;
-
- function rejectAsset(
- uint256 tokenId,
- uint256 index,
- uint64 assetId
- ) external;
-
- function rejectAllAssets(uint256 tokenId, uint256 maxRejections) external;
-
- function setPriority(
- uint256 tokenId,
- uint64[] calldata priorities
- ) external;
-
- function getActiveAssets(
- uint256 tokenId
- ) external view returns (uint64[] memory);
-
- function getPendingAssets(
- uint256 tokenId
- ) external view returns (uint64[] memory);
-
- function getActiveAssetPriorities(
- uint256 tokenId
- ) external view returns (uint64[] memory);
-
- function getAssetReplacements(
- uint256 tokenId,
- uint64 newAssetId
- ) external view returns (uint64);
-
- function getAssetMetadata(
- uint256 tokenId,
- uint64 assetId
- ) external view returns (string memory);
-
- function approveForAssets(address to, uint256 tokenId) external;
-
- function getApprovedForAssets(
- uint256 tokenId
- ) external view returns (address);
-
- function setApprovalForAllForAssets(
- address operator,
- bool approved
- ) external;
-
- function isApprovedForAllForAssets(
- address owner,
- address operator
- ) external view returns (bool);
-}
diff --git a/assets/eip-5773/contracts/MultiAssetToken.sol b/assets/eip-5773/contracts/MultiAssetToken.sol
deleted file mode 100644
index 089fc83..0000000
--- a/assets/eip-5773/contracts/MultiAssetToken.sol
+++ /dev/null
@@ -1,684 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.15;
-
-import "./IERC5773.sol";
-import "./library/MultiAssetLib.sol";
-import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
-import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import "@openzeppelin/contracts/utils/Address.sol";
-import "@openzeppelin/contracts/utils/Strings.sol";
-import "@openzeppelin/contracts/utils/Context.sol";
-
-contract MultiAssetToken is Context, IERC721, IERC5773 {
- using MultiAssetLib for uint256;
- using MultiAssetLib for uint64[];
- using MultiAssetLib for uint128[];
- using Address for address;
- using Strings for uint256;
-
- // Token name
- string private _name;
-
- // Token symbol
- string private _symbol;
-
- // Mapping from token ID to owner address
- mapping(uint256 => address) private _owners;
-
- // Mapping owner address to token count
- mapping(address => uint256) private _balances;
-
- // Mapping from token ID to approved address
- mapping(uint256 => address) private _tokenApprovals;
-
- // Mapping from owner to operator approvals
- mapping(address => mapping(address => bool)) private _operatorApprovals;
-
- // Mapping from token ID to approved address for assets
- mapping(uint256 => address) internal _tokenApprovalsForAssets;
-
- // Mapping from owner to operator approvals for assets
- mapping(address => mapping(address => bool))
- internal _operatorApprovalsForAssets;
-
- //mapping of uint64 Ids to asset object
- mapping(uint64 => string) internal _assets;
-
- //mapping of tokenId to new asset, to asset to be replaced
- mapping(uint256 => mapping(uint64 => uint64)) private _assetReplacements;
-
- //mapping of tokenId to all assets
- mapping(uint256 => uint64[]) internal _activeAssets;
-
- //mapping of tokenId to an array of asset priorities
- mapping(uint256 => uint64[]) internal _activeAssetPriorities;
-
- //Double mapping of tokenId to active assets
- mapping(uint256 => mapping(uint64 => bool)) private _tokenAssets;
-
- //mapping of tokenId to all assets by priority
- mapping(uint256 => uint64[]) internal _pendingAssets;
-
- constructor(string memory name_, string memory symbol_) {
- _name = name_;
- _symbol = symbol_;
- }
-
- ////////////////////////////////////////
- // ERC-721 COMPLIANCE
- ////////////////////////////////////////
-
- function supportsInterface(bytes4 interfaceId) public view returns (bool) {
- return
- interfaceId == type(IERC5773).interfaceId ||
- interfaceId == type(IERC721).interfaceId ||
- interfaceId == type(IERC165).interfaceId;
- }
-
- function balanceOf(
- address owner
- ) public view virtual override returns (uint256) {
- require(
- owner != address(0),
- "ERC721: address zero is not a valid owner"
- );
- return _balances[owner];
- }
-
- function ownerOf(
- uint256 tokenId
- ) public view virtual override returns (address) {
- address owner = _owners[tokenId];
- require(
- owner != address(0),
- "ERC721: owner query for nonexistent token"
- );
- return owner;
- }
-
- function name() public view virtual returns (string memory) {
- return _name;
- }
-
- function symbol() public view virtual returns (string memory) {
- return _symbol;
- }
-
- function approve(address to, uint256 tokenId) public virtual {
- address owner = ownerOf(tokenId);
- require(to != owner, "MultiAsset: approval to current owner");
- require(
- _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
- "MultiAsset: approve caller is not owner nor approved for all"
- );
-
- _approve(to, tokenId);
- }
-
- function approveForAssets(address to, uint256 tokenId) external virtual {
- address owner = ownerOf(tokenId);
- require(to != owner, "MultiAsset: approval to current owner");
- require(
- _msgSender() == owner ||
- isApprovedForAllForAssets(owner, _msgSender()),
- "MultiAsset: approve caller is not owner nor approved for all"
- );
- _approveForAssets(to, tokenId);
- }
-
- function getApproved(
- uint256 tokenId
- ) public view virtual override returns (address) {
- require(
- _exists(tokenId),
- "MultiAsset: approved query for nonexistent token"
- );
-
- return _tokenApprovals[tokenId];
- }
-
- function getApprovedForAssets(
- uint256 tokenId
- ) public view virtual returns (address) {
- require(
- _exists(tokenId),
- "MultiAsset: approved query for nonexistent token"
- );
- return _tokenApprovalsForAssets[tokenId];
- }
-
- function setApprovalForAll(
- address operator,
- bool approved
- ) public virtual override {
- _setApprovalForAll(_msgSender(), operator, approved);
- }
-
- function isApprovedForAll(
- address owner,
- address operator
- ) public view virtual override returns (bool) {
- return _operatorApprovals[owner][operator];
- }
-
- function setApprovalForAllForAssets(
- address operator,
- bool approved
- ) public virtual override {
- _setApprovalForAllForAssets(_msgSender(), operator, approved);
- }
-
- function isApprovedForAllForAssets(
- address owner,
- address operator
- ) public view virtual returns (bool) {
- return _operatorApprovalsForAssets[owner][operator];
- }
-
- function transferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public virtual override {
- //solhint-disable-next-line max-line-length
- require(
- _isApprovedOrOwner(_msgSender(), tokenId),
- "MultiAsset: transfer caller is not owner nor approved"
- );
-
- _transfer(from, to, tokenId);
- }
-
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId
- ) public virtual override {
- safeTransferFrom(from, to, tokenId, "");
- }
-
- function safeTransferFrom(
- address from,
- address to,
- uint256 tokenId,
- bytes memory data
- ) public virtual override {
- require(
- _isApprovedOrOwner(_msgSender(), tokenId),
- "MultiAsset: transfer caller is not owner nor approved"
- );
- _safeTransfer(from, to, tokenId, data);
- }
-
- function _safeTransfer(
- address from,
- address to,
- uint256 tokenId,
- bytes memory data
- ) internal virtual {
- _transfer(from, to, tokenId);
- require(
- _checkOnERC721Received(from, to, tokenId, data),
- "MultiAsset: transfer to non ERC721 Receiver implementer"
- );
- }
-
- function _exists(uint256 tokenId) internal view virtual returns (bool) {
- return _owners[tokenId] != address(0);
- }
-
- function _isApprovedOrOwner(
- address spender,
- uint256 tokenId
- ) internal view virtual returns (bool) {
- require(
- _exists(tokenId),
- "MultiAsset: approved query for nonexistent token"
- );
- address owner = ownerOf(tokenId);
- return (spender == owner ||
- isApprovedForAll(owner, spender) ||
- getApproved(tokenId) == spender);
- }
-
- function _isApprovedForAssetsOrOwner(
- address user,
- uint256 tokenId
- ) internal view virtual returns (bool) {
- require(
- _exists(tokenId),
- "MultiAsset: approved query for nonexistent token"
- );
- address owner = ownerOf(tokenId);
- return (user == owner ||
- isApprovedForAllForAssets(owner, user) ||
- getApprovedForAssets(tokenId) == user);
- }
-
- function _safeMint(address to, uint256 tokenId) internal virtual {
- _safeMint(to, tokenId, "");
- }
-
- function _safeMint(
- address to,
- uint256 tokenId,
- bytes memory data
- ) internal virtual {
- _mint(to, tokenId);
- require(
- _checkOnERC721Received(address(0), to, tokenId, data),
- "MultiAsset: transfer to non ERC721 Receiver implementer"
- );
- }
-
- function _mint(address to, uint256 tokenId) internal virtual {
- require(to != address(0), "MultiAsset: mint to the zero address");
- require(!_exists(tokenId), "MultiAsset: token already minted");
-
- _beforeTokenTransfer(address(0), to, tokenId);
-
- _balances[to] += 1;
- _owners[tokenId] = to;
-
- emit Transfer(address(0), to, tokenId);
-
- _afterTokenTransfer(address(0), to, tokenId);
- }
-
- function _burn(uint256 tokenId) internal virtual {
- // WARNING: If you intend to allow the reminting of a burned token, you
- // might want to clean the assets for the token, that is:
- // _pendingAssets, _activeAssets, _assetReplacements
- // _activeAssetPriorities and _tokenAssets.
- address owner = ownerOf(tokenId);
-
- _beforeTokenTransfer(owner, address(0), tokenId);
-
- // Clear approvals
- _approve(address(0), tokenId);
- _approveForAssets(address(0), tokenId);
-
- _balances[owner] -= 1;
- delete _owners[tokenId];
-
- emit Transfer(owner, address(0), tokenId);
-
- _afterTokenTransfer(owner, address(0), tokenId);
- }
-
- function _transfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual {
- require(
- ownerOf(tokenId) == from,
- "MultiAsset: transfer from incorrect owner"
- );
- require(to != address(0), "MultiAsset: transfer to the zero address");
-
- _beforeTokenTransfer(from, to, tokenId);
-
- // Clear approvals from the previous owner
- _approve(address(0), tokenId);
- _approveForAssets(address(0), tokenId);
-
- _balances[from] -= 1;
- _balances[to] += 1;
- _owners[tokenId] = to;
-
- emit Transfer(from, to, tokenId);
-
- _afterTokenTransfer(from, to, tokenId);
- }
-
- function _approve(address to, uint256 tokenId) internal virtual {
- _tokenApprovals[tokenId] = to;
- emit Approval(ownerOf(tokenId), to, tokenId);
- }
-
- function _approveForAssets(address to, uint256 tokenId) internal virtual {
- _tokenApprovalsForAssets[tokenId] = to;
- emit ApprovalForAssets(ownerOf(tokenId), to, tokenId);
- }
-
- function _setApprovalForAll(
- address owner,
- address operator,
- bool approved
- ) internal virtual {
- require(owner != operator, "MultiAsset: approve to caller");
- _operatorApprovals[owner][operator] = approved;
- emit ApprovalForAll(owner, operator, approved);
- }
-
- function _setApprovalForAllForAssets(
- address owner,
- address operator,
- bool approved
- ) internal virtual {
- require(owner != operator, "MultiAsset: approve to caller");
- _operatorApprovalsForAssets[owner][operator] = approved;
- emit ApprovalForAllForAssets(owner, operator, approved);
- }
-
- function _checkOnERC721Received(
- address from,
- address to,
- uint256 tokenId,
- bytes memory data
- ) private returns (bool) {
- if (to.isContract()) {
- try
- IERC721Receiver(to).onERC721Received(
- _msgSender(),
- from,
- tokenId,
- data
- )
- returns (bytes4 retval) {
- return retval == IERC721Receiver.onERC721Received.selector;
- } catch (bytes memory reason) {
- if (reason.length == 0) {
- revert(
- "MultiAsset: transfer to non ERC721 Receiver implementer"
- );
- } else {
- /// @solidity memory-safe-assembly
- assembly {
- revert(add(32, reason), mload(reason))
- }
- }
- }
- } else {
- return true;
- }
- }
-
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual {}
-
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 tokenId
- ) internal virtual {}
-
- ////////////////////////////////////////
- // ASSETS
- ////////////////////////////////////////
-
- function acceptAsset(
- uint256 tokenId,
- uint256 index,
- uint64 assetId
- ) external virtual {
- require(
- index < _pendingAssets[tokenId].length,
- "MultiAsset: index out of bounds"
- );
- require(
- _isApprovedForAssetsOrOwner(_msgSender(), tokenId),
- "MultiAsset: not owner or approved"
- );
- require(
- assetId == _pendingAssets[tokenId][index],
- "MultiAsset: Unexpected asset"
- );
-
- _beforeAcceptAsset(tokenId, index, assetId);
- uint64 replacesId = _assetReplacements[tokenId][assetId];
- uint256 replaceIndex;
- bool replacefound;
- if (replacesId != uint64(0))
- (replaceIndex, replacefound) = _activeAssets[tokenId].indexOf(
- replacesId
- );
-
- if (replacefound) {
- // We don't want to remove and then push a new asset.
- // This way we also keep the priority of the original resource
- _activeAssets[tokenId][replaceIndex] = assetId;
- delete _tokenAssets[tokenId][replacesId];
- } else {
- // We use the current size as next priority, by default priorities would be [0,1,2...]
- _activeAssetPriorities[tokenId].push(
- uint64(_activeAssets[tokenId].length)
- );
- _activeAssets[tokenId].push(assetId);
- replacesId = uint64(0);
- }
- _pendingAssets[tokenId].removeItemByIndex(index);
- delete _assetReplacements[tokenId][assetId];
-
- emit AssetAccepted(tokenId, assetId, replacesId);
- _afterAcceptAsset(tokenId, index, assetId);
- }
-
- function rejectAsset(
- uint256 tokenId,
- uint256 index,
- uint64 assetId
- ) external virtual {
- require(
- index < _pendingAssets[tokenId].length,
- "MultiAsset: index out of bounds"
- );
- require(
- _pendingAssets[tokenId].length > index,
- "MultiAsset: Pending asset index out of range"
- );
- require(
- _isApprovedForAssetsOrOwner(_msgSender(), tokenId),
- "MultiAsset: not owner or approved"
- );
-
- _beforeRejectAsset(tokenId, index, assetId);
- _pendingAssets[tokenId].removeItemByIndex(index);
- delete _tokenAssets[tokenId][assetId];
- delete _assetReplacements[tokenId][assetId];
-
- emit AssetRejected(tokenId, assetId);
- _afterRejectAsset(tokenId, index, assetId);
- }
-
- function rejectAllAssets(
- uint256 tokenId,
- uint256 maxRejections
- ) external virtual {
- require(
- _isApprovedForAssetsOrOwner(_msgSender(), tokenId),
- "MultiAsset: not owner or approved"
- );
-
- uint256 len = _pendingAssets[tokenId].length;
- if (len > maxRejections) revert("Unexpected number of assets");
-
- _beforeRejectAllAssets(tokenId);
- for (uint256 i; i < len; ) {
- uint64 assetId = _pendingAssets[tokenId][i];
- delete _assetReplacements[tokenId][assetId];
- unchecked {
- ++i;
- }
- }
- delete (_pendingAssets[tokenId]);
-
- emit AssetRejected(tokenId, uint64(0));
- _afterRejectAllAssets(tokenId);
- }
-
- function setPriority(
- uint256 tokenId,
- uint64[] memory priorities
- ) external virtual {
- uint256 length = priorities.length;
- require(
- length == _activeAssets[tokenId].length,
- "MultiAsset: Bad priority list length"
- );
- require(
- _isApprovedForAssetsOrOwner(_msgSender(), tokenId),
- "MultiAsset: not owner or approved"
- );
-
- _beforeSetPriority(tokenId, priorities);
- _activeAssetPriorities[tokenId] = priorities;
-
- emit AssetPrioritySet(tokenId);
- _afterSetPriority(tokenId, priorities);
- }
-
- function getActiveAssets(
- uint256 tokenId
- ) public view virtual returns (uint64[] memory) {
- return _activeAssets[tokenId];
- }
-
- function getPendingAssets(
- uint256 tokenId
- ) public view virtual returns (uint64[] memory) {
- return _pendingAssets[tokenId];
- }
-
- function getActiveAssetPriorities(
- uint256 tokenId
- ) public view virtual returns (uint64[] memory) {
- return _activeAssetPriorities[tokenId];
- }
-
- function getAssetReplacements(
- uint256 tokenId,
- uint64 newAssetId
- ) public view virtual returns (uint64) {
- return _assetReplacements[tokenId][newAssetId];
- }
-
- function getAssetMetadata(
- uint256 tokenId,
- uint64 assetId
- ) public view virtual returns (string memory) {
- if (!_tokenAssets[tokenId][assetId])
- revert("MultiAsset: Token does not have asset");
- return _assets[assetId];
- }
-
- function tokenURI(
- uint256 tokenId
- ) public view virtual returns (string memory) {
- return "";
- }
-
- // To be implemented with custom guards
-
- function _addAssetEntry(uint64 id, string memory metadataURI) internal {
- require(id != uint64(0), "RMRK: Write to zero");
- require(bytes(_assets[id]).length == 0, "RMRK: asset already exists");
-
- _beforeAddAsset(id, metadataURI);
- _assets[id] = metadataURI;
-
- emit AssetSet(id);
- _afterAddAsset(id, metadataURI);
- }
-
- function _addAssetToToken(
- uint256 tokenId,
- uint64 assetId,
- uint64 replacesAssetWithId
- ) internal {
- require(
- !_tokenAssets[tokenId][assetId],
- "MultiAsset: Asset already exists on token"
- );
-
- require(
- bytes(_assets[assetId]).length != 0,
- "MultiAsset: Asset not found in storage"
- );
-
- require(
- _pendingAssets[tokenId].length < 128,
- "MultiAsset: Max pending assets reached"
- );
-
- _beforeAddAssetToToken(tokenId, assetId, replacesAssetWithId);
- _tokenAssets[tokenId][assetId] = true;
- _pendingAssets[tokenId].push(assetId);
-
- if (replacesAssetWithId != uint64(0)) {
- _assetReplacements[tokenId][assetId] = replacesAssetWithId;
- }
-
- uint256[] memory tokenIds = new uint256[](1);
- tokenIds[0] = tokenId;
- emit AssetAddedToTokens(tokenIds, assetId, replacesAssetWithId);
- _afterAddAssetToToken(tokenId, assetId, replacesAssetWithId);
- }
-
- // HOOKS
-
- function _beforeAddAsset(
- uint64 id,
- string memory metadataURI
- ) internal virtual {}
-
- function _afterAddAsset(
- uint64 id,
- string memory metadataURI
- ) internal virtual {}
-
- function _beforeAddAssetToToken(
- uint256 tokenId,
- uint64 assetId,
- uint64 replacesAssetWithId
- ) internal virtual {}
-
- function _afterAddAssetToToken(
- uint256 tokenId,
- uint64 assetId,
- uint64 replacesAssetWithId
- ) internal virtual {}
-
- function _beforeAcceptAsset(
- uint256 tokenId,
- uint256 index,
- uint256 assetId
- ) internal virtual {}
-
- function _afterAcceptAsset(
- uint256 tokenId,
- uint256 index,
- uint256 assetId
- ) internal virtual {}
-
- function _beforeRejectAsset(
- uint256 tokenId,
- uint256 index,
- uint256 assetId
- ) internal virtual {}
-
- function _afterRejectAsset(
- uint256 tokenId,
- uint256 index,
- uint256 assetId
- ) internal virtual {}
-
- function _beforeRejectAllAssets(uint256 tokenId) internal virtual {}
-
- function _afterRejectAllAssets(uint256 tokenId) internal virtual {}
-
- function _beforeSetPriority(
- uint256 tokenId,
- uint64[] memory priorities
- ) internal virtual {}
-
- function _afterSetPriority(
- uint256 tokenId,
- uint64[] memory priorities
- ) internal virtual {}
-}
diff --git a/assets/eip-5773/contracts/library/MultiAssetLib.sol b/assets/eip-5773/contracts/library/MultiAssetLib.sol
deleted file mode 100644
index 24a9cc0..0000000
--- a/assets/eip-5773/contracts/library/MultiAssetLib.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-library MultiAssetLib {
- function indexOf(
- uint64[] memory A,
- uint64 a
- ) internal pure returns (uint256, bool) {
- uint256 length = A.length;
- for (uint256 i; i < length; ) {
- if (A[i] == a) {
- return (i, true);
- }
- unchecked {
- ++i;
- }
- }
- return (0, false);
- }
-
- //For reasource storage array
- function removeItemByIndex(uint64[] storage array, uint256 index) internal {
- //Check to see if this is already gated by require in all calls
- require(index < array.length);
- array[index] = array[array.length - 1];
- array.pop();
- }
-}
diff --git a/assets/eip-5773/contracts/mocks/ERC721ReceiverMock.sol b/assets/eip-5773/contracts/mocks/ERC721ReceiverMock.sol
deleted file mode 100644
index 1f0665b..0000000
--- a/assets/eip-5773/contracts/mocks/ERC721ReceiverMock.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.15;
-
-contract ERC721ReceiverMock {
- bytes4 constant ERC721_RECEIVED = 0x150b7a02;
-
- function onERC721Received(
- address,
- address,
- uint256,
- bytes calldata
- ) public returns (bytes4) {
- return ERC721_RECEIVED;
- }
-}
diff --git a/assets/eip-5773/contracts/mocks/MultiAssetTokenMock.sol b/assets/eip-5773/contracts/mocks/MultiAssetTokenMock.sol
deleted file mode 100644
index 0ceafe7..0000000
--- a/assets/eip-5773/contracts/mocks/MultiAssetTokenMock.sol
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.15;
-
-import "../MultiAssetToken.sol";
-
-contract MultiAssetTokenMock is MultiAssetToken {
- address private _issuer;
-
- constructor(
- string memory name,
- string memory symbol
- ) MultiAssetToken(name, symbol) {
- _setIssuer(_msgSender());
- }
-
- modifier onlyIssuer() {
- require(_msgSender() == _issuer, "RMRK: Only issuer");
- _;
- }
-
- function setIssuer(address issuer) external onlyIssuer {
- _setIssuer(issuer);
- }
-
- function getIssuer() external view returns (address) {
- return _issuer;
- }
-
- function mint(address to, uint256 tokenId) external onlyIssuer {
- _mint(to, tokenId);
- }
-
- function transfer(address to, uint256 tokenId) external {
- _transfer(msg.sender, to, tokenId);
- }
-
- function burn(uint256 tokenId) external {
- _burn(tokenId);
- }
-
- function addAssetToToken(
- uint256 tokenId,
- uint64 assetId,
- uint64 overwrites
- ) external onlyIssuer {
- _addAssetToToken(tokenId, assetId, overwrites);
- }
-
- function addAssetEntry(
- uint64 id,
- string memory metadataURI
- ) external onlyIssuer {
- _addAssetEntry(id, metadataURI);
- }
-
- function _setIssuer(address issuer) private {
- _issuer = issuer;
- }
-}
diff --git a/assets/eip-5773/contracts/mocks/NonReceiverMock.sol b/assets/eip-5773/contracts/mocks/NonReceiverMock.sol
deleted file mode 100644
index e9d2d6e..0000000
--- a/assets/eip-5773/contracts/mocks/NonReceiverMock.sol
+++ /dev/null
@@ -1,7 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.15;
-
-contract NonReceiverMock {
- function dummy() external {}
-}
diff --git a/assets/eip-5773/contracts/utils/MultiAssetRenderUtils.sol b/assets/eip-5773/contracts/utils/MultiAssetRenderUtils.sol
deleted file mode 100644
index 4a1ccbc..0000000
--- a/assets/eip-5773/contracts/utils/MultiAssetRenderUtils.sol
+++ /dev/null
@@ -1,143 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-import "../IERC5773.sol";
-
-pragma solidity ^0.8.15;
-
-/**
- * @dev Extra utility functions for composing RMRK assets.
- */
-
-contract MultiAssetRenderUtils {
- uint64 private constant _LOWEST_POSSIBLE_PRIORITY = 2 ** 16 - 1;
-
- struct ActiveAsset {
- uint64 id;
- uint64 priority;
- string metadata;
- }
-
- struct PendingAsset {
- uint64 id;
- uint128 acceptRejectIndex;
- uint64 overwritesAssetWithId;
- string metadata;
- }
-
- function getActiveAssets(
- address target,
- uint256 tokenId
- ) public view virtual returns (ActiveAsset[] memory) {
- IERC5773 target_ = IERC5773(target);
-
- uint64[] memory assets = target_.getActiveAssets(tokenId);
- uint64[] memory priorities = target_.getActiveAssetPriorities(tokenId);
- uint256 len = assets.length;
- if (len == 0) {
- revert("Token has no assets");
- }
-
- ActiveAsset[] memory activeAssets = new ActiveAsset[](len);
- string memory metadata;
- for (uint256 i; i < len; ) {
- metadata = target_.getAssetMetadata(tokenId, assets[i]);
- activeAssets[i] = ActiveAsset({
- id: assets[i],
- priority: priorities[i],
- metadata: metadata
- });
- unchecked {
- ++i;
- }
- }
- return activeAssets;
- }
-
- function getPendingAssets(
- address target,
- uint256 tokenId
- ) public view virtual returns (PendingAsset[] memory) {
- IERC5773 target_ = IERC5773(target);
-
- uint64[] memory assets = target_.getPendingAssets(tokenId);
- uint256 len = assets.length;
- if (len == 0) {
- revert("Token has no assets");
- }
-
- PendingAsset[] memory pendingAssets = new PendingAsset[](len);
- string memory metadata;
- uint64 overwritesAssetWithId;
- for (uint256 i; i < len; ) {
- metadata = target_.getAssetMetadata(tokenId, assets[i]);
- overwritesAssetWithId = target_.getAssetReplacements(
- tokenId,
- assets[i]
- );
- pendingAssets[i] = PendingAsset({
- id: assets[i],
- acceptRejectIndex: uint128(i),
- overwritesAssetWithId: overwritesAssetWithId,
- metadata: metadata
- });
- unchecked {
- ++i;
- }
- }
- return pendingAssets;
- }
-
- /**
- * @notice Returns asset metadata strings for the given ids
- *
- * Requirements:
- *
- * - `assetIds` must exist.
- */
- function getAssetsById(
- address target,
- uint256 tokenId,
- uint64[] calldata assetIds
- ) public view virtual returns (string[] memory) {
- IERC5773 target_ = IERC5773(target);
- uint256 len = assetIds.length;
- string[] memory assets = new string[](len);
- for (uint256 i; i < len; ) {
- assets[i] = target_.getAssetMetadata(tokenId, assetIds[i]);
- unchecked {
- ++i;
- }
- }
- return assets;
- }
-
- /**
- * @notice Returns the asset metadata with the highest priority for the given token
- */
- function getTopAssetMetaForToken(
- address target,
- uint256 tokenId
- ) external view returns (string memory) {
- IERC5773 target_ = IERC5773(target);
- uint64[] memory priorities = target_.getActiveAssetPriorities(tokenId);
- uint64[] memory assets = target_.getActiveAssets(tokenId);
- uint256 len = priorities.length;
- if (len == 0) {
- revert("Token has no assets");
- }
-
- uint64 maxPriority = _LOWEST_POSSIBLE_PRIORITY;
- uint64 maxPriorityAsset;
- for (uint64 i; i < len; ) {
- uint64 currentPrio = priorities[i];
- if (currentPrio < maxPriority) {
- maxPriority = currentPrio;
- maxPriorityAsset = assets[i];
- }
- unchecked {
- ++i;
- }
- }
- return target_.getAssetMetadata(tokenId, maxPriorityAsset);
- }
-}
diff --git a/assets/eip-5773/hardhat.config.ts b/assets/eip-5773/hardhat.config.ts
deleted file mode 100644
index 1c14d97..0000000
--- a/assets/eip-5773/hardhat.config.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { HardhatUserConfig } from "hardhat/config";
-import "@nomicfoundation/hardhat-chai-matchers";
-import "@nomiclabs/hardhat-etherscan";
-import "@typechain/hardhat";
-import "hardhat-contract-sizer";
-import "hardhat-gas-reporter";
-import "solidity-coverage";
-
-const config: HardhatUserConfig = {
- solidity: {
- version: "0.8.15",
- settings: {
- optimizer: {
- enabled: true,
- runs: 200,
- },
- },
- },
-};
-
-export default config;
diff --git a/assets/eip-5773/package.json b/assets/eip-5773/package.json
deleted file mode 100644
index e6f2346..0000000
--- a/assets/eip-5773/package.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "name": "eip-5773",
- "dependencies": {
- "@openzeppelin/contracts": "^4.6.0"
- },
- "devDependencies": {
- "@nomicfoundation/hardhat-chai-matchers": "^1.0.1",
- "@nomicfoundation/hardhat-network-helpers": "^1.0.3",
- "@nomiclabs/hardhat-ethers": "^2.2.1",
- "@nomiclabs/hardhat-etherscan": "^3.1.0",
- "@openzeppelin/test-helpers": "^0.5.15",
- "@primitivefi/hardhat-dodoc": "^0.2.3",
- "@typechain/ethers-v5": "^10.1.0",
- "@typechain/hardhat": "^6.1.2",
- "@types/chai": "^4.3.1",
- "@types/mocha": "^9.1.0",
- "@types/node": "^18.0.3",
- "@typescript-eslint/eslint-plugin": "^5.30.6",
- "@typescript-eslint/parser": "^5.30.6",
- "chai": "^4.3.6",
- "eslint": "^8.27.0",
- "eslint-config-prettier": "^8.5.0",
- "eslint-plugin-import": "^2.26.0",
- "eslint-plugin-node": "^11.1.0",
- "eslint-plugin-prettier": "^4.2.1",
- "eslint-plugin-promise": "^6.0.0",
- "ethers": "^5.6.9",
- "hardhat": "^2.12.2",
- "hardhat-contract-sizer": "^2.6.1",
- "hardhat-gas-reporter": "^1.0.8",
- "prettier": "2.7.1",
- "prettier-plugin-solidity": "^1.0.0-beta.20",
- "solc": "^0.8.9",
- "solhint": "^3.3.7",
- "solidity-coverage": "^0.8.2",
- "ts-node": "^10.8.2",
- "typechain": "^8.1.0",
- "typescript": "^4.7.4",
- "walk-sync": "^3.0.0"
- }
-}
diff --git a/assets/eip-5773/test/multiasset.ts b/assets/eip-5773/test/multiasset.ts
deleted file mode 100644
index e623e4e..0000000
--- a/assets/eip-5773/test/multiasset.ts
+++ /dev/null
@@ -1,761 +0,0 @@
-import { ethers } from "hardhat";
-import { expect } from "chai";
-import {
- ERC721ReceiverMock,
- MultiAssetReceiverMock,
- MultiAssetTokenMock,
- NonReceiverMock,
- MultiAssetRenderUtils,
-} from "../typechain-types";
-import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
-import { BigNumber } from "ethers";
-
-describe("MultiAsset", async () => {
- let token: MultiAssetTokenMock;
- let renderUtils: MultiAssetRenderUtils;
- let nonReceiver: NonReceiverMock;
- let receiver721: ERC721ReceiverMock;
-
- let owner: SignerWithAddress;
- let addrs: SignerWithAddress[];
-
- const name = "RmrkTest";
- const symbol = "RMRKTST";
-
- const metaURIDefault = "metaURI";
-
- beforeEach(async () => {
- const [signersOwner, ...signersAddr] = await ethers.getSigners();
- owner = signersOwner;
- addrs = signersAddr;
-
- const multiassetFactory = await ethers.getContractFactory(
- "MultiAssetTokenMock"
- );
- token = await multiassetFactory.deploy(name, symbol);
- await token.deployed();
-
- const renderFactory = await ethers.getContractFactory(
- "MultiAssetRenderUtils"
- );
- renderUtils = await renderFactory.deploy();
- await renderUtils.deployed();
- });
-
- describe("Init", async function () {
- it("Name", async function () {
- expect(await token.name()).to.equal(name);
- });
-
- it("Symbol", async function () {
- expect(await token.symbol()).to.equal(symbol);
- });
- });
-
- describe("ERC165 check", async function () {
- it("can support IERC165", async function () {
- expect(await token.supportsInterface("0x01ffc9a7")).to.equal(true);
- });
-
- it("can support IERC721", async function () {
- expect(await token.supportsInterface("0x80ac58cd")).to.equal(true);
- });
-
- it("can support IERC5773", async function () {
- expect(await token.supportsInterface("0x06b4329a")).to.equal(true);
- });
-
- it("cannot support other interfaceId", async function () {
- expect(await token.supportsInterface("0xffffffff")).to.equal(false);
- });
- });
-
- describe("Check OnReceived ERC721 and Multiasset", async function () {
- it("Revert on transfer to non onERC721/onMultiasset implementer", async function () {
- const tokenId = 1;
- await token.mint(owner.address, tokenId);
-
- const NonReceiver = await ethers.getContractFactory("NonReceiverMock");
- nonReceiver = await NonReceiver.deploy();
- await nonReceiver.deployed();
-
- await expect(
- token
- .connect(owner)
- ["safeTransferFrom(address,address,uint256)"](
- owner.address,
- nonReceiver.address,
- 1
- )
- ).to.be.revertedWith(
- "MultiAsset: transfer to non ERC721 Receiver implementer"
- );
- });
-
- it("onERC721Received callback on transfer", async function () {
- const tokenId = 1;
- await token.mint(owner.address, tokenId);
-
- const ERC721Receiver = await ethers.getContractFactory(
- "ERC721ReceiverMock"
- );
- receiver721 = await ERC721Receiver.deploy();
- await receiver721.deployed();
-
- await token
- .connect(owner)
- ["safeTransferFrom(address,address,uint256)"](
- owner.address,
- receiver721.address,
- 1
- );
- expect(await token.ownerOf(1)).to.equal(receiver721.address);
- });
- });
-
- describe("Asset storage", async function () {
- it("can add asset", async function () {
- const id = 10;
-
- await expect(token.addAssetEntry(id, metaURIDefault))
- .to.emit(token, "AssetSet")
- .withArgs(id);
- });
-
- it("cannot get non existing asset", async function () {
- const tokenId = 1;
- const resId = 10;
- await token.mint(owner.address, tokenId);
- await expect(token.getAssetMetadata(tokenId, resId)).to.be.revertedWith(
- "MultiAsset: Token does not have asset"
- );
- });
-
- it("cannot add asset entry if not issuer", async function () {
- const id = 10;
- await expect(
- token.connect(addrs[1]).addAssetEntry(id, metaURIDefault)
- ).to.be.revertedWith("RMRK: Only issuer");
- });
-
- it("can set and get issuer", async function () {
- const newIssuerAddr = addrs[1].address;
- expect(await token.getIssuer()).to.equal(owner.address);
-
- await token.setIssuer(newIssuerAddr);
- expect(await token.getIssuer()).to.equal(newIssuerAddr);
- });
-
- it("cannot set issuer if not issuer", async function () {
- const newIssuer = addrs[1];
- await expect(
- token.connect(newIssuer).setIssuer(newIssuer.address)
- ).to.be.revertedWith("RMRK: Only issuer");
- });
-
- it("cannot overwrite asset", async function () {
- const id = 10;
-
- await token.addAssetEntry(id, metaURIDefault);
- await expect(token.addAssetEntry(id, metaURIDefault)).to.be.revertedWith(
- "RMRK: asset already exists"
- );
- });
-
- it("cannot add asset with id 0", async function () {
- const id = ethers.utils.hexZeroPad("0x0", 8);
-
- await expect(token.addAssetEntry(id, metaURIDefault)).to.be.revertedWith(
- "RMRK: Write to zero"
- );
- });
-
- it("cannot add same asset twice", async function () {
- const id = 10;
-
- await expect(token.addAssetEntry(id, metaURIDefault))
- .to.emit(token, "AssetSet")
- .withArgs(id);
-
- await expect(token.addAssetEntry(id, metaURIDefault)).to.be.revertedWith(
- "RMRK: asset already exists"
- );
- });
- });
-
- describe("Adding assets", async function () {
- it("can add asset to token", async function () {
- const resId = 1;
- const resId2 = 2;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await expect(token.addAssetToToken(tokenId, resId, 0)).to.emit(
- token,
- "AssetAddedToTokens"
- );
- await expect(token.addAssetToToken(tokenId, resId2, 0)).to.emit(
- token,
- "AssetAddedToTokens"
- );
-
- const pendingIds = await token.getPendingAssets(tokenId);
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, pendingIds)
- ).to.be.eql([metaURIDefault, metaURIDefault]);
- });
-
- it("cannot add non existing asset to token", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await expect(token.addAssetToToken(tokenId, resId, 0)).to.be.revertedWith(
- "MultiAsset: Asset not found in storage"
- );
- });
-
- it("can add asset to non existing token and it is pending when minted", async function () {
- const resId = 1;
- const tokenId = 1;
- await addAssets([resId]);
-
- await token.addAssetToToken(tokenId, resId, 0);
- await token.mint(owner.address, tokenId);
- expect(await token.getPendingAssets(tokenId)).to.eql([
- ethers.BigNumber.from(resId),
- ]);
- });
-
- it("cannot add asset twice to the same token", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
- await expect(
- token.addAssetToToken(tokenId, ethers.BigNumber.from(resId), 0)
- ).to.be.revertedWith("MultiAsset: Asset already exists on token");
- });
-
- it("cannot add too many assets to the same token", async function () {
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- for (let i = 1; i <= 128; i++) {
- await addAssets([i]);
- await token.addAssetToToken(tokenId, i, 0);
- }
-
- // Now it's full, next should fail
- const resId = 129;
- await addAssets([resId]);
- await expect(token.addAssetToToken(tokenId, resId, 0)).to.be.revertedWith(
- "MultiAsset: Max pending assets reached"
- );
- });
-
- it("can add same asset to 2 different tokens", async function () {
- const resId = 1;
- const tokenId1 = 1;
- const tokenId2 = 2;
-
- await token.mint(owner.address, tokenId1);
- await token.mint(owner.address, tokenId2);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId1, resId, 0);
- await token.addAssetToToken(tokenId2, resId, 0);
- });
- });
-
- describe("Accepting assets", async function () {
- it("can accept asset if owner", async function () {
- const { tokenOwner, tokenId } = await mintSampleToken();
- const approved = tokenOwner;
-
- await checkAcceptFromAddress(approved, tokenId);
- });
-
- it("can accept asset if approved for assets", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[1];
-
- await token.approveForAssets(approved.address, tokenId);
- await checkAcceptFromAddress(approved, tokenId);
- });
-
- it("can accept asset if approved for assets for all", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[2];
-
- await token.setApprovalForAllForAssets(approved.address, true);
- await checkAcceptFromAddress(approved, tokenId);
- });
-
- it("can accept multiple assets", async function () {
- const resId = 1;
- const resId2 = 2;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.addAssetToToken(tokenId, resId2, 0);
- await expect(token.acceptAsset(tokenId, 1, resId2))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId2, 0);
- await expect(token.acceptAsset(tokenId, 0, resId))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId, 0);
-
- expect(await token.getPendingAssets(tokenId)).to.be.eql([]);
-
- const activeIds = await token.getActiveAssets(tokenId);
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, activeIds)
- ).to.eql([metaURIDefault, metaURIDefault]);
- });
-
- it("cannot accept asset twice", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.acceptAsset(tokenId, 0, resId);
- });
-
- it("cannot accept asset if not owner", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
- await expect(
- token.connect(addrs[1]).acceptAsset(tokenId, 0, resId)
- ).to.be.revertedWith("MultiAsset: not owner or approved");
- });
-
- it("cannot accept non existing asset", async function () {
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await expect(token.acceptAsset(tokenId, 0, 1)).to.be.revertedWith(
- "MultiAsset: index out of bounds"
- );
- });
- });
-
- describe("Overwriting assets", async function () {
- it("can add asset to token overwritting an existing one", async function () {
- const resId = 1;
- const resId2 = 2;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.acceptAsset(tokenId, 0, resId);
-
- // Add new asset to overwrite the first, and accept
- const activeAssets = await token.getActiveAssets(tokenId);
- await expect(token.addAssetToToken(tokenId, resId2, activeAssets[0]))
- .to.emit(token, "AssetAddedToTokens")
- .withArgs([tokenId], resId2, resId);
- const pendingAssets = await token.getPendingAssets(tokenId);
-
- expect(
- await token.getAssetReplacements(tokenId, pendingAssets[0])
- ).to.eql(activeAssets[0]);
- await expect(token.acceptAsset(tokenId, 0, resId2))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId2, resId);
-
- const activeIds = await token.getActiveAssets(tokenId);
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, activeIds)
- ).to.eql([metaURIDefault]);
- // Overwrite should be gone
- expect(
- await token.getAssetReplacements(tokenId, pendingAssets[0])
- ).to.eql(ethers.BigNumber.from(0));
- });
-
- it("can overwrite non existing asset to token, it could have been deleted", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(
- tokenId,
- resId,
- ethers.utils.hexZeroPad("0x1", 8)
- );
- await token.acceptAsset(tokenId, 0, resId);
-
- const activeIds = await token.getActiveAssets(tokenId);
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, activeIds)
- ).to.eql([metaURIDefault]);
- });
-
- it("can overwrite an existing asset after 3 have been added and 1 accepted", async function () {
- const resId = 1;
- const resId2 = 2;
- const resId3 = 3;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2, resId3]);
- await expect(token.addAssetToToken(tokenId, resId, 0)).to.emit(
- token,
- "AssetAddedToTokens"
- );
- await expect(token.addAssetToToken(tokenId, resId2, 0)).to.emit(
- token,
- "AssetAddedToTokens"
- );
- await expect(token.addAssetToToken(tokenId, resId3, resId2))
- .to.emit(token, "AssetAddedToTokens")
- .withArgs([tokenId], resId3, resId2);
-
- const pendingIds = await token.getPendingAssets(tokenId);
-
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, pendingIds)
- ).to.be.eql([metaURIDefault, metaURIDefault, metaURIDefault]);
-
- await expect(token.acceptAsset(tokenId, 1, resId2))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId2, 0);
-
- await expect(token.acceptAsset(tokenId, 1, resId3))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId3, 2);
- });
- });
-
- describe("Rejecting assets", async function () {
- it("can reject asset if owner", async function () {
- const { tokenOwner, tokenId } = await mintSampleToken();
- const approved = tokenOwner;
-
- await checkRejectFromAddress(approved, tokenId);
- });
-
- it("can reject asset if approved for assets", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[1];
-
- await token.approveForAssets(approved.address, tokenId);
- await checkRejectFromAddress(approved, tokenId);
- });
-
- it("can reject asset if approved for assets for all", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[2];
-
- await token.setApprovalForAllForAssets(approved.address, true);
- await checkRejectFromAddress(approved, tokenId);
- });
-
- it("can reject all assets if owner", async function () {
- const { tokenOwner, tokenId } = await mintSampleToken();
- const approved = tokenOwner;
-
- await checkRejectAllFromAddress(approved, tokenId);
- });
-
- it("can reject all assets if approved for assets", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[1];
-
- await token.approveForAssets(approved.address, tokenId);
- await checkRejectAllFromAddress(approved, tokenId);
- });
-
- it("can reject all assets if approved for assets for all", async function () {
- const { tokenId } = await mintSampleToken();
- const approved = addrs[2];
-
- await token.setApprovalForAllForAssets(approved.address, true);
- await checkRejectAllFromAddress(approved, tokenId);
- });
-
- it("can reject asset and overwrites are cleared", async function () {
- const resId = 1;
- const resId2 = 2;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.acceptAsset(tokenId, 0, resId);
-
- // Will try to overwrite but we reject it
- await token.addAssetToToken(tokenId, resId2, resId);
- await token.rejectAsset(tokenId, 0, resId2);
-
- expect(await token.getAssetReplacements(tokenId, resId2)).to.eql(
- ethers.BigNumber.from(0)
- );
- });
-
- it("can reject all assets and overwrites are cleared", async function () {
- const resId = 1;
- const resId2 = 2;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.acceptAsset(tokenId, 0, resId);
-
- // Will try to overwrite but we reject all
- await token.addAssetToToken(tokenId, resId2, resId);
- await token.rejectAllAssets(tokenId, 1);
-
- expect(await token.getAssetReplacements(tokenId, resId2)).to.eql(
- ethers.BigNumber.from(0)
- );
- });
-
- it("can reject all pending assets at max capacity", async function () {
- const tokenId = 1;
- const resArr = [];
-
- for (let i = 1; i < 128; i++) {
- resArr.push(i);
- }
-
- await token.mint(owner.address, tokenId);
- await addAssets(resArr);
-
- for (let i = 1; i < 128; i++) {
- await token.addAssetToToken(tokenId, i, 1);
- }
- await token.rejectAllAssets(tokenId, 128);
-
- expect(await token.getAssetReplacements(1, 2)).to.eql(
- ethers.BigNumber.from(0)
- );
- });
-
- it("cannot reject asset twice", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.rejectAsset(tokenId, 0, resId);
- });
-
- it("cannot reject asset nor reject all if not owner", async function () {
- const resId = 1;
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
-
- await expect(
- token.connect(addrs[1]).rejectAsset(tokenId, 0, resId)
- ).to.be.revertedWith("MultiAsset: not owner or approved");
- await expect(
- token.connect(addrs[1]).rejectAllAssets(tokenId, 1)
- ).to.be.revertedWith("MultiAsset: not owner or approved");
- });
-
- it("cannot reject non existing asset", async function () {
- const tokenId = 1;
-
- await token.mint(owner.address, tokenId);
- await expect(token.rejectAsset(tokenId, 0, 1)).to.be.revertedWith(
- "MultiAsset: index out of bounds"
- );
- });
- });
-
- describe("Priorities", async function () {
- it("can set and get priorities", async function () {
- const tokenId = 1;
- await addAssetsToToken(tokenId);
-
- expect(await token.getActiveAssetPriorities(tokenId)).to.be.eql([BigNumber.from(0), BigNumber.from(1)]);
- await expect(token.setPriority(tokenId, [2, 1]))
- .to.emit(token, "AssetPrioritySet")
- .withArgs(tokenId);
- expect(await token.getActiveAssetPriorities(tokenId)).to.be.eql([BigNumber.from(2), BigNumber.from(1)]);
- });
-
- it("cannot set priorities for non owned token", async function () {
- const tokenId = 1;
- await addAssetsToToken(tokenId);
- await expect(
- token.connect(addrs[1]).setPriority(tokenId, [2, 1])
- ).to.be.revertedWith("MultiAsset: not owner or approved");
- });
-
- it("cannot set different number of priorities", async function () {
- const tokenId = 1;
- await addAssetsToToken(tokenId);
- await expect(
- token.connect(addrs[1]).setPriority(tokenId, [1])
- ).to.be.revertedWith("MultiAsset: Bad priority list length");
- await expect(
- token.connect(addrs[1]).setPriority(tokenId, [2, 1, 3])
- ).to.be.revertedWith("MultiAsset: Bad priority list length");
- });
-
- it("cannot set priorities for non existing token", async function () {
- const tokenId = 1;
- await expect(
- token.connect(addrs[1]).setPriority(tokenId, [])
- ).to.be.revertedWith("MultiAsset: approved query for nonexistent token");
- });
- });
-
- describe("Approval Cleaning", async function () {
- it("cleans token and assets approvals on transfer", async function () {
- const tokenId = 1;
- const tokenOwner = addrs[1];
- const newOwner = addrs[2];
- const approved = addrs[3];
- await token.mint(tokenOwner.address, tokenId);
- await token.connect(tokenOwner).approve(approved.address, tokenId);
- await token
- .connect(tokenOwner)
- .approveForAssets(approved.address, tokenId);
-
- expect(await token.getApproved(tokenId)).to.eql(approved.address);
- expect(await token.getApprovedForAssets(tokenId)).to.eql(
- approved.address
- );
-
- await token.connect(tokenOwner).transfer(newOwner.address, tokenId);
-
- expect(await token.getApproved(tokenId)).to.eql(
- ethers.constants.AddressZero
- );
- expect(await token.getApprovedForAssets(tokenId)).to.eql(
- ethers.constants.AddressZero
- );
- });
-
- it("cleans token and assets approvals on burn", async function () {
- const tokenId = 1;
- const tokenOwner = addrs[1];
- const approved = addrs[3];
- await token.mint(tokenOwner.address, tokenId);
- await token.connect(tokenOwner).approve(approved.address, tokenId);
- await token
- .connect(tokenOwner)
- .approveForAssets(approved.address, tokenId);
-
- expect(await token.getApproved(tokenId)).to.eql(approved.address);
- expect(await token.getApprovedForAssets(tokenId)).to.eql(
- approved.address
- );
-
- await token.connect(tokenOwner).burn(tokenId);
-
- await expect(token.getApproved(tokenId)).to.be.revertedWith(
- "MultiAsset: approved query for nonexistent token"
- );
- await expect(token.getApprovedForAssets(tokenId)).to.be.revertedWith(
- "MultiAsset: approved query for nonexistent token"
- );
- });
- });
-
- async function mintSampleToken(): Promise<{
- tokenOwner: SignerWithAddress;
- tokenId: number;
- }> {
- const tokenOwner = owner;
- const tokenId = 1;
- await token.mint(tokenOwner.address, tokenId);
-
- return { tokenOwner, tokenId };
- }
-
- async function addAssets(ids: number[]): Promise {
- ids.forEach(async (resId) => {
- await token.addAssetEntry(resId, metaURIDefault);
- });
- }
-
- async function addAssetsToToken(tokenId: number): Promise {
- const resId = 1;
- const resId2 = 2;
- await token.mint(owner.address, tokenId);
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.addAssetToToken(tokenId, resId2, 0);
- await token.acceptAsset(tokenId, 0, resId);
- await token.acceptAsset(tokenId, 0, resId2);
- }
-
- async function checkAcceptFromAddress(
- accepter: SignerWithAddress,
- tokenId: number
- ): Promise {
- const resId = 1;
-
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
- await expect(token.connect(accepter).acceptAsset(tokenId, 0, resId))
- .to.emit(token, "AssetAccepted")
- .withArgs(tokenId, resId, 0);
-
- expect(await token.getPendingAssets(tokenId)).to.be.eql([]);
-
- const activeIds = await token.getActiveAssets(tokenId);
- expect(
- await renderUtils.getAssetsById(token.address, tokenId, activeIds)
- ).to.eql([metaURIDefault]);
- }
-
- async function checkRejectFromAddress(
- rejecter: SignerWithAddress,
- tokenId: number
- ): Promise {
- const resId = 1;
-
- await addAssets([resId]);
- await token.addAssetToToken(tokenId, resId, 0);
-
- await expect(
- token.connect(rejecter).rejectAsset(tokenId, 0, resId)
- ).to.emit(token, "AssetRejected");
-
- expect(await token.getPendingAssets(tokenId)).to.be.eql([]);
- expect(await token.getActiveAssets(tokenId)).to.be.eql([]);
- }
-
- async function checkRejectAllFromAddress(
- rejecter: SignerWithAddress,
- tokenId: number
- ): Promise {
- const resId = 1;
- const resId2 = 2;
-
- await addAssets([resId, resId2]);
- await token.addAssetToToken(tokenId, resId, 0);
- await token.addAssetToToken(tokenId, resId2, 0);
-
- await expect(token.connect(rejecter).rejectAllAssets(tokenId, 2)).to.emit(
- token,
- "AssetRejected"
- );
-
- expect(await token.getPendingAssets(tokenId)).to.be.eql([]);
- expect(await token.getActiveAssets(tokenId)).to.be.eql([]);
- }
-});
diff --git a/assets/eip-5773/test/renderUtils.ts b/assets/eip-5773/test/renderUtils.ts
deleted file mode 100644
index 78bc785..0000000
--- a/assets/eip-5773/test/renderUtils.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { BigNumber } from "ethers";
-import { ethers } from "hardhat";
-import { expect } from "chai";
-import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
-import { MultiAssetTokenMock, MultiAssetRenderUtils } from "../typechain-types";
-import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
-
-function bn(x: number): BigNumber {
- return BigNumber.from(x);
-}
-
-async function assetsFixture() {
- const multiassetFactory = await ethers.getContractFactory(
- "MultiAssetTokenMock"
- );
- const renderUtilsFactory = await ethers.getContractFactory(
- "MultiAssetRenderUtils"
- );
-
- const multiasset = await multiassetFactory.deploy("Chunky", "CHNK");
- await multiasset.deployed();
-
- const renderUtils = await renderUtilsFactory.deploy();
- await renderUtils.deployed();
-
- return { multiasset, renderUtils };
-}
-
-describe("Render Utils", async function () {
- let owner: SignerWithAddress;
- let multiasset: MultiAssetTokenMock;
- let renderUtils: MultiAssetRenderUtils;
- let tokenId: number;
-
- const resId = bn(1);
- const resId2 = bn(2);
- const resId3 = bn(3);
- const resId4 = bn(4);
-
- before(async function () {
- ({ multiasset, renderUtils } = await loadFixture(assetsFixture));
-
- const signers = await ethers.getSigners();
- owner = signers[0];
-
- tokenId = 1;
- await multiasset.mint(owner.address, tokenId);
- await multiasset.addAssetEntry(resId, "ipfs://res1.jpg");
- await multiasset.addAssetEntry(resId2, "ipfs://res2.jpg");
- await multiasset.addAssetEntry(resId3, "ipfs://res3.jpg");
- await multiasset.addAssetEntry(resId4, "ipfs://res4.jpg");
- await multiasset.addAssetToToken(tokenId, resId, 0);
- await multiasset.addAssetToToken(tokenId, resId2, 0);
- await multiasset.addAssetToToken(tokenId, resId3, resId);
- await multiasset.addAssetToToken(tokenId, resId4, 0);
-
- await multiasset.acceptAsset(tokenId, 0, resId);
- await multiasset.acceptAsset(tokenId, 1, resId2);
- await multiasset.setPriority(tokenId, [10, 5]);
- });
-
- describe("Render Utils MultiAsset", async function () {
- it("can get active assets", async function () {
- expect(
- await renderUtils.getActiveAssets(multiasset.address, tokenId)
- ).to.eql([
- [resId, BigNumber.from(10), "ipfs://res1.jpg"],
- [resId2, BigNumber.from(5), "ipfs://res2.jpg"],
- ]);
- });
- it("can get pending assets", async function () {
- expect(
- await renderUtils.getPendingAssets(multiasset.address, tokenId)
- ).to.eql([
- [resId4, bn(0), bn(0), "ipfs://res4.jpg"],
- [resId3, bn(1), resId, "ipfs://res3.jpg"],
- ]);
- });
-
- it("can get top asset by priority", async function () {
- expect(
- await renderUtils.getTopAssetMetaForToken(multiasset.address, tokenId)
- ).to.eql("ipfs://res2.jpg");
- });
-
- it("cannot get top asset if token has no assets", async function () {
- const otherTokenId = 2;
- await multiasset.mint(owner.address, otherTokenId);
- await expect(
- renderUtils.getTopAssetMetaForToken(multiasset.address, otherTokenId)
- ).to.be.revertedWith("Token has no assets");
- });
- });
-});
diff --git a/assets/eip-5827/ERC5827.sol b/assets/eip-5827/ERC5827.sol
deleted file mode 100644
index 1d70d48..0000000
--- a/assets/eip-5827/ERC5827.sol
+++ /dev/null
@@ -1,149 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity 0.8.17;
-
-import "openzeppelin-contracts/token/ERC20/ERC20.sol";
-import "./IERC5827.sol";
-
-contract ERC5827 is ERC20, IERC5827 {
- struct RenewableAllowance {
- uint256 amount;
- uint192 recoveryRate;
- uint64 lastUpdated;
- }
-
- // owner => spender => renewableAllowance
- mapping(address => mapping(address => RenewableAllowance))
- private rAllowance;
-
- constructor(
- string memory name_,
- string memory symbol_
- ) ERC20(name_, symbol_) {}
-
- function approve(
- address _spender,
- uint256 _value
- ) public override(ERC20, IERC5827) returns (bool success) {
- address owner = _msgSender();
- _approve(owner, _spender, _value, 0);
- return true;
- }
-
- function approveRenewable(
- address _spender,
- uint256 _value,
- uint256 _recoveryRate
- ) public override returns (bool success) {
- address owner = _msgSender();
- _approve(owner, _spender, _value, _recoveryRate);
- return true;
- }
-
- function _approve(
- address _owner,
- address _spender,
- uint256 _value,
- uint256 _recoveryRate
- ) internal virtual {
- require(
- _recoveryRate <= _value,
- "recoveryRate must be less than or equal to value"
- );
-
- rAllowance[_owner][_spender] = RenewableAllowance({
- amount: _value,
- recoveryRate: uint192(_recoveryRate),
- lastUpdated: uint64(block.timestamp)
- });
-
- _approve(_owner, _spender, _value);
- emit RenewableApproval(_owner, _spender, _value, _recoveryRate);
- }
-
- /// @notice fetch amounts spendable by _spender
- /// @return remaining allowance at the current point in time
- function allowance(
- address _owner,
- address _spender
- ) public view override(ERC20, IERC5827) returns (uint256 remaining) {
- return _remainingAllowance(_owner, _spender);
- }
-
- /// @dev returns the sum of two uint256 values, saturating at 2**256 - 1
- function saturatingAdd(
- uint256 a,
- uint256 b
- ) internal pure returns (uint256) {
- unchecked {
- uint256 c = a + b;
- if (c < a) return type(uint256).max;
- return c;
- }
- }
-
- function _remainingAllowance(
- address _owner,
- address _spender
- ) private view returns (uint256) {
- RenewableAllowance memory a = rAllowance[_owner][_spender];
- uint256 remaining = super.allowance(_owner, _spender);
-
- uint256 recovered = uint256(a.recoveryRate) *
- uint64(block.timestamp - a.lastUpdated);
- uint256 remainingAllowance = saturatingAdd(remaining, recovered);
- return remainingAllowance > a.amount ? a.amount : remainingAllowance;
- }
-
- /// @notice fetch approved max amount and recovery rate
- /// @return amount initial and maximum allowance given to spender
- /// @return recoveryRate recovery amount per second
- function renewableAllowance(
- address _owner,
- address _spender
- ) public view returns (uint256 amount, uint256 recoveryRate) {
- RenewableAllowance memory a = rAllowance[_owner][_spender];
- return (a.amount, uint256(a.recoveryRate));
- }
-
- /// @notice transfers base token with renewable allowance logic applied
- /// @param from owner of base token
- /// @param to recipient of base token
- /// @param amount amount to transfer
- function transferFrom(
- address from,
- address to,
- uint256 amount
- ) public override(ERC20, IERC5827) returns (bool) {
- address spender = _msgSender();
- _spendAllowance(from, spender, amount);
- _transfer(from, to, amount);
- return true;
- }
-
- function _spendAllowance(
- address owner,
- address spender,
- uint256 amount
- ) internal virtual override {
- (uint256 maxAllowance, ) = renewableAllowance(owner, spender);
- if (maxAllowance != type(uint256).max) {
- uint256 currentAllowance = _remainingAllowance(owner, spender);
- if (currentAllowance < amount) {
- revert InsufficientRenewableAllowance({
- available: currentAllowance
- });
- }
-
- unchecked {
- _approve(owner, spender, currentAllowance - amount);
- }
- rAllowance[owner][spender].lastUpdated = uint64(block.timestamp);
- }
- }
-
- function supportsInterface(
- bytes4 interfaceId
- ) public view virtual returns (bool) {
- return interfaceId == type(IERC5827).interfaceId;
- }
-}
diff --git a/assets/eip-5827/IERC5827.sol b/assets/eip-5827/IERC5827.sol
deleted file mode 100644
index 2f45588..0000000
--- a/assets/eip-5827/IERC5827.sol
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import "openzeppelin-contracts/interfaces/IERC20.sol";
-import "openzeppelin-contracts/interfaces/IERC165.sol";
-
-/// @title Interface for IERC5827 contracts
-/// @notice Please see https://eips.ethereum.org/EIPS/eip-5827 for more details on the goals of this interface
-/// @author Zac (zlace0x), zhongfu (zhongfu), Edison (edison0xyz)
-interface IERC5827 is IERC20, IERC165 {
- /// Note: the ERC-165 identifier for this interface is 0x93cd7af6.
- /// 0x93cd7af6 ===
- /// bytes4(keccak256('approveRenewable(address,uint256,uint256)')) ^
- /// bytes4(keccak256('renewableAllowance(address,address)')) ^
- /// bytes4(keccak256('approve(address,uint256)') ^
- /// bytes4(keccak256('transferFrom(address,address,uint256)') ^
- /// bytes4(keccak256('allowance(address,address)') ^
-
- /// @dev Thrown when there available allowance is lesser than transfer amount
- /// @param available Allowance available, 0 if unset
- error InsufficientRenewableAllowance(uint256 available);
-
- /// @notice Emitted when a new renewable allowance is set.
- /// @param _owner owner of token
- /// @param _spender allowed spender of token
- /// @param _value initial and maximum allowance given to spender
- /// @param _recoveryRate recovery amount per second
- event RenewableApproval(
- address indexed _owner,
- address indexed _spender,
- uint256 _value,
- uint256 _recoveryRate
- );
-
- /// @notice Grants an allowance of `_value` to `_spender` initially, which recovers over time based on `_recoveryRate` up to a limit of `_value`.
- /// SHOULD throw when `_recoveryRate` is larger than `_value`.
- /// MUST emit `RenewableApproval` event.
- /// @param _spender allowed spender of token
- /// @param _value initial and maximum allowance given to spender
- /// @param _recoveryRate recovery amount per second
- function approveRenewable(
- address _spender,
- uint256 _value,
- uint256 _recoveryRate
- ) external returns (bool success);
-
- /// @notice Returns approved max amount and recovery rate.
- /// @return amount initial and maximum allowance given to spender
- /// @return recoveryRate recovery amount per second
- function renewableAllowance(
- address _owner,
- address _spender
- ) external view returns (uint256 amount, uint256 recoveryRate);
-
- /// Overridden EIP-20 functions
-
- /// @notice Grants a (non-increasing) allowance of _value to _spender.
- /// MUST clear set _recoveryRate to 0 on the corresponding renewable allowance, if any.
- /// @param _spender allowed spender of token
- /// @param _value allowance given to spender
- function approve(
- address _spender,
- uint256 _value
- ) external returns (bool success);
-
- /// @notice Moves `amount` tokens from `from` to `to` using the
- /// allowance mechanism. `amount` is then deducted from the caller's
- /// allowance factoring in recovery rate logic.
- /// SHOULD throw when there is insufficient allowance
- /// @param from token owner address
- /// @param to token recipient
- /// @param amount amount of token to transfer
- /// @return success True if the function is successful, false if otherwise
- function transferFrom(
- address from,
- address to,
- uint256 amount
- ) external returns (bool success);
-
- /// @notice Returns amounts spendable by `_spender`.
- /// @param _owner Address of the owner
- /// @param _spender spender of token
- /// @return remaining allowance at the current point in time
- function allowance(
- address _owner,
- address _spender
- ) external view returns (uint256 remaining);
-}
diff --git a/assets/eip-5851/contracts/ERC5851Issuer.sol b/assets/eip-5851/contracts/ERC5851Issuer.sol
deleted file mode 100644
index f6e91de..0000000
--- a/assets/eip-5851/contracts/ERC5851Issuer.sol
+++ /dev/null
@@ -1,46 +0,0 @@
-
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-import "./interfaces/IERC5851.sol";
-
-
-abstract contract ERC5851Issuer is IERC5851{
- mapping(uint256 => IERC5851.Claim[]) private _claimMetadata;
- mapping(address => mapping(uint256 => bool)) private _SBTVerified;
- address public admin;
-
- constructor() {
- admin = msg.sender;
-
- }
-
- function ifVerified(address claimmer, uint256 SBTID) public override view returns (bool){
- return(_SBTVerified[claimmer][SBTID]);
- }
-
- function standardClaim(uint256 SBTID) public override view returns (Claim[] memory){
- return(_claimMetadata[SBTID]);
- }
-
- function changeStandardClaim(uint256 SBTID, Claim[] memory _claims) public override returns (bool){
- require(msg.sender == admin);
- _claimMetadata[SBTID] = _claims;
- emit StandardChanged(SBTID, _claims);
- return(true);
- }
-
- function certify(address claimer, uint256 SBTID) public override returns (bool){
- require(msg.sender == admin);
- _SBTVerified[claimer][SBTID] = true;
- emit Certified(claimer, SBTID);
- return(true);
- }
-
- function revoke(address claimer, uint256 SBTID) external override returns (bool){
- require(msg.sender == admin);
- _SBTVerified[claimer][SBTID] = false;
- emit Revoked(claimer, SBTID);
- return(true);
- }
-
-}
diff --git a/assets/eip-5851/contracts/ERC5851Verifier.sol b/assets/eip-5851/contracts/ERC5851Verifier.sol
deleted file mode 100644
index 75c6633..0000000
--- a/assets/eip-5851/contracts/ERC5851Verifier.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-import "./interfaces/IERC5851.sol";
-
-abstract contract ERC5851Verifier is IERC5851 {
- address private _issuer;
-
- constructor(address issuer) {
- _issuer = issuer;
- }
-
- modifier KYCApproved(address claimer, uint256 SBTID) {
- IERC5851(_issuer).ifVerified(claimer, SBTID);
- _;
- }
-
-}
diff --git a/assets/eip-5851/contracts/interfaces/IERC5851.sol b/assets/eip-5851/contracts/interfaces/IERC5851.sol
deleted file mode 100644
index a045e9c..0000000
--- a/assets/eip-5851/contracts/interfaces/IERC5851.sol
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-
-pragma solidity ^0.8.0;
-
-interface IERC5851{
-
- /** Metadata
- *
- * @param title defines the name of the claim field
- * @param kind is the nature of the data (bool,string,address,bytes,..)
- * @param description additional information about claim details.
- */
- struct Metadata {
- string title;
- string kind;
- string description;
- }
-
- /** Values
- *
- * @dev Values here can be read and wrote by smartcontract and front-end, cited from [EIP-3475](./eip-3475.md)
- */
- struct Values {
- string stringValue;
- uint uintValue;
- address addressValue;
- bool boolValue;
- }
-
- /** Claim
- *
- * Claims structure consist of the conditions and value that holder claims to associate and verifier has to validate them.
- * @notice the below given parameters are for reference purposes only, developers can optimize the fields that are needed to be represented on-chain by using schemes like TLV, encoding into base64 etc.
- * @dev structure that DeFines the parameters for specific claims of the SBT certificate
- * @notice this structure is used for the verification process, it contains the metadata, logic and expectation
- * @logic given here MUST be one of ("⊄", "⊂", "<", "<=", "==", "!=", ">=",">")
- */
- struct Claim {
- Metadata metadata;
- string logic;
- Values expectation;
- }
-
- //Verifier
- /// @notice getter function to validate if the address `claimer` is the holder of the claim Defined by the tokenId `SBTID`
- /// @dev it MUST be Defining the logic to fetch the result of the ZK verification (either from).
- /// @dev logic given here MUST be one of ("⊄", "⊂", "<", "<=", "==", "!=", ">=", ">")
- /// @param claimer is the EOA address that wants to validate the SBT issued to it by the KYC.
- /// @param SBTID is the Id of the SBT that user is the claimer.
- /// @return true if the assertion is valid, else false
- /**
- example ifVerified(0xfoo, 1) => true will mean that 0xfoo is the holder of the SBT identity token DeFined by tokenId of the given collection.
- */
- function ifVerified(address claimer, uint256 SBTID) external view returns (bool);
-
- //Issuer
- /// @notice getter function to fetch the on-chain identification logic for the given identity holder.
- /// @dev it MUST not be defined for address(0).
- /// @param SBTID is the Id of the SBT that the user is the claimer.
- /// @return the struct array of all the descriptions of condition metadata that is defined by the administrator for the given KYC provider.
- /**
- ex: standardClaim(1) --> {
- { "title":"age",
- "kind": "uint",
- "description": "age of the person based on the birth date on the legal document",
- },
- "logic": ">=",
- "value":"18"
- }
- Defines the condition encoded for the identity index 1, DeFining the identity condition that holder must be equal or more than 18 years old.
- **/
- function standardClaim(uint256 SBTID) external view returns (Claim[] memory);
-
- /// @notice function for setting the claim requirement logic (defined by Claims metadata) details for the given identity token defined by SBTID.
- /// @dev it should only be called by the admin address.
- /// @param SBTID is the Id of the SBT-based identity certificate for which the admin wants to define the Claims.
- /// @param `claims` is the struct array of all the descriptions of condition metadata that is defined by the administrator. check metadata section for more information.
- /**
- example: changeStandardClaim(1, { "title":"age",
- "kind": "uint",
- "description": "age of the person based on the birth date on the legal document",
- },
- "logic": ">=",
- "value":"18"
- });
- will correspond to the functionality that admin needs to adjust the standard claim for the identification SBT with tokenId = 1, based on the conditions described in the Claims array struct details.
- **/
- function changeStandardClaim(uint256 SBTID, Claim[] memory _claims) external returns (bool);
-
- /// @notice function which uses the ZKProof protocol to validate the identity based on the given
- /// @dev it should only be called by the admin address.
- /// @param SBTID is the Id of the SBT-based identity certificate for which admin wants to define the Claims.
- /// @param claimer is the address that needs to be proven as the owner of the SBT defined by the tokenID.
- /**
- example: certify(0xA....., 10) means that admin assigns the DID badge with id 10 to the address defined by the `0xA....` wallet.
- */
- function certify(address claimer, uint256 SBTID) external returns (bool);
-
- /// @notice function which uses the ZKProof protocol to validate the identity based on the given
- /// @dev it should only be called by the admin address.
- /// @param SBTID is the Id of the SBT-based identity certificate for which the admin wants to define the Claims.
- /// @param certifying is the address that needs to be proven as the owner of the SBT defined by the tokenID.
- // eg: revoke(0xfoo,1): means that KYC admin revokes the SBT certificate number 1 for the address '0xfoo'.
- function revoke(address certifying, uint256 SBTID) external returns (bool);
-
-
-// Events
- /**
- * standardChanged
- * @notice standardChanged MUST be triggered when claims are changed by the admin.
- * @dev standardChanged MUST also be triggered for the creation of a new SBTID.
- e.g : emit StandardChanged(1, Claims(Metadata('age', 'uint', 'age of the person based on the birth date on the legal document'), ">=", "18");
- is emitted when the Claim condition is changed which allows the certificate holder to call the functions with the modifier, claims that the holder must be equal or more than 18 years old.
- */
- event StandardChanged(uint256 SBTID, Claim[] _claims);
-
- /**
- * certified
- * @notice certified MUST be triggered when the SBT certificate is given to the certifying address.
- * eg: Certified(0xfoo,2); means that wallet holder address 0xfoo is certified to hold a certificate issued with id 2, and thus can satisfy all the conditions defined by the required interface.
- */
- event Certified(address claimer, uint256 SBTID);
-
- /**
- * revoked
- * @notice revoked MUST be triggered when the SBT certificate is revoked.
- * eg: Revoked( 0xfoo,1); means that entity user 0xfoo has been revoked to all the function access defined by the SBT ID 1.
- */
- event Revoked(address claimer, uint256 SBTID);
-}
diff --git a/assets/eip-5851/contracts/test.sol b/assets/eip-5851/contracts/test.sol
deleted file mode 100644
index a299dbb..0000000
--- a/assets/eip-5851/contracts/test.sol
+++ /dev/null
@@ -1,17 +0,0 @@
-// SPDX-License-Identifier: CC0-1.0
-pragma solidity ^0.8.0;
-import "./ERC5851Verifier.sol";
-
-abstract contract Token is ERC5851Verifier {
- uint public test;
- uint public SBTID;
- function mint(address to, uint256 amount) public KYCApproved(to, SBTID){
- _mint(to, amount);
- }
-
- function _mint(address account, uint256 amount) internal {
- require(account != address(0), "ERC20: mint to the zero address");
- test = amount;
- }
-
-}
diff --git a/assets/eip-5851/script/offchainOperations.js b/assets/eip-5851/script/offchainOperations.js
deleted file mode 100644
index e2636d3..0000000
--- a/assets/eip-5851/script/offchainOperations.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// CC0 license.
-// taken from (credits): https://soliditydeveloper.com/merkle-tree
-const keccak256 = require("keccak256");
-const { MerkleTree } = require("merkletreejs");
-
-const Web3 = require("web3");
-
-const web3 = new Web3();
-
-
-/**
- * generates the proof offchain using the PII information of the user and associated it with the other parameter details.
- *
- */
-
-async function generateProof() {
-
-// consider the given information that is verified privately off-chain (storing with wallet, name, age, personal ID, jurisdiction)
-// they will be considered as leaves for the application.
-const personalIdentifiedInfo = ["0x00000a86986129038908a9808098-toto-18-99123456-France", "0x00000a86986129038908a9808098-john-20-1276546-England"].map(x => keccak256(x));
-const tree = new MerkleTree(leaves,keccak256);
-
-}
-
-
-/**
- * this checks the ownership of the information from requirement (stored onchain) and then verify whether the keccak256 representation is a member of the given proof.
- * we follow the checkProof
- */
-async function verifyRequirement(verifyingAddress,leafNodes) {
-const buf2hex = x => '0x'+x.toString('hex')
-const leaf = keccak256('0x00000a86986129038908a9808098-toto-18-99123456-France')
-
-const leafInfo = buf2hex(leaf);
-
-const hexproof = tree.getProof(leaf).map(x => buf2hex(x.data));
-
-const positions = tree.getProof(leaf).map(x => x.position === 'right' ? 1 : 0)
-
-
-
-//TODO: fetch the
-const SBTCertification = await web3.eth.Contract();
-
-const verifiedOnchain = await SBTCertification.ifVerified(verifyingAddress, leafNodes);
-
-assert.equal(MerkleTree.verify(proof,leaf,root), verifiedOnchain);
-
-}
-
-
-
-const root = tree.getRoot();
-
-
-// this is the root generated by claim verifier, by doing the operations offchain.
-const hexroot = buf2hex(root);
-
-const merkleTree = new MerkleTree(leafNodes, keccak256, { sortPairs: true });
-
-console.log("---------");
-console.log("Merke Tree");
-console.log("---------");
-console.log(merkleTree.toString());
-console.log("---------");
-console.log("Merkle Root: " + merkleTree.getHexRoot());
-
-console.log("Proof 1: " + merkleTree.getHexProof(leafNodes[0]));
-console.log("Proof 2: " + merkleTree.getHexProof(leafNodes[1]));
diff --git a/assets/eip-5988/benchmarks/.gitkeep b/assets/eip-5988/benchmarks/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/assets/eip-5988/papers/poseidon_paper.pdf b/assets/eip-5988/papers/poseidon_paper.pdf
deleted file mode 100644
index 6a48677..0000000
Binary files a/assets/eip-5988/papers/poseidon_paper.pdf and /dev/null differ
diff --git a/assets/eip-5988/papers/practical_algebraic_attacks.pdf b/assets/eip-5988/papers/practical_algebraic_attacks.pdf
deleted file mode 100644
index 286184a..0000000
--- a/assets/eip-5988/papers/practical_algebraic_attacks.pdf
+++ /dev/null
@@ -1,6748 +0,0 @@
-%PDF-1.4
-%
-1 0 obj
-<<
-/Type /Catalog
-/Version /1.5
-/Pages 2 0 R
-/OpenAction [3 0 R /Fit]
-/Names 4 0 R
-/Outlines 5 0 R
-/Metadata 6 0 R
->>
-endobj
-7 0 obj
-<<
-/Creator
-/Title
-/Subject
-/Author
-/Producer
-/Keywords
-/CreationDate (D:20221031055618-00'00')
-/ModDate (D:20211221220139+01'00')
-/Trapped /False
-/PTEX.Fullbanner (This is pdfTeX, Version 3.14159265-2.6-1.40.21 \(TeX Live 2020/Debian\) kpathsea version 6.3.2)
->>
-endobj
-2 0 obj
-<<
-/Type /Pages
-/Kids [3 0 R 8 0 R 9 0 R 10 0 R 11 0 R 12 0 R 13 0 R 14 0 R 15 0 R 16 0 R
-17 0 R 18 0 R]
-/Count 12
->>
-endobj
-3 0 obj
-<<
-/Resources 19 0 R
-/Type /Page
-/Parent 2 0 R
-/Contents [20 0 R]
-/Annots [21 0 R 22 0 R]
-/CropBox [0.0 0.0 595.28 841.89]
-/MediaBox [0.0 0.0 595.28 841.89]
-/Rotate 0
->>
-endobj
-4 0 obj
-<<
-/Dests 23 0 R
->>
-endobj
-5 0 obj
-<<
-/Type /Outlines
-/First 24 0 R
-/Last 25 0 R
-/Count 7
->>
-endobj
-6 0 obj
-<<
-/Length 15488
-/Type /Metadata
-/Subtype /XML
->>
-stream
-
-
-
-
-
-
-
- Adobe PDF Schema
- pdf
- http://ns.adobe.com/pdf/1.3/
-
-
-
- Trapped
- Text
- internal
- Indication if the document has been modified to include trapping information
-
-
-
-
-
- XMP Media Management Schema
- xmpMM
- http://ns.adobe.com/xap/1.0/mm/
-
-
-
- DocumentID
- URI
- internal
- UUID based identifier for all versions and renditions of a document
-
-
- InstanceID
- URI
- internal
- UUID based identifier for specific incarnation of a document
-
-
- VersionID
- Text
- internal
- Document version identifier
-
-
- RenditionClass
- RenditionClass
- internal
- The manner in which a document is rendered
-
-
-
-
-
- PRISM Basic Metadata
- prism
- http://prismstandard.org/namespaces/basic/3.0/
-
-
-
- complianceProfile
- Text
- internal
- PRISM specification compliance profile to which this document adheres
-
-
- publicationName
- Text
- external
- Publication name
-
-
- aggregationType
- Text
- external
- Publication type
-
-
- bookEdition
- Text
- external
- Edition of the book in which the document was published
-
-
- volume
- Text
- external
- Publication volume number
-
-
- number
- Text
- external
- Publication issue number within a volume
-
-
- pageRange
- Text
- external
- Page range for the document within the print version of its publication
-
-
- issn
- Text
- external
- ISSN for the printed publication in which the document was published
-
-
- eIssn
- Text
- external
- ISSN for the electronic publication in which the document was published
-
-
- isbn
- Text
- external
- ISBN for the publication in which the document was published
-
-
- doi
- Text
- external
- Digital Object Identifier for the document
-
-
- url
- URL
- external
- URL at which the document can be found
-
-
- byteCount
- Integer
- internal
- Approximate file size in octets
-
-
- pageCount
- Integer
- internal
- Number of pages in the print version of the document
-
-
- subtitle
- Text
- external
- Document's subtitle
-
-
-
-
-
-
- pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020/Debian) kpathsea version 6.3.2
- Arithmetization-oriented hash functions, Poseidon, Feistel-MiMC, Rescue Prime, algebraic cryptanalysis
- 1.5
- application/pdf
-
-
- Practical Algebraic Attacks against some Arithmetization-oriented Hash Functions
-
-
-
-
- 2021-12-21T22:01:39+01:00
-
-
-
-
- Text
-
-
-
-
- Augustin Bariant
- Clémence Bouvier
- Gaëtan Leurent
- Léo Perrin
-
-
-
-
- Arithmetization-oriented hash functions
- Poseidon
- Feistel-MiMC
- Rescue Prime
- algebraic cryptanalysis
-
-
- writeup.tex
-
-
- en
-
-
- 2021-12-21T22:01:39+01:00
- 2021-12-21T22:01:39+01:00
- 2021-12-21T22:01:39+01:00
- LaTeX with hyperref
- uuid:d7a3900a-3eae-4f2b-ac46-c905467ae462
- uuid:3e413900-0000-4a8d-ba82-b67590005fdc
- 1
- default
- three
- 11
- 11
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-endstream
-endobj
-8 0 obj
-<<
-/Type /Page
-/Contents 26 0 R
-/Resources 27 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Group 28 0 R
-/Annots [29 0 R 30 0 R 31 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-9 0 obj
-<<
-/Type /Page
-/Contents 32 0 R
-/Resources 33 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Group 28 0 R
-/Annots [34 0 R 35 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-10 0 obj
-<<
-/Type /Page
-/Contents 36 0 R
-/Resources 37 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [38 0 R 39 0 R 40 0 R 41 0 R 42 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-11 0 obj
-<<
-/Type /Page
-/Contents 43 0 R
-/Resources 44 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [45 0 R 46 0 R 47 0 R 48 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-12 0 obj
-<<
-/Type /Page
-/Contents 49 0 R
-/Resources 50 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [51 0 R 52 0 R 53 0 R 54 0 R 55 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-13 0 obj
-<<
-/Type /Page
-/Contents 56 0 R
-/Resources 57 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [58 0 R 59 0 R 60 0 R 61 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-14 0 obj
-<<
-/Type /Page
-/Contents 62 0 R
-/Resources 63 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [64 0 R 65 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-15 0 obj
-<<
-/Type /Page
-/Contents 66 0 R
-/Resources 67 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [68 0 R 69 0 R 70 0 R 71 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-16 0 obj
-<<
-/Type /Page
-/Contents 72 0 R
-/Resources 73 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [74 0 R 75 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-17 0 obj
-<<
-/Type /Page
-/Contents 76 0 R
-/Resources 77 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/Annots [78 0 R 79 0 R]
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-18 0 obj
-<<
-/Type /Page
-/Contents 80 0 R
-/Resources 81 0 R
-/MediaBox [0.0 0.0 595.276 841.89]
-/Parent 2 0 R
-/CropBox [0.0 0.0 595.276 841.89]
-/Rotate 0
->>
-endobj
-19 0 obj
-<<
-/Font 82 0 R
-/XObject <<
-/Im0 83 0 R
-/Im1 84 0 R
->>
-/ProcSet [/PDF /Text /ImageC /ImageB /ImageI]
->>
-endobj
-20 0 obj
-<<
-/Length 1514
-/Filter /FlateDecode
->>
-stream
-xڵXɎ6+t
ҷ =%O")[H7"YUN`J̹L7|3~l߿L~+se:琧11v3ƧR'WW\jh
g2~1_9ñq/N?|Is<T<%t(Q7>6ɜ d7hG
a!T[sQy?5s1Ų#B5:V MP'~pT+FnRёwU6FCܨ̱`Du{
pc/bS*t=/