Skip to content

Commit

Permalink
Merge branch 'master' into solanaHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
sshmatrix authored Oct 12, 2024
2 parents 3ec7f62 + 3173a48 commit 4e18a9d
Show file tree
Hide file tree
Showing 10 changed files with 4,150 additions and 1,607 deletions.
14 changes: 7 additions & 7 deletions ERCS/erc-7578.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ interface IERC7578 {
* @dev Does NOT revert if token doesn't exist
* @param tokenId The token ID of the minted token
*/
function getProperties(uint256 tokenId) external view returns (Properties memory properties);
function getPropertiesOf(uint256 tokenId) external view returns (Properties memory properties);
}
```

When `properties` are set, the `PropertiesSet(uint256 indexed tokenId, Properties properties)` event is emitted.

When `properties` are removed, the `PropertiesRemoved(uint256 indexed tokenId)` event is emitted.

The `getProperties(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct.
The `getPropertiesOf(uint256 tokenId)` function MUST return the unique `properties` of a token. If the ERC-721 token is burned or has no properties set, it SHOULD return an empty `Properties` struct.

## Rationale

Expand Down Expand Up @@ -158,7 +158,7 @@ contract ERC7578 is ERC721, IERC7578 {
/**
* @inheritdoc IERC7578
*/
function getProperties(uint256 tokenId) public view override returns (Properties memory properties) {
function getPropertiesOf(uint256 tokenId) public view override returns (Properties memory properties) {
properties = _properties[tokenId];
}
Expand All @@ -172,7 +172,7 @@ contract ERC7578 is ERC721, IERC7578 {
*
* Emits a {PropertiesSet} event
*/
function _setProperties(uint256 tokenId, Properties calldata properties) internal {
function _setPropertiesOf(uint256 tokenId, Properties calldata properties) internal {
_properties[tokenId] = Properties({
tokenIssuer: properties.tokenIssuer,
assetHolder: properties.assetHolder,
Expand All @@ -194,7 +194,7 @@ contract ERC7578 is ERC721, IERC7578 {
*
* Emits a {PropertiesRemoved} event
*/
function _removeProperties(uint256 tokenId) internal {
function _removePropertiesOf(uint256 tokenId) internal {
delete _properties[tokenId];
emit PropertiesRemoved(tokenId);
}
Expand All @@ -207,7 +207,7 @@ contract ERC7578 is ERC721, IERC7578 {
function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
address from = _ownerOf(tokenId);
if (to == address(0)) {
_removeProperties(tokenId);
_removePropertiesOf(tokenId);
} else if (from == address(0)) {
if (bytes(_properties[tokenId].tokenIssuer).length == 0) revert PropertiesUninitialized();
}
Expand All @@ -219,7 +219,7 @@ contract ERC7578 is ERC721, IERC7578 {

## Security Considerations

To ensure the authenticity of a token's properties, the `_setProperties()` 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 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.

## Copyright

Expand Down
21 changes: 21 additions & 0 deletions ERCS/erc-7579.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ The account MAY also implement the following function in accordance with ERC-433
function executeUserOp(PackedUserOperation calldata userOp, bytes32 userOpHash) external;
```

If an account chooses to implement `executeUserOp`, this method SHOULD ensure the account executes `userOp.calldata` except 4 most significant bytes, which are reserved for `executeUserOp.selector` as per ERC-4337. Thus the `userOp.callData[4:]` should represent the calldata for a valid call to the account. It is RECOMMENDED that the account executes a `delegatecall` in order to preserve the original `msg.sender` to the account.

Example:
```
(bool success, bytes memory innerCallRet) = address(this).delegatecall(userOp.callData[4:]);
```

The execution mode is a `bytes32` value that is structured as follows:

- callType (1 byte): `0x00` for a single `call`, `0x01` for a batch `call`, `0xfe` for `staticcall` and `0xff` for `delegatecall`
Expand Down Expand Up @@ -223,6 +230,9 @@ If the smart account has a fallback handler installed, it:
- MUST route to fallback handlers based on the function selector of the calldata
- MAY implement authorization control, which SHOULD be done via hooks

If the account adds features via fallback, these should be considered the same as if the account was implementing those features natively.
ERC-165 support (see below) is one example of such an approach. Note, that it is only RECOMMENDED to implement view functions via fallback where this can lead to greater extensibility. It is NOT RECOMMENDED to implement core account logic via a fallback.

#### 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.
Expand Down Expand Up @@ -268,6 +278,17 @@ interface IModule {
}
```

Note: A single module that is of multiple types MAY decide to pass `moduleTypeId` inside `data` to `onInstall` and/or `onUninstall` methods, so those methods are able to properly handle installation/uninstallation for various types.
Example:
```solidity
// Module.sol
function onInstall(bytes calldata data) external {
// ...
(uint256 moduleTypeId, bytes memory otherData) = abi.decode(data, (uint256, bytes));
// ...
}
```

#### Validators

Validators MUST implement the `IModule` and the `IValidator` interface and have module type id: `1`.
Expand Down
51 changes: 29 additions & 22 deletions ERCS/erc-7751.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ created: 2024-08-06

## Abstract

This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using custom errors. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The custom errors should follow the naming structure `Wrap__` followed by a descriptive name and allow an arbitrary number of parameters, with the first being the address of the called contract and the second being the raw bytes of the bubbled up revert.
This ERC proposes a standard for handling bubbled up reverts in Ethereum smart contracts using a dedicated custom error. This standard aims to improve the clarity and usability of revert reasons by allowing additional context to be passed alongside the raw bytes of the bubbled up revert. The `WrappedError` custom error should wrap reverts from called contracts and provide a consistent interface for parsing and handling reverts in tools like Etherscan or Tenderly.

## Motivation

Expand All @@ -22,20 +22,22 @@ Currently, when a smart contract calls another and the called contract reverts,

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.

1. **Custom Error Naming Convention:**
- Custom errors that bubble up reverts MUST be prefixed with `Wrap__`.
- Example: `Wrap__ERC20TransferFailed`.
2. **Parameters:**
- The first parameter MUST be the address of the called contract that reverted.
- The second parameter MUST be the raw bytes of the bubbled up revert.
- Additional parameters MAY be included to provide context.
- Example: `Wrap__ERC20TransferFailed(address token, bytes reason, address recipient)`.
In order to wrap a revert, a contract MUST revert with the following error that corresponds to the following signature `0x90bfb865`:

If no additional parameters are defined and a generic call reverts, the custom error `Wrap__SubcontextReverted(address, bytes)` SHOULD be thrown to ensure a consistent signature.
```solidity
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);
```

Where:

- `target` is the address of the called contract that reverted.
- `selector` is the selector of the called function that reverted. If the call was an ETH transfer without any data, the selector MUST be `bytes4(0)`
- `reason` is the raw bytes of the revert reason.
- `details` is optional additional context about the revert. In cases where no additional context is needed, the `details` bytes can be empty. In cases with additional context, the `details` bytes MUST be an ABI encoded custom error declared on the contract that emits the `WrappedError` error.

## Rationale

By including the called contract, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general.
By including the called contract and function, raw revert bytes and additional context, developers can provide more detailed information about the failure. Additionally, by standardizing the way reverts are bubbled up, it also enables nested bubbled up reverts where multiple reverts thrown by different contracts can be followed recursively. The reverts can also be parsed and handled by tools like Etherscan and Foundry to further enhance the readability and debuggability of smart contract interactions, as well as facilitating better error handling practices in general.

## Backwards Compatibility

Expand Down Expand Up @@ -64,7 +66,9 @@ contract Token {
contract Vault {
Token token;
error Wrap__ERC20TransferFailed(address token, bytes reason, address recipient);
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);
error ERC20TransferFailed(address recipient);
constructor(Token token_) {
token = token_;
Expand All @@ -73,15 +77,15 @@ contract Vault {
function withdraw(address to, uint256 amount) external {
// logic
try token.transfer(to, amount) {} catch (bytes memory error) {
revert Wrap__ERC20TransferFailed(address(token), error, to);
revert WrappedError(address(token), token.transfer.selector, error, abi.encodeWithSelector(ERC20TransferFailed.selector, to));
}
}
}
contract Router {
Vault vault;
error Wrap__SubcontextReverted(address target, bytes reason);
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);
constructor(Vault vault_) {
vault = vault_;
Expand All @@ -90,7 +94,7 @@ contract Router {
function withdraw(uint256 amount) external {
// logic
try vault.withdraw(msg.sender, amount) {} catch (bytes memory error) {
revert Wrap__SubcontextReverted(address(vault), error);
revert WrappedError(address(vault), vault.withdraw.selector, error, "");
}
}
}
Expand All @@ -103,12 +107,13 @@ contract Test {
try router.withdraw(amount) {} catch (bytes memory thrownError) {
bytes memory expectedError = abi.encodeWithSelector(
Router.Wrap__SubcontextReverted.selector, address(vault), abi.encodeWithSelector(
Vault.Wrap__ERC20TransferFailed.selector,
Router.WrappedError.selector, address(vault), vault.withdraw.selector, abi.encodeWithSelector(
Vault.WrappedError.selector,
address(token),
token.transfer.selector,
abi.encodeWithSignature("Error(string)", "insufficient balance"),
address(this)
)
abi.encodeWithSelector(Vault.ERC20TransferFailed.selector, address(this))
), ""
);
assert(keccak256(thrownError) == keccak256(expectedError));
}
Expand All @@ -122,21 +127,23 @@ When catching a revert from a called contract, the calling contract should rever

```solidity
contract Foo {
error Wrap__SubcontextReverted(address target, bytes reason);
error WrappedError(address target, bytes4 selector, bytes reason, bytes details);
error MyCustomError(uint256 x);
function foo(address to, bytes memory data) external {
// logic
(bool success, bytes memory returnData) = to.call(data);
if (!success) {
revert Wrap__SubcontextReverted(to, returnData);
revert WrappedError(to, bytes4(data), returnData, abi.encodeWithSelector(MyCustomError.selector, 42));
}
}
}
```

## Security Considerations

This EIP does not introduce new security risks.
Smart contracts could either drop or purposefully suppress the bubbled up reverts along the revert chain. Additionally, smart contracts may also lie or incorrectly report the wrapped reverts, so the information is not guaranteed to be accurate.

## Copyright

Expand Down
93 changes: 93 additions & 0 deletions assets/erc-7700/fonts/Licenses/Rajdhani.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
Copyright (c) 2009, Indian Type Foundry

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://openfontlicense.org


-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Loading

0 comments on commit 4e18a9d

Please sign in to comment.