Skip to content

Add ERC: Confidential Real World Asset Token - #2034

Open
arr00 wants to merge 9 commits into
ethereum:masterfrom
arr00:feat/add-confidential-rwa
Open

arr00 wants to merge 9 commits into
ethereum:masterfrom
arr00:feat/add-confidential-rwa

Conversation

@arr00

@arr00 arr00 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

This PR adds a new ERC that extends ERC-7984 for confidential RWA tokens. As in ERC-7984, confidentiality is maintained via an implementation-specific pointer-based confidentiality system.

@eip-review-bot

eip-review-bot commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

File ERCS/erc-8424.md

Requires 1 more review from Editors: @g11tech, @jochem-brouwer, @samwilsn, @xinbenlv

@eip-review-bot eip-review-bot changed the title Add ERC: Confidential RWA Token Add ERC: Confidential Real World Asset Token Sep 25, 2026
@github-actions github-actions Bot added the w-ci label Sep 25, 2026
@github-actions

Copy link
Copy Markdown

The commit 7e9eb24 (as a parent of 070030a) contains errors.
Please inspect the Run Summary for details.

Comment thread ERCS/erc-draft_confidential_rwa.md Outdated
Comment thread ERCS/erc-draft_confidential_rwa.md Outdated
arr00 and others added 2 commits September 25, 2026 10:05
Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com>
@github-actions github-actions Bot removed the w-ci label Sep 25, 2026
Comment thread ERCS/erc-8424.md
- MUST return a pointer to false OR revert if `canSend(from)` returns false, unless `from` is the zero address.
- MUST return a pointer to false OR revert if `canReceive(to)` returns false, unless `to` is the zero address.
- MUST return a pointer to false OR revert if any other rule would prevent the transfer (such as vesting, balance caps, etc).
- MUST return a pointer to false if `amount` exceeds the value returned by `confidentialAvailableBalanceOf(from)`, unless `from` is the zero address.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyone can call confidentialCanTransfer with any from and any amount, and the result is false exactly when amount exceeds from's available balance. If the caller can resolve the returned pointer, that is a balance oracle: about 64 calls with a binary search give you anyone's exact available balance. confidentialAvailableBalanceOf(account) does the same in one call. The spec leaves "who can resolve a pointer" to the implementation, so a naive implementation that grants the caller access is compliant. Can we say who may resolve the results (e.g. only from/operator for confidentialCanTransfer, only account and parties it authorised for confidentialAvailableBalanceOf)?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Further, an implementation would also need to limit calls to this function somehow (either flow limiting or only to trusted operators) since even a user calling confidentialCanTransfer from themselves would be able to bypass some expected confidentiality by trying to send different amounts to a given recipient.

Comment thread ERCS/erc-8424.md Outdated
Comment thread ERCS/erc-8424.md

### Token

Compliant tokens MUST implement [ERC-7984](./eip-7984.md) and [ERC-165](./eip-165.md). The `supportsInterface` function MUST return `true` when the `interfaceID` argument is `0x00000000`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace if/when any signature changes

Suggested change
Compliant tokens MUST implement [ERC-7984](./eip-7984.md) and [ERC-165](./eip-165.md). The `supportsInterface` function MUST return `true` when the `interfaceID` argument is `0x00000000`.
Compliant tokens MUST implement [ERC-7984](./eip-7984.md) and [ERC-165](./eip-165.md). The `supportsInterface` function MUST return `true` when the `interfaceID` argument is `0xcd0f4d6c`.

