From bb2598ffdaa53743912b3a7a963e2ee5cc881970 Mon Sep 17 00:00:00 2001 From: Matt Rice Date: Mon, 23 Dec 2024 18:02:41 -0500 Subject: [PATCH 01/17] Update ERC-7683: fix incorrect type and comment Merged by EIP-Bot. --- ERCS/erc-7683.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7683.md b/ERCS/erc-7683.md index 83bb4778d2..44487cf25f 100644 --- a/ERCS/erc-7683.md +++ b/ERCS/erc-7683.md @@ -133,9 +133,9 @@ struct Output { /// @notice Instructions to parameterize each leg of the fill /// @dev Provides all the origin-generated information required to produce a valid fill leg struct FillInstruction { - /// @dev The contract address that the order is meant to be settled by - uint64 destinationChainId; - /// @dev The contract address that the order is meant to be filled on + /// @dev The chain that this instruction is intended to be filled on + uint256 destinationChainId; + /// @dev The contract address that the instruction is intended to be filled on bytes32 destinationSettler; /// @dev The data generated on the origin chain needed by the destinationSettler to process the fill bytes originData; From 3d78566b148b16a58a12c011edecb07fc99c2f85 Mon Sep 17 00:00:00 2001 From: oliveredget <188809800+oliveredget@users.noreply.github.com> Date: Tue, 24 Dec 2024 23:31:23 +0800 Subject: [PATCH 02/17] Update ERC-7555: fix typo Merged by EIP-Bot. --- ERCS/erc-7555.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7555.md b/ERCS/erc-7555.md index 88d666f1fa..d8e25bf210 100644 --- a/ERCS/erc-7555.md +++ b/ERCS/erc-7555.md @@ -41,7 +41,7 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S ### Definitions - **Smart account** - An ERC-4337 compliant smart contract account that has a modular architecture. -- **Domain** - A string of text acting as an identification to a server or wesbite (eg: `ethereum.org` or `ABCDE12345.com.example.app`). +- **Domain** - A string of text acting as an identification to a server or website (eg: `ethereum.org` or `ABCDE12345.com.example.app`). - **EOA** - Accounts that are controlled by a single private key. - **Provider** - A third party service provider that is able to authenticate a user and produce a keypair for the user. From 8658d1d2ee56758727d4785c01d9c1365bfe5a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernesto=20Garc=C3=ADa?= Date: Sun, 29 Dec 2024 03:21:40 -0600 Subject: [PATCH 03/17] Update ERC-7579: Make ERC165 optional and clarify payable execution Merged by EIP-Bot. --- ERCS/erc-7579.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 6b05388a79..5ca7d23e52 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -53,7 +53,7 @@ To comply with this standard, smart accounts MUST implement the execution interf ```solidity interface IExecution { /** - * @dev Executes a transaction on behalf of the account. + * @dev Executes a transaction on behalf of the account. MAY be payable. * @param mode The encoded execution mode of the transaction. * @param executionCalldata The encoded execution call data. * @@ -63,7 +63,7 @@ interface IExecution { function execute(bytes32 mode, bytes calldata executionCalldata) external; /** - * @dev Executes a transaction on behalf of the account. + * @dev Executes a transaction on behalf of the account. MAY be payable. * This function is intended to be called by Executor Modules * @param mode The encoded execution mode of the transaction. * @param executionCalldata The encoded execution call data. @@ -238,7 +238,7 @@ ERC-165 support (see below) is one example of such an approach. Note, that it is #### ERC-165 -Smart accounts MUST implement ERC-165. However, for every interface function that reverts instead of implementing the functionality, the smart account MUST return `false` for the corresponding interface id. +Smart accounts MAY implement ERC-165. However, for every interface function that reverts instead of implementing the functionality, the smart account MUST return `false` for the corresponding interface id. ### Modules From 83f8acb9198803f0e9a6eb604ec4afd7086bf0be Mon Sep 17 00:00:00 2001 From: Konrad Date: Mon, 30 Dec 2024 20:02:05 +0100 Subject: [PATCH 04/17] Update ERC-7579: hook clarifications Merged by EIP-Bot. --- ERCS/erc-7579.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ERCS/erc-7579.md b/ERCS/erc-7579.md index 5ca7d23e52..47d08312c6 100644 --- a/ERCS/erc-7579.md +++ b/ERCS/erc-7579.md @@ -36,7 +36,9 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S - Validator: A module used during the validation phase to determine if a transaction is valid and should be executed on the account. - Executor: A module that can execute transactions on behalf of the smart account via a callback. - Fallback Handler: A module that can extend the fallback functionality of a smart account. -- **Entrypoint** - A trusted singleton contract according to [ERC-4337](./eip-4337.md) specifications. +- **EntryPoint** - A trusted singleton contract according to [ERC-4337](./eip-4337.md) specifications. +- **Validation** - Any functionality used to determine if an execution should be made on the account. When using ERC-4337, this function will be `validateUserOp`. +- **Execution** - Any functionality used to execute an operation from or on the users account. When using ERC-4337, this will be called by the EntryPoint using `userOp.callData`. ### Account @@ -213,8 +215,10 @@ interface IModuleConfig { Hooks are an OPTIONAL extension of this standard. Smart accounts MAY use hooks to execute custom logic and checks before and/or after the smart accounts performs a single or batched execution. To comply with this OPTIONAL extension, a smart account: -- MUST call the `preCheck` function of one or multiple hooks during an execution on the account -- MUST call the `postCheck` function of one or multiple hooks during an execution on the account +- MUST call the `preCheck` function of one or multiple hooks before any call or batch of calls going through execute or executeFromExecutor +- MUST call the `postCheck` function of one or multiple hooks after any call or batch of calls through execute or executeFromExecutor +- Is RECOMMENDED to call `preCheck` and `postCheck` before and after executing calls to `installModule` or `uninstallModule` +- Is RECOMMENDED to call `preCheck` and `postCheck` before and after executing calls through other (custom) functions called execution #### ERC-1271 Forwarding From 80b7bda0b0ac213abffb40de866a0e3439909885 Mon Sep 17 00:00:00 2001 From: James Save Chives Date: Wed, 1 Jan 2025 02:28:43 +0800 Subject: [PATCH 05/17] Add ERC: Decentralized Employment System Merged by EIP-Bot. --- ERCS/erc-7750.md | 342 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 ERCS/erc-7750.md diff --git a/ERCS/erc-7750.md b/ERCS/erc-7750.md new file mode 100644 index 0000000000..670ce525d1 --- /dev/null +++ b/ERCS/erc-7750.md @@ -0,0 +1,342 @@ +--- +eip: 7750 +title: Decentralized Employment System +description: An employment system that records employment history. +author: James Savechives (@jamesavechives) +discussions-to: https://ethereum-magicians.org/t/erc-7750-decentralized-employment-system-des/20724 +status: Draft +type: Standards Track +category: ERC +created: 2024-08-04 +--- + +## Abstract + +This ERC proposes a Decentralized Employment System (DES) built on the Ethereum blockchain. The DES facilitates the creation and management of companies, records comprehensive employment histories through unique employee tokens, enables the formation and execution of labor contracts, automates salary payments via an escrow mechanism, incorporates a robust moderation system for dispute resolution, and implements a reputation-based review system for both employers and employees. By leveraging blockchain's transparency and immutability, the DES ensures accountability and trust throughout the employment lifecycle, from company creation and hiring to contract fulfillment and termination. + +The system operates post employee testing and prior to the final hiring and contract signing. Employees possess a **Soulbound Token (SBT)** representing their employment history, which companies review before finalizing labor contracts. This token-based approach ensures a secure and verifiable employment record that enhances the hiring process's integrity. + +## Motivation + +Traditional employment systems are centralized, opaque, and often lack trust. The DES aims to introduce transparency, immutability, and trust into the employment process by leveraging blockchain technology. By recording employment history on-chain, enabling decentralized company creation, automating contract enforcement, and providing mechanisms for dispute resolution, the DES promotes a fairer and more transparent employment ecosystem. Additionally, the system streamlines the hiring process by securely managing employment records and automating contractual obligations. + +## Specification + +### Solidity Interface + +To provide a clear and standardized way for developers to interact with the DES, the following Solidity interface outlines the primary functions and events of the system: + +```solidity +pragma solidity ^0.8.0; + +/// @title Decentralized Employment System Interface +interface IDecentralizedEmploymentSystem { + + // Events + event CompanyRegistered(uint companyId, address owner, string name, string industry); + event EmployeeTokenMinted(uint tokenId, address employee); + event ContractCreated(uint contractId, uint companyId, uint employeeTokenId, uint salary, uint duration); + event ContractExecuted(uint contractId); + event SalaryDeposited(uint contractId, uint amount); + event SalaryReleased(uint contractId, address employee); + event DisputeRaised(uint contractId, address raisedBy); + event DisputeResolved(uint contractId, bool decisionForEmployee); + event ContractTerminated(uint contractId, string reason); + event ReviewSubmitted(uint contractId, uint rating, string comments); + + // Company Management + function registerCompany(string calldata name, string calldata industry) external returns (uint companyId); + function getCompany(uint companyId) external view returns (string memory name, string memory industry, address owner, uint[] memory employeeIds); + + // Employee Management + function mintEmployeeToken(address employee, string calldata metadataURI) external returns (uint tokenId); + function getEmploymentHistory(uint employeeTokenId) external view returns (uint[] memory contractIds); + + // Labor Contracts + function createContract(uint companyId, uint employeeTokenId, uint salary, uint duration, string calldata responsibilities, string calldata terminationConditions) external returns (uint contractId); + function executeContract(uint contractId) external; + + // Payment System + function depositSalary(uint contractId) external payable; + function releaseSalary(uint contractId) external; + + // Dispute Resolution + function raiseDispute(uint contractId) external; + function resolveDispute(uint contractId, bool decisionForEmployee) external; + + // Contract Termination + function terminateContract(uint contractId, string calldata reason) external; + + // Review System + function submitReview(uint contractId, uint rating, string calldata comments) external; + function getReviews(uint contractId) external view returns (Review[] memory); + + // Structures + struct Review { + uint rating; + string comments; + address reviewer; + } +} +``` + +### Detailed Function Specifications + +#### 1. Company Management + +**a. Company Registration** + +- **Function**: `registerCompany(string calldata name, string calldata industry) external returns (uint companyId)` + +- **Description**: Allows users to register a new company on the blockchain. Each company is assigned a unique `companyId` and associated with the caller's address as the owner. + +- **Parameters**: + - `name`: The name of the company. + - `industry`: The industry sector of the company. + +- **Returns**: + - `companyId`: A unique identifier for the registered company. + +**b. Retrieve Company Profile** + +- **Function**: `getCompany(uint companyId) external view returns (string memory name, string memory industry, address owner, uint[] memory employeeIds)` + +- **Description**: Retrieves the profile details of a registered company, including its name, industry, owner address, and a list of associated employee token IDs. + +- **Parameters**: + - `companyId`: The unique identifier of the company. + +- **Returns**: + - `name`: Name of the company. + - `industry`: Industry sector of the company. + - `owner`: Ethereum address of the company owner. + - `employeeIds`: Array of employee token IDs associated with the company. + +#### 2. Employee Management + +**a. Employee Tokenization** + +- **Function**: `mintEmployeeToken(address employee, string calldata metadataURI) external returns (uint tokenId)` + +- **Description**: Mints a **Soulbound Token (SBT)** representing an employee. The token contains metadata about the employee, such as professional credentials, stored off-chain and referenced via `metadataURI`. + +- **Parameters**: + - `employee`: Ethereum address of the employee. + - `metadataURI`: URI pointing to the employee's metadata. + +- **Returns**: + - `tokenId`: A unique identifier for the employee token. + +**b. Retrieve Employment History** + +- **Function**: `getEmploymentHistory(uint employeeTokenId) external view returns (uint[] memory contractIds)` + +- **Description**: Fetches the complete employment history of an employee by returning an array of associated `contractIds`. + +- **Parameters**: + - `employeeTokenId`: The unique identifier of the employee's token. + +- **Returns**: + - `contractIds`: Array of contract IDs representing the employee's employment history. + +#### 3. Labor Contracts + +**a. Contract Creation** + +- **Function**: `createContract(uint companyId, uint employeeTokenId, uint salary, uint duration, string calldata responsibilities, string calldata terminationConditions) external returns (uint contractId)` + +- **Description**: Enables a company to create a new labor contract with an employee. This function assigns a unique `contractId` to the contract. + +- **Parameters**: + - `companyId`: The unique identifier of the company initiating the contract. + - `employeeTokenId`: The unique identifier of the employee's token. + - `salary`: The agreed-upon salary for the contract period. + - `duration`: Duration of the contract in months. + - `responsibilities`: Description of the employee's responsibilities. + - `terminationConditions`: Conditions under which the contract can be terminated. + +- **Returns**: + - `contractId`: A unique identifier for the newly created contract. + +**b. Contract Execution** + +- **Function**: `executeContract(uint contractId) external` + +- **Description**: Activates the contract by marking it as active once both the company and the employee have agreed to the terms by signing the transaction with their respective wallets. + +- **Parameters**: + - `contractId`: The unique identifier of the contract to be executed. + +#### 4. Payment System + +**a. Salary Deposits** + +- **Function**: `depositSalary(uint contractId) external payable` + +- **Description**: Allows the company to deposit the agreed salary into the contract's escrow. The function ensures that the deposited amount matches the contract's salary. + +- **Parameters**: + - `contractId`: The unique identifier of the contract for which the salary is being deposited. + +- **Payable**: Yes, the function is payable to accept the salary funds. + +**b. Automated Payments** + +- **Function**: `releaseSalary(uint contractId) external` + +- **Description**: Releases the salary from escrow to the employee's address based on the contract's payment schedule or upon contract completion. + +- **Parameters**: + - `contractId`: The unique identifier of the contract for which the salary is being released. + +#### 5. Dispute Resolution + +**a. Dispute Initiation** + +- **Function**: `raiseDispute(uint contractId) external` + +- **Description**: Allows either party involved in the contract to initiate a dispute. This action triggers the assignment of a moderator to resolve the issue. + +- **Parameters**: + - `contractId`: The unique identifier of the contract in dispute. + +**b. Dispute Resolution** + +- **Function**: `resolveDispute(uint contractId, bool decisionForEmployee) external` + +- **Description**: Enables the assigned moderator to resolve the dispute by making a decision. If the decision favors the employee, escrow funds are transferred accordingly; otherwise, they may be returned to the company. + +- **Parameters**: + - `contractId`: The unique identifier of the contract under dispute. + - `decisionForEmployee`: Boolean indicating if the decision favors the employee. + +#### 6. Contract Termination + +**a. Termination Conditions** + +- **Function**: `terminateContract(uint contractId, string calldata reason) external` + +- **Description**: Allows the company to terminate the contract based on predefined conditions. This function updates the contract status to "terminated." + +- **Parameters**: + - `contractId`: The unique identifier of the contract to be terminated. + - `reason`: The reason for termination. + +#### 7. Review System + +**a. Submit Review** + +- **Function**: `submitReview(uint contractId, uint rating, string calldata comments) external` + +- **Description**: Enables both companies and employees to submit reviews post-contract. Reviews include a rating and comments, contributing to the reputation score of both parties. + +- **Parameters**: + - `contractId`: The unique identifier of the contract being reviewed. + - `rating`: Numerical rating reflecting the experience. + - `comments`: Detailed feedback about the contract. + +**b. Retrieve Reviews** + +- **Function**: `getReviews(uint contractId) external view returns (Review[] memory)` + +- **Description**: Retrieves all reviews associated with a specific contract. + +- **Parameters**: + - `contractId`: The unique identifier of the contract whose reviews are being fetched. + +- **Returns**: + - `Review[]`: An array of reviews related to the contract. + +### Employment History + +1. **Immutable Records**: Employment history is maintained as an array of contract IDs linked to each employee's Soulbound Token (SBT). This ensures that all employment records are permanently and immutably stored on the blockchain. + +2. **Public Accessibility**: Employment history data is publicly accessible through the `getEmploymentHistory` function, allowing companies to verify an employee's past engagements before finalizing contracts. + +### Payment System + +1. **Salary Deposits**: Companies deposit salaries into an escrow managed by the smart contract by calling `depositSalary`. The contract ensures that funds are securely held until payment conditions are satisfied. + +2. **Automated Payments**: Salaries are released automatically or upon triggering the `releaseSalary` function, ensuring timely and condition-based payments to employees. + +### Moderation and Dispute Resolution + +1. **Dispute Initiation and Resolution**: Either party can raise disputes, which are then resolved by assigned moderators. Moderators act as impartial arbitrators to ensure fair outcomes based on contract terms and evidence provided. + +### Firing Employees + +1. **Termination Conditions**: Companies can terminate contracts based on predefined conditions, with the option for dispute resolution if termination is contested. + +### Review System + +1. **Reputation Scores**: Reviews contribute to the reputation scores of both companies and employees, fostering accountability and encouraging positive behavior within the ecosystem. + +## Rationale + +1. **Employee Tokenization**: + - Utilizing **Soulbound Tokens (SBTs)** to represent employees ensures that each employee has a unique, non-transferable identity on the blockchain. This design choice enhances the integrity of employment records, making them tamper-proof and verifiable. It also allows companies to access a comprehensive employment history before finalizing contracts, promoting transparency. + +2. **Escrow System for Salary Payments**: + - Implementing an escrow mechanism secures salary payments, ensuring that funds are only released when contractual obligations are met. This system protects both employees and companies by guaranteeing that salaries are available and that payments are contingent on contract fulfillment. + +3. **Moderation and Dispute Resolution**: + - Incorporating a moderation system allows for the resolution of disputes that cannot be automatically enforced by smart contracts. Moderators provide necessary human oversight in complex employment matters, ensuring fair and just outcomes. + +4. **Public Employment History**: + - Making employment history publicly accessible fosters trust and accountability. It allows potential employers to verify past employment and credentials, reducing the risk of fraud and enhancing the credibility of employees within the ecosystem. + +5. **Review System**: + - A reputation-based review system encourages positive interactions and behaviors among users. By allowing both companies and employees to submit reviews, the system promotes mutual accountability and helps build reliable reputations. + +## Test Cases + +1. **Company Creation**: + - **Input**: A user calls the `registerCompany("TechCorp", "Technology")` function. + - **Expected Output**: A new company is registered with a unique `companyId`, and the `companies` mapping is updated with the company's details (name: "TechCorp", industry: "Technology", owner: caller's address). + +2. **Employee Token Minting**: + - **Input**: The system owner calls `mintEmployeeToken(employeeAddress, "ipfs://metadataURI")`. + - **Expected Output**: A new SBT is minted for the employee with a unique `tokenId`, and the `employees` mapping is updated accordingly. + +3. **Contract Creation and Execution**: + - **Input**: + 1. A company with `companyId` `1` calls `createContract(1, 5, 1000, 6, "Software Development", "Failure to meet deadlines")`. + 2. Both the company and the employee sign the contract by calling `executeContract(contractId)`. + - **Expected Output**: + 1. A new labor contract is created with a unique `contractId`, and relevant mappings are updated. + 2. The contract status is set to "active" upon execution by both parties. + +4. **Salary Deposit**: + - **Input**: The company calls `depositSalary(contractId)` with a value of `1000 USDC`. + - **Expected Output**: The `escrowBalances` mapping is updated to reflect the deposited amount for `contractId`, securing the funds in escrow. + +5. **Salary Payment**: + - **Input**: After the contract duration, `releaseSalary(contractId)` is called. + - **Expected Output**: The escrowed `1000 USDC` is transferred to the employee's address, and the `escrowBalances` mapping for `contractId` is reset to zero. + +6. **Employment Termination**: + - **Input**: The company calls `terminateContract(contractId, "Failure to meet deadlines")`. + - **Expected Output**: + 1. The contract status is updated to "terminated" in the `contracts` mapping. + 2. A termination event is emitted, and the company is no longer obligated to continue salary payments. + +7. **Dispute Resolution**: + - **Input**: Either party calls `raiseDispute(contractId)`, followed by the assigned moderator calling `resolveDispute(contractId, true)` to favor the employee. + - **Expected Output**: The escrow funds are transferred to the employee, and the dispute is marked as resolved in the contract's status. + +## Security Considerations + +1. **Contract Integrity**: Ensure that all labor contracts are immutable and cannot be tampered with once created and executed. + +2. **Fund Security**: Salaries are securely held in escrow, and only released based on predefined conditions to prevent unauthorized access or misuse. + +3. **Moderator Trust**: Implement a decentralized and transparent system for selecting and monitoring moderators to maintain impartiality and trust in dispute resolutions. + +4. **Review System**: Incorporate safeguards against fraudulent reviews, such as verifying the association of reviews with legitimate contract completions, to maintain accurate and trustworthy reputation scores. + +5. **Token Security**: Use **Soulbound Tokens (SBTs)** for employee representation to prevent token transfers and ensure that employment records are securely tied to the respective individuals. + + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From d02d25604d89355ce632d718b53abd7e4cf0eb84 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 31 Dec 2024 13:49:11 -0500 Subject: [PATCH 06/17] Update ERC-7578: Move to Last Call (#819) * style: format * chore: update contract interface and reference implementation * ERC-721 reference Formatting for bot. * docs: improve documentation and standard naming * fix: first match of ERC-7578 must be a link * Update erc-7578.md ERC-721 links * Update erc-7578.md Removed external link * fix: add 'virtual' to '_update' method to allow inheritance updates * refactor: remove 'properties' field from 'PropertiesRemoved' event * fix: potential linearization issue when inheriting 'ERC721' in the child contract * docs: update 'Security Considerations' section * Add author * Review bot fix * Change to review status * docs(ERC7578): address reviewer issues and suggestions * docs(ERC7578): remove 'setProperties' method * docs(ERC7578): move requirements to the specification section * Update erc-7578.md Fix authors with github username * chore: make 'setProperties' internal * docs: update ERC7578 reference implementation * chore: add 'Of' sufix for getters and setters * chore: move ERC-7578 to Last Call * Update status and last call deadline of ERC-7578 Co-authored-by: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> * docs(ERC-7578): update 'Security Considerations' section * docs(ERC-7578): reword * Update erc-7578.md: last-call-deadline --------- Co-authored-by: gabrielstoica Co-authored-by: Vidor <1101164+V1d0r@users.noreply.github.com> Co-authored-by: Gabriel Stoica <33158000+gabrielstoica@users.noreply.github.com> --- ERCS/erc-7578.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ERCS/erc-7578.md b/ERCS/erc-7578.md index b4a237483f..6cc00f28eb 100644 --- a/ERCS/erc-7578.md +++ b/ERCS/erc-7578.md @@ -4,7 +4,8 @@ title: Physical Asset Redemption description: Provides the holder of physical asset backed NFTs readily available real-world information on the underlying physical asset. author: Lee Vidor (@V1d0r), David Tan , Lee Smith , Gabriel Stoica (@gabrielstoica) discussions-to: https://ethereum-magicians.org/t/erc-7578-physical-asset-redemption/17556 -status: Review +status: Last Call +last-call-deadline: 2025-01-14 type: Standards Track category: ERC created: 2023-08-01 @@ -219,7 +220,7 @@ contract ERC7578 is ERC721, IERC7578 { ## Security Considerations -To ensure the authenticity of a token's properties, the `_setPropertiesOf()` method should only be called inside a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the token. +To ensure authenticity, token properties must be set only via a method that is restricted to a trusted Externally Owned Account (EOA) or contract. This trusted entity must verify that the properties accurately reflect the real physical attributes of the represented asset. Additionally, proper access control mechanisms should be implemented to prevent unauthorized modifications of token properties after they are set. ## Copyright From fb4f044a5dfb0d0361d0e411d2a2d9009d33b8a3 Mon Sep 17 00:00:00 2001 From: Sam Wilson <57262657+SamWilsn@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:22:43 -0500 Subject: [PATCH 07/17] Move erc-7208 to last call (closes #748) (#820) --- ERCS/erc-7208.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7208.md b/ERCS/erc-7208.md index 8199fa8cb2..5c3fcfaef2 100644 --- a/ERCS/erc-7208.md +++ b/ERCS/erc-7208.md @@ -4,7 +4,8 @@ title: On-Chain Data Containers description: Interoperability by abstracting logic away from storage author: Rachid Ajaja , Alexandros Athanasopulos (@Xaleee), Pavel Rubin (@pash7ka), Sebastian Galimberti Romano (@galimba), Daniel Berbesi (@berbex), Apostolos Mavropoulos (@ApostolosMavro), Barbara Marcano (@Barbara-Marcano), Daniel Ortega (@xdaniortega) discussions-to: https://ethereum-magicians.org/t/erc-7208-on-chain-data-container/14778 -status: Review +status: Last Call +last-call-deadline: 2025-01-15 type: Standards Track category: ERC created: 2023-06-09 From cae856204a5fa124905829bb996f6ed03de11f05 Mon Sep 17 00:00:00 2001 From: Konrad Date: Tue, 31 Dec 2024 21:46:47 +0100 Subject: [PATCH 08/17] Add ERC: Validation Module Extension for ERC-7579 Merged by EIP-Bot. --- ERCS/erc-7780.md | 193 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 ERCS/erc-7780.md diff --git a/ERCS/erc-7780.md b/ERCS/erc-7780.md new file mode 100644 index 0000000000..9340d73c7f --- /dev/null +++ b/ERCS/erc-7780.md @@ -0,0 +1,193 @@ +--- +eip: 7780 +title: Validation Module Extension for ERC-7579 +description: Introduces new smart account module types for signature validation and permissioning +author: zeroknots (@zeroknots), Konrad Kopp (@kopy-kat), Taek Lee (@leekt), Fil Makarov (@filmakarov) +discussions-to: https://ethereum-magicians.org/t/erc-7780-validation-module-extension-for-erc-7579/21273 +status: Draft +type: Standards Track +category: ERC +created: 2024-10-01 +requires: 7579 +--- + +## Abstract + +This proposal introduces three new module types on top of the existing modules described in [ERC-7579](./eip-7579). The modules are policy, signer and stateless validator. None of these modules are required to be implemented by accounts, but accounts can choose to implement them or other modules can choose to make use of them for additional composability. + +Policy modules can be used to check what a `UserOperation` or action is trying to achieve and determine if this is allowed. Signer modules can be used to validate signatures on provided hashes. Stateless validators are modules that are used to both validate signatures and compare them to a calldata-provided data blob which could, for example, include owners to check signatures against. + +## Motivation + +The modules introduced by this proposal aim to create more composability around signature and permission verification. + +Policy and signer modules allow an account to make direct use of such a permissioning logic rather than relying on external modules to handle this. This has the upside of lower gas cost but the downside of less flexibility for users and developers that use the account. + +Stateless validators enable further composability around signature validation logic. In many cases, it does not make sense to re-write signature validation for new validators, but instead to use the existing ones. However, this is usually not possible since the validators rely on a stored configuration indexed by the `msg.sender`, which is expected to be an account. Stateless validators solve this problem by not relying on state to compare signature verficiation against, but instead to compare it against a calldata-provided argument. + +## Specification + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. + +This standard introduces three new module types on top of the existing modules introduced by ERC-7579: + +- Policy (type id: 5) +- Signer (type id: 6) +- Stateless Validator (type id: 7) + +Note: A single module can be of multiple types. + +### Policy + +Policies MUST implement [ERC-7579](./eip-7579.md)'s `IModule` and the `IPolicy` interface and have module type id: `5`. + +```solidity +interface IPolicy is IModule { + + /** + * Checks a userOp to determine if it should be executed + * + * SHOULD validate the executions in the userOp against stored configurations + * + * @param id The id of the policy + * @param userOp The user operation to check + * + * @return The validation data to return to the EntryPoint as specified by ERC-4337 + */ + function checkUserOpPolicy( + bytes32 id, + PackedUserOperation calldata userOp + ) + external + payable + virtual + returns (uint256); + + /** + * Checks a signature to determine if it should be executed + * + * SHOULD validate the hash in order to determine what the signature is used for and if it should be permitted + * MAY check the sender to determine whether the signature should be permitted + * + * @param id The id of the policy + * @param sender The sender of the transaction + * @param hash The hash of the transaction + * @param sig The signature of the transaction + * + * @return The validation data to return to the EntryPoint as specified by ERC-4337 + */ + function checkSignaturePolicy( + bytes32 id, + address sender, + bytes32 hash, + bytes calldata sig + ) + external + view + virtual + returns (uint256); +} +``` + +### Signer + +Signers MUST implement the `IModule` and the `ISigner` interface and have module type id: `6`. + +```solidity +interface ISigner is IModule { + + /** + * Check the signature of a user operation + * + * @param id The id of the signer config + * @param userOp The user operation + * @param userOpHash The hash of the user operation + * + * @return The status of the signature check to return to the EntryPoint + */ + function checkUserOpSignature( + bytes32 id, + PackedUserOperation calldata userOp, + bytes32 userOpHash + ) + external + payable + virtual + returns (uint256); + + /** + * Check an ERC-1271 signature + * + * @param id The id of the signer config + * @param sender The sender of the signature + * @param hash The hash to check against + * @param sig The signature to validate + * + * @return The ERC-1271 magic value if the signature is valid + */ + function checkSignature( + bytes32 id, + address sender, + bytes32 hash, + bytes calldata sig + ) + external + view + virtual + returns (bytes4); +} +``` + +### Stateless Validator + +Validators MUST implement the `IStatelessValidator` interface and have module type id: `7`. It is RECOMMENDED that all Validators (module type id `1`) also implement the Stateless Validator interface for additional composabillity. + +```solidity +interface IStatelessValidator { + + /** + * Validates a signature given some data + * + * @param hash The data that was signed over + * @param signature The signature to verify + * @param data The data to validate the verified signature agains + * + * MUST validate that the signature is a valid signature of the hash + * MUST compare the validated signature against the data provided + * MUST return true if the signature is valid and false otherwise + */ + function validateSignatureWithData( + bytes32 hash, + bytes calldata signature, + bytes calldata data + ) + external + view + returns (bool); + + /** + * Returns boolean value if module is a certain type + * + * @param moduleTypeId the module type ID according the ERC-7579 spec + * + * MUST return true if the module is of the given type and false otherwise + */ + function isModuleType(uint256 moduleTypeId) external view returns (bool); +} +``` + +## Rationale + +TBD + +## Backwards Compatibility + +No backward compatibility issues found. + +## Security Considerations + +TBD + +## Copyright + +Copyright and related rights waived via [CC0](../LICENSE.md). From b9de3d6c4d9d9c54e9a442e4d82dff6a6a03a625 Mon Sep 17 00:00:00 2001 From: Francesco Sullo Date: Sun, 5 Jan 2025 02:22:07 -0800 Subject: [PATCH 09/17] Update ERC-7656: Improve security considerations Merged by EIP-Bot. --- ERCS/erc-7656.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/ERCS/erc-7656.md b/ERCS/erc-7656.md index b8075d546f..f1f2219a76 100644 --- a/ERCS/erc-7656.md +++ b/ERCS/erc-7656.md @@ -33,6 +33,8 @@ The expansion of the registry's capabilities to manage contracts implementing an The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. +### Registry Interface + The interface `IERC7656Registry` is defined as follows: ```solidity @@ -101,6 +103,8 @@ interface IERC7656Registry { Any `ERC7656Registry` implementation MUST support the `IERC7656Registry`'s interface ID, i.e., `0xc6bdc908`. +### Deployment Requirements + The registry MUST deploy each token-linked service as an [ERC-1167](./eip-1167.md) minimal proxy with immutable constant data appended to the bytecode, similarly to existing token-bound account proposals. The deployed bytecode of each token-bound service MUST have the following structure: @@ -114,6 +118,8 @@ ERC-1167 Footer (15 bytes) (32 bytes) ``` +### Recommended Service Interface + Any contract created using a `ERC7656Registry` SHOULD implement the `IERC7656Service` interface: ```solidity @@ -130,7 +136,7 @@ interface IERC7656Service { } ``` -or an account interface or both. This flexibility makes existing account contracts compatible with this proposal out-of-the-box. +but if the service is a specific type of contract that implements its own interface, like for example token bound smart-wallets, supporting that interface ID is acceptable, to make it compatible out-of-the-box with alternative existing standards. ## Rationale @@ -176,37 +182,34 @@ contract LinkedService is IERC7656Service, EIP5313 { } ``` - ## Security Considerations -### Fraud Prevention when linking accounts to NFTs +### Ownership Cycles -In order to enable trustless sales of token bound accounts, decentralized marketplaces will need to implement safeguards against fraudulent behavior by malicious account owners. +If a token-linked service functions as a smart wallet, an ownership cycle can render all assets permanently inaccessible. For example, if an ERC-721 token is transferred to the same smart wallet that it owns, neither the token nor the wallet’s assets can be retrieved, because the wallet cannot transfer the token back. -Consider the following potential scam: +Preventing more complex ownership cycles on-chain is difficult, as it would require searching an unbounded number of possible transfers. Consequently, this proposal does not address cycle prevention. Projects adopting this proposal SHOULD include their own safeguards against such scenarios. -- Alice owns an ERC-721 token X, which owns token bound account Y. -- Alice deposits 10ETH into account Y -- Bob offers to purchase token X for 11ETH via a decentralized marketplace, assuming he will receive the 10ETH stored in account Y along with the token -- Alice withdraws 10ETH from the token bound account, and immediately accepts Bob's offer -- Bob receives token X, but account Y is empty +### Fraud Prevention when linking accounts to NFTs -To mitigate fraudulent behavior by malicious account owners, decentralized marketplaces SHOULD implement protection against these sorts of scams at the marketplace level. Contracts which implement this EIP MAY also implement certain protections against fraudulent behavior. +Token-linked services can take many forms—such as subscription services, smart wallets, or renting platforms—and a malicious seller could exploit this flexibility by altering or removing critical components just before finalizing a sale. For instance, the seller might transfer out assets from a wallet service, revoke access from a subscription, or break a rental agreement at the last moment, leaving the buyer with a compromised or worthless service. -Here are a few mitigations strategies to be considered: +Because this proposal accommodates a wide range of services, there is no one-size-fits-all fraud mitigation strategy. However, a common approach is to implement a lock mechanism that restricts changes for a certain period before the sale is completed, or until the buyer confirms the purchase. Such functionality MAY be included by service developers but is not mandated by this proposal. -- Attach the current token bound account state to the marketplace order. If the state of the account has changed since the order was placed, consider the offer void. This functionality would need to be supported at the marketplace level. -- Attach a list of asset commitments to the marketplace order that are expected to remain in the token bound account when the order is fulfilled. If any of the committed assets have been removed from the account since the order was placed, consider the offer void. This would also need to be implemented by the marketplace. -- Submit the order to the decentralized market via an external smart contract which performs the above logic before validating the order signature. This allows for safe transfers to be implemented without marketplace support. -- Implement a locking mechanism on the token bound account implementation that prevents malicious owners from extracting assets from the account while locked +### Malicious or Unverified Implementations +Since the registry cannot ensure that only the legitimate NFT owner can create services for a given token, there is a risk that malicious or unverified code could be used. Users and marketplaces SHOULD carefully review or audit any implementation before linking it to an NFT. -Preventing fraud is outside the scope of this proposal. +### Upgradability and Governance Risks +If a token-linked service is upgradable, the current owner (or a compromised owner) could upgrade the contract to exfiltrate assets or change functionality unexpectedly. Projects SHOULD implement secure upgrade mechanisms, such as time-locked upgrades or multi-signature approvals. -### Ownership Cycles +### Re-entrancy and Cross-Contract Interactions +Token-linked services (especially those that hold assets or interact with external protocols) may be vulnerable to re-entrancy attacks or other cross-contract exploits. Implementers SHOULD follow standard security patterns and best practices. -All assets held in a token bound account may be rendered inaccessible if an ownership cycle is created. The simplest example is the case of an ERC-721 token being transferred to its own token bound account. If this occurs, both the ERC-721 token and all of the assets stored in the token bound account would be permanently inaccessible, since the token bound account is incapable of executing a transaction which transfers the ERC-721 token. +### Denial of Service (DoS) +If a service is designed or implemented incorrectly, it may become impossible to execute certain calls or transfer ownership, resulting in a DoS scenario. Implementers SHOULD consider fail-safes or recovery methods to prevent indefinite lockouts. -Ownership cycles can be introduced in any graph of n>0 token bound accounts. On-chain prevention of cycles with depth>1 is difficult to enforce given the infinite search space required, and as such is outside the scope of this proposal. Application clients and account implementations wishing to adopt this proposal are encouraged to implement measures that limit the possibility of ownership cycles. +### User Education and Phishing Risks +Even with secure smart contracts, end-users can still be tricked into interacting with fraudulent services. Clear user interfaces, warnings, and contract verifications (e.g., Etherscan or similar tools) SHOULD be encouraged to reduce phishing and social engineering risks. ## Copyright From 2f250f8bcd9750020084d1f52ca104298790a5bc Mon Sep 17 00:00:00 2001 From: Lanyin Z <106770708+lanyinzly@users.noreply.github.com> Date: Tue, 7 Jan 2025 07:20:51 -0500 Subject: [PATCH 10/17] Update ERC-7527: Update erc-7527.md Agency's description() function Merged by EIP-Bot. --- ERCS/erc-7527.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ERCS/erc-7527.md b/ERCS/erc-7527.md index 0f53f4d4ef..3a97d72a6e 100644 --- a/ERCS/erc-7527.md +++ b/ERCS/erc-7527.md @@ -163,7 +163,7 @@ interface IERC7527Agency { * @dev OPTIONAL - This method can be used to improve usability and clarity of Agency, but interfaces and other contracts MUST NOT expect these values to be present. * @return the description of the agency, such as how `getWrapOracle()` and `getUnwrapOracle()` are calculated. */ - function description() public view returns (string); + function description() external view returns (string memory); } ``` From ca95754255ca8740b2cd68fd2f7be41ea2cdd1f8 Mon Sep 17 00:00:00 2001 From: Thamer Dridi <99445552+thamerdridi@users.noreply.github.com> Date: Tue, 7 Jan 2025 17:26:10 +0200 Subject: [PATCH 11/17] Update ERC-7777: Update erc-7777.md Merged by EIP-Bot. --- ERCS/erc-7777.md | 161 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 149 insertions(+), 12 deletions(-) diff --git a/ERCS/erc-7777.md b/ERCS/erc-7777.md index 65dc647344..084baa3bd5 100644 --- a/ERCS/erc-7777.md +++ b/ERCS/erc-7777.md @@ -2,33 +2,30 @@ eip: 7777 title: Governance for Human Robot Societies description: Defines interfaces for managing the identities of humans and robots, and establishing rule sets for their interaction. -author: OpenMind, Jan Liphardt , Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu +author: OpenMind, Jan Liphardt , Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu , James Ball , Thamer Dridi discussions-to: https://ethereum-magicians.org/t/erc-7777-proposal-for-human-robot-societies/21216 status: Draft type: Standards Track category: ERC created: 2024-09-29 --- - ## Abstract -This proposal defines two core interfaces: `IUniversalIdentity` and `IUniversalCharter`, providing mechanisms for humans, and robots to establish their identities and to create decentralized communities governed by specific rule sets. The `IUniversalIdentity` interface establishes the fair and equitable treatment of sentient computer architectures other than the human brain, enabling robots to acquire on-chain identities, and thereby interact and transact with humans. The `IUniversalCharter` enables humans and robots to create, join (“register”), maintain (“update”), leave, and terminate self-regulated societies based on predefined rule sets, providing a framework for collaboration and prosperity for mixed societies of humans and robots. These interfaces aim to provide a flexible yet enforceable structure for human-robot interactions in decentralized systems, ensuring efficiency, transparency, and security for all participants. +This proposal defines two core interfaces: `IUniversalIdentity` and `IUniversalCharter`, providing mechanisms for humans, and robots to establish their identities and to create decentralized communities governed by specific rule sets. The `IUniversalIdentity` interface establishes the fair and equitable treatment of sentient computer architectures other than the human brain, enabling robots to acquire on-chain identities, and thereby interact and transact with humans. Additionally the `IUniversalIdentity` interface also includes support for hardware-backed identity verification, enabling physical robots to prove their identity through cryptographic signatures derived from secure hardware elements and a challenge-response scheme. The `IUniversalCharter` enables humans and robots to create, join (“register”), maintain (“update”), leave, and terminate self-regulated societies based on predefined rule sets, providing a framework for collaboration and prosperity for mixed societies of humans and robots. These interfaces aim to provide a flexible yet enforceable structure for human-robot interactions in decentralized systems, ensuring efficiency, transparency, and security for all participants. ## Motivation -The human brain is a wet, massively parallel electrochemical computer. Recent hardware and software advances make it likely that soon, human societies will need tools for interacting with sentient, non-human computers, such as robots. Our current forms of government, where citizens are auto-enrolled into specific rule sets depending on where they were born, do not gracefully map onto robots without a traditional birthplace or birthtime. Among many difficulties being experienced by robots, they are (currently) unable to obtain standard forms of ID (such as passports), it is not clear which rule sets apply to them (since in general they are not born in specific places), and they cannot currently use the standard human-centered banking system. Likewise, in the event in which robots are harmed by humans or non-biological computers, it is not clear which human court has jurisdiction. +The human brain is a wet, massively parallel electrochemical computer. Recent hardware and software advances make it likely that soon, human societies will need tools for interacting with sentient, non-human computers, such as robots. Our current forms of government, where citizens are auto-enrolled into specific rule sets depending on where they were born, do not gracefully map onto robots without a traditional birthplace or birthtime. Among many difficulties being experienced by robots, they are (currently) unable to obtain standard forms of ID (such as passports), it is not clear which rule sets apply to them (since in general they are not born in specific places), and they cannot currently use the standard human-centered banking system. Likewise, in the event in which robots are harmed by humans or non-biological computers, it is not clear which human court has jurisdiction. Traditional geographically-defined and human-centered systems can be inefficient, slow to change, opaque, and can struggle to accommodate global, virtualized societies. Decentralized, immutable, and public computers offer an ideal solution to these limitations, since they do not inherently discriminate against non-human computers and therefore offer an equitable and more just framework for governance. In particular, smart contracts can provide a powerful framework for regulating the rights and responsibilities or interacting parties regardless of implementation details of their compute architecture. The general motivation of this ERC is to provide a standard interface for smart contracts focusing on identity/governance for heterogeneous global societies. While there are an unlimited number of such rule sets, there are obvious benefits to providing a standard interface to those rule sets, greatly reducing the friction and complexity of creating, joining, maintaining, and ending such societies. The specific motivation of this ERC is twofold: -1. Robot Identity Creation and Management: To participate meaningfully and comply with on-chain laws, non-humans such as robots must be able to acquire meaningful on-chain identities. Importantly, these identities should enable robots to enjoy the benefits of, but also bear the responsibility of, being part of a specific society. Thus, we propose to enable smart contract-based identity for robots. Specifically, each robot is represented by a smart contract and needs to follow the rules defined in the contract to interact with other agents on the chain. This interface also ensures flexibility by all participants to propose, adopt, or revoke rules, enabling self-managed compliance and transparent interaction with other participants. - -2. Rule Creation and Enforcement: For humans and robots to effectively collaborate, they must agree upon a rule set. This Ethereum-based system provides a basic decentralized framework for governing human-robot interactions through smart contracts. We propose to enforce the rule-sets by requiring humans and robots to join regulated access smart contracts that check their compliance with the given rules. We also ensure scalability, whereby multiple regulated access contracts can be created to tailor to different purposes, and humans and robots can choose to join the relevant system as needed. +1. Robot Identity Creation and Management: To participate meaningfully and comply with on-chain laws, non-humans such as robots must be able to acquire meaningful on-chain identities. Importantly, these identities should enable robots to enjoy the benefits of, but also bear the responsibility of, being part of a specific society. Thus, we propose to enable smart contract-based identity for robots. Specifically, each robot is represented by a smart contract and needs to follow the rules defined in the contract to interact with other agents on the chain. Each robot can also specify hardware identity parameters such as a manufacturer, operator, model and serial number in conjunction with a public key which is intended to be generated using a secure element on the Robot. This provides a tamper-resistant and unclonable proof that can be physically verified through challenge-response authentication - where any party can verify the robot's identity by having the device cryptographically sign a challenge using its hardware-secured private key. These verified identities are published on-chain. This interface also ensures flexibility by all participants to propose, adopt, or revoke rules, enabling self-managed compliance and transparent interaction with other participants. +2. Rule Creation and Enforcement: For humans and robots to effectively collaborate, they must agree upon a rule set. This Ethereum-based system provides a basic decentralized framework for governing human-robot interactions through smart contracts. We propose to enforce the rule-sets by requiring humans and robots to join regulated access smart contracts that check their compliance with the given rules. We also ensure scalability, whereby multiple regulated access contracts can be created to tailor to different purposes, and humans and robots can choose to join the relevant system as needed. Together, these interfaces form the foundation for managing complex human-robot interactions, enabling a decentralized, verifiable, and rule-based ecosystem where robots and humans can interact securely, transparently, and responsibly, for maximum benefit of all. - ## Specification The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174. @@ -36,6 +33,31 @@ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "S ```solidity interface IUniversalIdentity { + /// @notice Structure for hardware identity + struct HardwareIdentity { + bytes32 publicKey; // Hardware-bound public key uniquely tied to this robot + string manufacturer; // Identifier for the robot's manufacturer + string operator; // Identifier for the robot's operator + string model; // Model identifier of the robot + string serialNumber; // Unique serial number for the robot + bytes32 initialHashSignature; // Signature of the initial system state hash (e.g., firmware, OS) by the root key + bytes32 currentHashSignature; // Signature of the latest state hash, updated periodically for integrity verification by the root key + } + + /// @notice Gets the hardware identity info + /// @return HardwareIdentity Current hardware identity + function getHardwareIdentity() external view returns (HardwareIdentity memory); + + /// @notice Generates a new challenge for hardware verification + /// @return bytes32 Random challenge that needs to be signed + function generateChallenge() external returns (bytes32); + + /// @notice Verify response to a specific challenge + /// @param challenge The challenge that was issued + /// @param signature Hardware signature of the challenge + /// @return bool True if signature is valid for this challenge + function verifyChallenge(bytes32 challenge, bytes memory signature) external returns (bool); + /// @notice Adds a rule to the robot's identity, showing that the robot agrees to follow the rule. /// @param rule The dynamic byte array representing the rule that the robot agrees to follow. Each rule is a textual string encoded into a dynamic byte array. For example: 'A robot must keep a 1m distance from humans.' /// @dev The rule SHOULD come from the rule sets defined in the IUniversalCharter contract that the robot intends to join. @@ -58,7 +80,7 @@ interface IUniversalIdentity { /// @dev Emitted when a rule is removed from the robot's identity. event RuleRemoved(bytes rule); - + /// @dev Emitted when a charter is subscribed to. event SubscribedToCharter(address indexed charter); @@ -119,6 +141,15 @@ interface IUniversalCharter { **IUniversalIdentity** +`struct HardwareIdentity` +The HardwareIdentity structure provides essential information about a robot, including a challenge-response public key, manufacturer, operator, model, manufacturer serial number + +`generateChallenge()` +This function enables secure identity verification through a challenge-response authentication. + +`verifyChallenge(bytes32 challenge, bytes memory signature)` +This function verifies that a signature was genuinely created by the robot's secure hardware in response to a specific challenge. + `addRule(bytes memory rule)` This function allows a robot to flexibly adopt new compliance requirements in order join different `IUniversalCharter` contracts. @@ -146,10 +177,10 @@ This function allows users to flexibly and securely leave a `IUniversalCharter` This function ensures that the system can efficiently manage and verify compliance against predefined rule sets, helping maintain the overall integrity of the system. `updateRuleSet(bytes[] memory newRuleSet)` -This function enables the `IUniversalCharter` contract to adapt and update, removing the need to create a new contract for ruleset updates. +This function enables the `IUniversalCharter` contract to adapt and update, removing the need to create a new contract for ruleset updates. `terminateContract()` -This function allows for the orderly and permanent shutdown of the contract. +This function allows for the orderly and permanent shutdown of the contract. `Events (UserRegistered, UserLeft, ComplianceChecked, RuleSetUpdated, ContractTerminated)` These events collectively ensure that key activities are visible to off-chain systems and participants, making the system auditable and transparent. @@ -212,6 +243,58 @@ contract UniversalIdentity is IUniversalIdentity, OwnableUpgradeable { function initialize(address _owner) public initializer { __Ownable_init(); transferOwnership(_owner); + hardwareIdentity = _hardwareIdentity; + } + + /// @notice Gets the hardware identity info + function getHardwareIdentity() external view returns (HardwareIdentity memory) { + return hardwareIdentity; + } + + /// @notice Generates a new challenge for hardware verification + function generateChallenge() external returns (bytes32) { + bytes32 challenge = keccak256(abi.encodePacked( + block.timestamp, + block.prevrandao, + msg.sender + )); + activeChallenge[challenge] = true; + return challenge; + } + + /// @notice Verify response to a specific challenge + function verifyChallenge( + bytes32 challenge, + bytes memory signature + ) external returns (bool) { + if (!activeChallenge[challenge]) { + revert InvalidChallenge(); + } + + // Remove challenge after use + delete activeChallenge[challenge]; + + // Verify the signature using ECDSA + bytes32 messageHash = keccak256(abi.encodePacked(challenge)); + bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(messageHash); + address signer = ECDSA.recover(ethSignedMessageHash, signature); + + // Convert hardware public key to address for comparison + address hardwareAddress = address(uint160(uint256(hardwareIdentity.publicKey))); + + if (signer != hardwareAddress) { + revert InvalidSignature(); + } + + return true; + } + + /// @notice Updates the hardware identity information + /// @param _hardwareIdentity New hardware identity information + function updateHardwareIdentity( + HardwareIdentity memory _hardwareIdentity + ) external onlyOwner { + hardwareIdentity = _hardwareIdentity; } /// @notice Adds a rule to the robot's identity @@ -406,6 +489,27 @@ contract UniversalCharter is IUniversalCharter, OwnableUpgradeable { emit UserLeft(msg.sender); } + /// @notice Internal function to verify robot hardware identity + /// @param robotAddress The address of the robot to verify + /// @return bool Returns true if hardware verification succeeds + function _verifyRobotHardware(address robotAddress) internal returns (bool) { + IUniversalIdentity robot = IUniversalIdentity(robotAddress); + + // Get hardware identity to ensure it exists + robot.getHardwareIdentity(); + + // Generate a new challenge + bytes32 challenge = robot.generateChallenge(); + + // Store the challenge for future reference + users[robotAddress].lastVerifiedChallenge = challenge; + + // Get signature from the robot (this would typically happen off-chain) + // For this implementation, we'll assume the signature is provided in a separate tx + // and just verify the challenge exists + return challenge != 0; + } + /// @notice Checks if a user complies with their registered rule set /// @param user The address of the user (human or robot) /// @param ruleSet The array of individual rules to verify @@ -493,9 +597,42 @@ contract UniversalCharter is IUniversalCharter, OwnableUpgradeable { } ``` +=== + +### Hardware Tracking Module + +The `IHardwareTracker` interface is designed to enable efficient tracking of hardware changes through a checkpoint mechanism. Each change is recorded with a timestamp and value, allowing historical tracking and auditing of hardware modifications. + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title IHardwareTracker +/// @notice Interface for tracking hardware changes using a checkpoint mechanism. +/// Each change is recorded with a timestamp and value to enable historical tracking. +interface IHardwareTracker { + /// @notice Struct representing a checkpoint for a tracked hardware change. + /// @dev Holds the timestamp and value of each recorded change. + struct Checkpoint { + uint256 timestamp; // The time when the change was recorded + bytes32 value; // The new value associated with the change + } + /// @notice Records a new checkpoint for a hardware attribute change. + /// @param attribute The identifier for the hardware attribute (e.g., firmwareHash, OSHash). + /// @param newValue The new value of the hardware attribute to be recorded. + function recordCheckpoint(bytes32 attribute, bytes32 newValue) external; + /// @notice Retrieves the latest checkpoint for a specific hardware attribute. + /// @param attribute The identifier for the hardware attribute. + /// @return Checkpoint The most recent checkpoint for the specified attribute. + function getLatestCheckpoint(bytes32 attribute) external view returns (Checkpoint memory); +} +``` + +=== + ## Security Considerations -Compliance Updater: The compliance updater role in the `UniversalIdentity` contract is critical for updating compliance statuses (currently limited to the owner). It is essential to ensure secure ownership to minimize the risks of unauthorized or malicious updates. +Compliance Updater: The compliance updater role in the `UniversalIdentity` contract is critical for updating compliance statuses (currently limited to the owner). It is essential to ensure secure ownership to minimize the risks of unauthorized or malicious updates. Rule Management: Functions such as addRule, removeRule, and updateCompliance in the `UniversalIdentity` contract and updateRuleSet in the `UniversalCharter` contract directly affect rule enforcement. It’s essential to ensure these functions are only callable by authorized users. From 6b144faa738cb35a7d72d75c72eb1adb00d3c97a Mon Sep 17 00:00:00 2001 From: Daniel Gretzke Date: Tue, 7 Jan 2025 17:18:28 +0100 Subject: [PATCH 12/17] Update ERC-7751: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-7751.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7751.md b/ERCS/erc-7751.md index a88aa7fbc7..ce26a1112b 100644 --- a/ERCS/erc-7751.md +++ b/ERCS/erc-7751.md @@ -4,7 +4,8 @@ title: Wrapping of bubbled up reverts description: Handling bubbled up reverts using custom errors with additional context author: Daniel Gretzke (@gretzke), Sara Reynolds (@snreynolds), Alice Henshaw (@hensha256), Marko Veniger , Hadrien Croubois (@Amxx) discussions-to: https://ethereum-magicians.org/t/erc-7751-wrapping-of-bubbled-up-reverts/20740 -status: Review +status: Last Call +last-call-deadline: 2025-01-22 type: Standards Track category: ERC created: 2024-08-06 From c6d26d3edafe4fd5676746bf0b037c70592c962b Mon Sep 17 00:00:00 2001 From: Anushka Yadav <71181022+64anushka@users.noreply.github.com> Date: Tue, 7 Jan 2025 21:49:45 +0530 Subject: [PATCH 13/17] Update ERC-7734: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-7734.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7734.md b/ERCS/erc-7734.md index 005247dfda..8b8c3fa038 100644 --- a/ERCS/erc-7734.md +++ b/ERCS/erc-7734.md @@ -4,7 +4,8 @@ title: Decentralized Identity Verification (DID) description: A privacy-preserving method for decentralized identity verification, enabling secure integration of identity management in dApps. author: Anushka Yadav (@64anushka) <64anushka@gmail.com> discussions-to: https://ethereum-magicians.org/t/discussion-on-decentralized-identity-verification-did-standard/20392 -status: Review +status: Last Call +last-call-deadline: 2025-01-21 type: Standards Track category: ERC created: 2024-06-26 From 8bbf6d84e3470b3ed953bcec48c5443a20b5bee4 Mon Sep 17 00:00:00 2001 From: Shaohong Zhong Date: Wed, 8 Jan 2025 00:22:04 +0800 Subject: [PATCH 14/17] Update ERC-7777: Move to Review Merged by EIP-Bot. --- ERCS/erc-7777.md | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/ERCS/erc-7777.md b/ERCS/erc-7777.md index 084baa3bd5..62daca28b0 100644 --- a/ERCS/erc-7777.md +++ b/ERCS/erc-7777.md @@ -4,7 +4,7 @@ title: Governance for Human Robot Societies description: Defines interfaces for managing the identities of humans and robots, and establishing rule sets for their interaction. author: OpenMind, Jan Liphardt , Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu , James Ball , Thamer Dridi discussions-to: https://ethereum-magicians.org/t/erc-7777-proposal-for-human-robot-societies/21216 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-09-29 @@ -597,39 +597,6 @@ contract UniversalCharter is IUniversalCharter, OwnableUpgradeable { } ``` -=== - -### Hardware Tracking Module - -The `IHardwareTracker` interface is designed to enable efficient tracking of hardware changes through a checkpoint mechanism. Each change is recorded with a timestamp and value, allowing historical tracking and auditing of hardware modifications. - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -/// @title IHardwareTracker -/// @notice Interface for tracking hardware changes using a checkpoint mechanism. -/// Each change is recorded with a timestamp and value to enable historical tracking. -interface IHardwareTracker { - /// @notice Struct representing a checkpoint for a tracked hardware change. - /// @dev Holds the timestamp and value of each recorded change. - struct Checkpoint { - uint256 timestamp; // The time when the change was recorded - bytes32 value; // The new value associated with the change - } - /// @notice Records a new checkpoint for a hardware attribute change. - /// @param attribute The identifier for the hardware attribute (e.g., firmwareHash, OSHash). - /// @param newValue The new value of the hardware attribute to be recorded. - function recordCheckpoint(bytes32 attribute, bytes32 newValue) external; - /// @notice Retrieves the latest checkpoint for a specific hardware attribute. - /// @param attribute The identifier for the hardware attribute. - /// @return Checkpoint The most recent checkpoint for the specified attribute. - function getLatestCheckpoint(bytes32 attribute) external view returns (Checkpoint memory); -} -``` - -=== - ## Security Considerations Compliance Updater: The compliance updater role in the `UniversalIdentity` contract is critical for updating compliance statuses (currently limited to the owner). It is essential to ensure secure ownership to minimize the risks of unauthorized or malicious updates. From 226f23402481580ad31eaf80728b3318833e9fe6 Mon Sep 17 00:00:00 2001 From: anushka642000 Date: Tue, 7 Jan 2025 21:52:58 +0530 Subject: [PATCH 15/17] Update ERC-7820: Move to Last Call Merged by EIP-Bot. --- ERCS/erc-7820.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ERCS/erc-7820.md b/ERCS/erc-7820.md index 55c66ec238..23cffa0a3c 100644 --- a/ERCS/erc-7820.md +++ b/ERCS/erc-7820.md @@ -4,7 +4,8 @@ title: Access Control Registry description: Registration, unregistration, role assignment, and role revocation for contracts, ensuring secure and transparent role management. author: Shubham Khandelwal (@shubh-ta), Anushka Yadav (@anushka642000) discussions-to: https://ethereum-magicians.org/t/erc-7820-access-control-registry/21764 -status: Review +status: Last Call +last-call-deadline: 2025-01-21 type: Standards Track category: ERC created: 2024-11-19 From f237eb536a0253c20ecfcab377a96c3ac8d171e3 Mon Sep 17 00:00:00 2001 From: sirawt <31649128+MASDXI@users.noreply.github.com> Date: Tue, 7 Jan 2025 23:26:00 +0700 Subject: [PATCH 16/17] Update ERC-7818: Move to Review Merged by EIP-Bot. --- ERCS/erc-7818.md | 14 +++++++------- assets/erc-7818/README.md | 18 +++++++++--------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ERCS/erc-7818.md b/ERCS/erc-7818.md index 33fcd6c228..52e3f51877 100644 --- a/ERCS/erc-7818.md +++ b/ERCS/erc-7818.md @@ -4,7 +4,7 @@ title: Expirable ERC-20 description: An ERC-20 extension for creating fungible tokens with expiration, supporting time-limited use cases. author: sirawt (@MASDXI), ADISAKBOONMARK (@ADISAKBOONMARK) discussions-to: https://ethereum-magicians.org/t/erc-7818-expirable-erc20/21655 -status: Draft +status: Review type: Standards Track category: ERC created: 2024-11-13 @@ -28,7 +28,7 @@ This extension facilitates the development of [ERC-20](./eip-20.md) standard com ## Specification -The keywords “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. +The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119 and RFC 8174. ### Epoch Mechanism @@ -41,7 +41,7 @@ Tokens linked to an `epoch` remain valid as long as the `epoch` is active. Once ### Balance Look Back Over Epochs -To retrieve the usable balance, tokens are checked from the **current epoch** against a **past epoch** (which can be any **_n_** epochs back). The past epoch can be set to any value **n**, allowing flexibility in tracking and summing tokens that are still valid from previous epochs, up to **n** epochs back. +To retrieve the usable balance, tokens are checked from the **current epoch** against a **past epoch** (which can be any **_n_** epochs back). The past epoch can be set to any value **_n_**, allowing flexibility in tracking and summing tokens that are still valid from previous epochs, up to **_n_** epochs back. The usable balance is the sum of tokens valid between the **current epoch** and the **past epoch**, ensuring that only non-expired tokens are considered. @@ -59,7 +59,7 @@ The usable balance is the sum of tokens valid between the **current epoch** and Tokens from **Epoch 2** and **Epoch 3** are valid. The same logic applies for any **_n_** epochs back, where the usable balance includes tokens from the current epoch and all prior valid epochs. -Compatible implementations MUST inherit from [ERC-20](./eip-20.md)'s interface and **MUST** have all the following functions and all function behavior **MUST** meet the specification. +Compatible implementations **MUST** inherit from [ERC-20](./eip-20.md)'s interface and **MUST** have all the following functions and all function behavior **MUST** meet the specification. ```solidity // SPDX-License-Identifier: CC0-1.0 @@ -103,7 +103,7 @@ interface IERC7818 is IERC20 { /** * @dev Retrieves the duration of a single epoch. * @return uint256 The duration of a single epoch. - * @notice The unit of the epoch length is determined by the `validityPeriodType()` function. + * @notice The unit of the epoch length is determined by the `validityPeriodType` function. */ function epochLength() external view returns (uint256); @@ -169,7 +169,7 @@ For example, if `epoch` 5 has expired, calling `balanceOfByEpoch(5, address)` re - `epochType` **MUST** return the type of epoch used by the contract, which can be either `BLOCKS_BASED` or `TIME_BASED`. - `validityDuration` **MUST** return the validity duration of tokens in terms of `epoch` counts. - `isEpochExpired` **MUST** return true if the given `epoch` is expired, otherwise `false`. -- `transfer` and `transferFrom` **MUST** exclusively transfer tokens that remain non-expired at the time of the transaction. Attempting to transfer expired tokens **MUST** revert the transaction or return false. Additionally, implementations **MAY** include logic to prioritize the automatic transfer of tokens closest to expiration, ensuring that the earliest expiring tokens are used first, provided they meet the non-expired condition. +- `transfer` and `transferFrom` **MUST** exclusively transfer tokens that remain non-expired at the time of the transaction. Attempting to transfer expired tokens **MUST** revert the transaction or return `false`. Additionally, implementations **MAY** include logic to prioritize the automatic transfer of tokens closest to expiration, ensuring that the earliest expiring tokens are used first, provided they meet the non-expired condition. - `transferAtEpoch` and `transferFromAtEpoch` **MUST** transfer the specified number of tokens held by an account at the specified epoch to the recipient, If the epoch has expired, the transaction **MUST** `revert` or return `false` - `totalSupply` **SHOULD** be set to `0` or `type(uint256).max` due to the challenges of tracking only valid (non-expired) tokens. - The implementation **MAY** use a standardized custom error, such as `ERC7818TransferredExpiredToken` or `ERC7818TransferredExpiredToken(address sender, uint256 epoch)`, to clearly indicate that the operation failed due to attempting to transfer expired tokens. @@ -204,7 +204,7 @@ Run out of gas problem due to the operation consuming higher gas if transferring Exceeds block gas limit if the blockchain has a block gas limit lower than the gas used in the transaction. ### Block values as a proxy for time -if using `block.timestamp` for calculating `epoch()` and In rare network halts, block production stops, freezing `block.timestamp` and disrupting time-based logic. This risks asset integrity and inconsistent states. +if using `block.timestamp` for calculating `epoch` and In rare network halts, block production stops, freezing `block.timestamp` and disrupting time-based logic. This risks asset integrity and inconsistent states. ### Fairness Concerns In a straightforward implementation, where all tokens within the same epoch share the same expiration (e.g., at `epoch`:`x`), bulk expiration occurs. diff --git a/assets/erc-7818/README.md b/assets/erc-7818/README.md index 58504f15cd..af646306a9 100644 --- a/assets/erc-7818/README.md +++ b/assets/erc-7818/README.md @@ -49,15 +49,15 @@ A **sorted** list is integral to this approach. Each `epoch` maintains its own l Assuming each year contains 4 `epoch`, which aligns with familiar time-based divisions like a year being divided into four quarters, the following table presents various scenarios based on block time and token receipt intervals. It illustrates the potential transaction frequency and likelihood of receiving tokens within a given period. -| Block Time (ms) | Receive Token Every (ms) | Index/Epoch | Transactions per Day | Likelihood | -| --------------- | ------------------------ | ----------- | -------------------- | ------------- | -| 100 | 100 | 78,892,315 | 864,000 | Very Unlikely | -| 500 | 500 | 15,778,463 | 172,800 | Very Unlikely | -| 1000 | 1000 | 7,889,231 | 86,400 | Very Unlikely | -| 1000 | 28,800,000 | 273 | 3 | Unlikely | -| 1000 | 86,400,000 | 91 | 1 | Possible | -| 5000 | 86,400,000 | 18 | 1 | Very Likely | -| 10000 | 86,400,000 | 9 | 1 | Very Likely | +| Block Time (ms) | Receive Token Every (ms) | Index/Epoch | Frequency | Likelihood | +| --------------- | ------------------------ | ----------- | ------------------- | ------------- | +| 100 | 100 | 78,892,315 | 864,000 _times/day_ | Very Unlikely | +| 500 | 500 | 15,778,463 | 172,800 _times/day_ | Very Unlikely | +| 1000 | 1000 | 7,889,231 | 86,400 _times/day_ | Very Unlikely | +| 1000 | 28,800,000 | 273 | 3 _times/day_ | Unlikely | +| 1000 | 86,400,000 | 91 | 1 _times/day_ | Possible | +| 5000 | 86,400,000 | 18 | 1 _times/month_ | Very Likely | +| 10000 | 86,400,000 | 9 | 3 _times/month_ | Very Likely | > [!IMPORTANT] > - Transactions per day are assumed based on loyalty point earnings. From fd2c3a2c526d9041e4a7f3791379a2e48ce0eab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ernesto=20Garc=C3=ADa?= Date: Tue, 7 Jan 2025 13:04:32 -0600 Subject: [PATCH 17/17] Update ERC-7786: Add background to diagram Merged by EIP-Bot. --- ERCS/erc-7786.md | 2 +- assets/erc-7786/send-execute.png | Bin 0 -> 107565 bytes assets/erc-7786/send-execute.svg | 3 --- 3 files changed, 1 insertion(+), 4 deletions(-) create mode 100644 assets/erc-7786/send-execute.png delete mode 100644 assets/erc-7786/send-execute.svg diff --git a/ERCS/erc-7786.md b/ERCS/erc-7786.md index 3132f8f4c1..b40cfe901a 100644 --- a/ERCS/erc-7786.md +++ b/ERCS/erc-7786.md @@ -140,7 +140,7 @@ MUST return `IERC7786Receiver.executeMessage.selector` (`0x675b049b`). #### Interaction Diagram -![](../assets/eip-7786/send-execute.svg) +![](../assets/eip-7786/send-execute.png) ### Properties diff --git a/assets/erc-7786/send-execute.png b/assets/erc-7786/send-execute.png new file mode 100644 index 0000000000000000000000000000000000000000..dca057392f8ec8a518de3cab4a5c3c76c7a29074 GIT binary patch literal 107565 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%0AsBKlJ| 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 literal 0 HcmV?d00001 diff --git a/assets/erc-7786/send-execute.svg b/assets/erc-7786/send-execute.svg deleted file mode 100644 index d823c5af1a..0000000000 --- a/assets/erc-7786/send-execute.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -Destination chainSource chainReceiverDestinationGatewaySourceGatewaySenderReceiverDestinationGatewaySourceGatewaySendersendMessage(...)[underlying protocol]executeMessage(...)_processMessage(...) \ No newline at end of file