Comment thread ERCS/erc-8424.md
Comment on lines +126 to +128
- MAY move 0 tokens if `amount` exceeds `confidentialAvailableBalanceOf(from)`
- MUST revert if `canReceive(to)` returns false.
- MUST NOT call `confidentialCanTransfer`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forced transfers usually is to move frozen funds. With "MAY move 0 tokens if amount exceeds confidentialAvailableBalanceOf(from)", a compliant token can refuse that, so an issuer can't rely on the function across implementations. It also doesn't say whether canSend(from) is bypassed, or what happens to the frozen amount after part of it is seized. ERC-7943 unfreezes first. "MUST NOT call confidentialCanTransfer" describes the implementation, but what we mean is that the Transfer Behavior rule doesn't apply here. Can we decide the frozen-funds case explicitly and state the canSend bypass?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely can state the canSend bypass. We've discussed the concept of moving frozen funds a couple times in the past, will come back to it.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following up on the MAY: it makes forced-transfer behaviour unpredictable across implementations. I don't see why a forced transfer shouldn't be able to take the whole balance. And since, unlike ERC-7943, this ERC doesn't standardize freezing, an issuer would first have to lift the restrictions in an implementation-specific way to make the whole balance available, and only then force the transfer. Could this be a MUST?

Suggested change
- MAY move 0 tokens if `amount` exceeds `confidentialAvailableBalanceOf(from)`
- MUST revert if `canReceive(to)` returns false.
- MUST NOT call `confidentialCanTransfer`.
- MUST NOT be limited by `confidentialAvailableBalanceOf(from)`.
- MUST revert if `canReceive(to)` returns false.
- MUST NOT call `canSend(from)`.
- MUST NOT call `confidentialCanTransfer`.

Comment thread ERCS/erc-8424.md Outdated
Comment thread ERCS/erc-8424.md
- MAY move 0 tokens if `amount` exceeds `confidentialAvailableBalanceOf(from)`
- MUST revert if `canReceive(to)` returns false.
- MUST NOT call `confidentialCanTransfer`.
- MUST emit `ConfidentialTransfer` as defined by [ERC-7984](./eip-7984.md), in addition to `ConfidentialForcedTransfer`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we be specific this is the pointer and not the amount?

Suggested change
- MUST emit `ConfidentialTransfer` as defined by [ERC-7984](./eip-7984.md), in addition to `ConfidentialForcedTransfer`.
- MUST emit `ConfidentialTransfer` as defined by [ERC-7984](./eip-7984.md), in addition to `ConfidentialForcedTransfer`, both with the returned pointer as `amount`.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that line 36 already says the following:

All amounts are confidential pointers represented as bytes32 values, as defined by ERC-7984. The mechanism by which a pointer is resolved, and the mechanism by which an account is authorized to resolve one, are implementation specific.

Do you think further clarification is needed here?

Maybe we should add a requirement that the return amount is equal to the event amount?

arr00 and others added 3 commits October 1, 2026 15:49
Co-authored-by: eitjuh <1449065+eitjuh@users.noreply.github.com>
Co-authored-by: eitjuh <1449065+eitjuh@users.noreply.github.com>
Comment thread ERCS/erc-8424.md
Returns a pointer to the largest amount `account` could transfer at the time of the call, disregarding rules that depend on the recipient.
- MUST be less than or equal to `confidentialBalanceOf(account)`.
- MUST account for every restriction the implementation applies to the account's own balance, including issuer freezes, lockups, vesting schedules, and pledged amounts.
- SHOULD NOT revert.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"SHOULD NOT revert" reads as applying to every caller, which conflicts with restricting who may query this (see the thread on L101). Reverting because the caller isn't authorised discloses nothing, since isOperator is public. What must not revert is anything that depends on confidential state. Could the two be split?

Suggested change
- SHOULD NOT revert.
- MUST revert unless the caller is `account`, an operator of `account`, or a party the implementation authorizes to resolve `account`'s balance.
- MUST NOT revert for any reason that depends on confidential state.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer an implementation gate access to this function via handle access control as opposed to explicitly reverting on the call to confidentialAvailableBalanceOf. This allows relayers etc to facilitate user interactions without gaining access to private data.

Comment thread ERCS/erc-8424.md Outdated
Co-authored-by: akerbabber <maurizio.murru93@gmail.com>
Comment thread ERCS/erc-8424.md Outdated
Comment thread ERCS/erc-8424.md Outdated
Comment thread ERCS/erc-8424.md Outdated
Co-authored-by: Arr00 <13561405+arr00@users.noreply.github.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants