Skip to content

Return the amount of wrapped token sent on wrap calls#307

Merged
arr00 merged 1 commit intomasterfrom
feat/return-wrapped-amount
Feb 19, 2026
Merged

Return the amount of wrapped token sent on wrap calls#307
arr00 merged 1 commit intomasterfrom
feat/return-wrapped-amount

Conversation

@arr00
Copy link
Copy Markdown
Member

@arr00 arr00 commented Feb 13, 2026

The amount wrapped is readily available to the wrap function--we should return it with transient approval for integrators.

Summary by CodeRabbit

  • New Features
    • The wrap function now returns the amount of wrapped tokens sent on wrap calls.

@arr00 arr00 requested a review from a team as a code owner February 13, 2026 16:04
@netlify
Copy link
Copy Markdown

netlify bot commented Feb 13, 2026

Deploy Preview for confidential-tokens ready!

Name Link
🔨 Latest commit d8b781e
🔍 Latest deploy log https://app.netlify.com/projects/confidential-tokens/deploys/698f4b7d0ca3c3000827adbc
😎 Deploy Preview https://deploy-preview-307--confidential-tokens.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 13, 2026

Walkthrough

The PR updates the ERC7984ERC20Wrapper contract to modify the wrap function API, making it return the amount of wrapped tokens as an euint64 value. The implementation now captures the minted amount and calls FHE.allowTransient for the wrapped amount. Changes include updates to both the interface signature and implementation.

Changes

Cohort / File(s) Summary
Changeset
.changeset/pink-areas-double.md
Documents the minor update marking the behavioral change to wrap function returning wrapped token amount.
Interface & Implementation
contracts/interfaces/IERC7984ERC20Wrapper.sol, contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol
Updated wrap function signature to return euint64 representing the amount of wrapped tokens. Implementation now captures minted amount in a local variable, calls FHE.allowTransient for transient authorization, and returns the wrapped amount.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

  • Issue #304: Directly addresses the same wrap() API modification to return the wrapped amount (euint64) across the ERC7984ERC20Wrapper interface and implementation.

Possibly related PRs

  • PR #268: Modifies ERC7984ERC20Wrapper.wrap and the handling of minted/wrapped amount types and return values.
  • PR #288: Updates ERC7984ERC20Wrapper to add return semantics for wrapper operations (unwrap variant of the same API pattern change).

Suggested reviewers

  • Amxx
  • james-toussaint

Poem

🐰 A wrap that now reveals its gift,
Returns the tokens with a swift lift,
With transient allowance freshly placed,
The wrapped amount's return embraced! ✨

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: the wrap function now returns the amount of wrapped tokens sent, which is reflected across all modified files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into master

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/return-wrapped-amount

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol`:
- Around line 82-93: The wrap function may silently receive a short or zero mint
from _mint (which returns the encrypted amount minted), so update wrap to
validate the returned euint64 wrappedAmountSent against the expected minted
quantity (compute expected as FHE.asEuint64(SafeCast.toUint64(amount / rate()))
or equivalent) and revert if wrappedAmountSent is zero or not equal to the
expected value; ensure you perform this check before calling FHE.allowTransient
and returning, or alternatively upgrade the ERC7984 implementation to >=0.3.1 to
eliminate the silent-failure bug (references: wrap, _mint, wrappedAmountSent,
rate(), FHE.allowTransient).

Comment on lines +82 to +93
*
* Returns the amount of wrapped token sent.
*/
function wrap(address to, uint256 amount) public virtual override {
function wrap(address to, uint256 amount) public virtual override returns (euint64) {
// take ownership of the tokens
SafeERC20.safeTransferFrom(IERC20(underlying()), msg.sender, address(this), amount - (amount % rate()));

// mint confidential token
_mint(to, FHE.asEuint64(SafeCast.toUint64(amount / rate())));
euint64 wrappedAmountSent = _mint(to, FHE.asEuint64(SafeCast.toUint64(amount / rate())));
FHE.allowTransient(wrappedAmountSent, msg.sender);

return wrappedAmountSent;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the main ERC7984 contract file
fd -a '^ERC7984\.sol$' --type f contracts/

Repository: OpenZeppelin/openzeppelin-confidential-contracts

Length of output: 343


🏁 Script executed:

#!/bin/bash
# Find and examine _mint implementation
rg -n "function _mint" contracts/token/ERC7984/ -A 10

Repository: OpenZeppelin/openzeppelin-confidential-contracts

Length of output: 343


🏁 Script executed:

#!/bin/bash
# Also check _update implementation since _mint often delegates to it
rg -n "function _update" contracts/token/ERC7984/ -A 10

Repository: OpenZeppelin/openzeppelin-confidential-contracts

Length of output: 343


🏁 Script executed:

#!/bin/bash
# Check the wrap function documentation more thoroughly
cat -n contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol | sed -n '75,95p'

Repository: OpenZeppelin/openzeppelin-confidential-contracts

Length of output: 343


🌐 Web query:

ERC7984 _mint return semantics OpenZeppelin confidential contracts

💡 Result:

In OpenZeppelin Confidential Contracts (@openzeppelin/confidential-contracts), ERC7984’s internal mint is not “ERC20-style (bool success / revert)”. Its signature is:

  • function _mint(address to, euint64 amount) internal returns (euint64 transferred) — it returns the encrypted amount actually minted (“transferred”), not a boolean. [1]

Return semantics (important):

  • The transferred return value can be less than requested, including 0.
  • In particular, in versions <= 0.3.0, if minting would make the confidential euint64 total supply overflow, _mint can fail silently (i.e., not revert) and effectively mint 0, so callers must not assume mint succeeded unless they check the returned transferred. This behavior is the root cause of GHSA-hqf9-8xv5-x8xw. [2]

Practical implication:

  • If your logic needs “mint must succeed or revert” (e.g., wrappers), you should check the returned euint64 transferred (or upgrade to >= 0.3.1, which patches the wrapper-side issue). [2]

Sources: OpenZeppelin ERC7984 API docs [1], OpenZeppelin advisory GHSA-hqf9-8xv5-x8xw (patched in 0.3.1) [2].


The wrap function must handle potential silent mint failures.

_mint in ERC7984 returns the encrypted amount actually minted (not the updated balance), so the return semantics are correct. However, in versions <= 0.3.0, _mint can silently fail to mint the full amount or return 0 due to overflow, without reverting. The wrap function should either:

  • Validate that wrappedAmountSent equals the requested amount (or handle underflow)
  • Upgrade to version >= 0.3.1, which patches this issue
  • Or explicitly document this failure mode for callers
🤖 Prompt for AI Agents
In `@contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol` around lines 82 -
93, The wrap function may silently receive a short or zero mint from _mint
(which returns the encrypted amount minted), so update wrap to validate the
returned euint64 wrappedAmountSent against the expected minted quantity (compute
expected as FHE.asEuint64(SafeCast.toUint64(amount / rate())) or equivalent) and
revert if wrappedAmountSent is zero or not equal to the expected value; ensure
you perform this check before calling FHE.allowTransient and returning, or
alternatively upgrade the ERC7984 implementation to >=0.3.1 to eliminate the
silent-failure bug (references: wrap, _mint, wrappedAmountSent, rate(),
FHE.allowTransient).

@arr00 arr00 merged commit 136840e into master Feb 19, 2026
20 of 21 checks passed
@arr00 arr00 deleted the feat/return-wrapped-amount branch February 19, 2026 00:16
@arr00 arr00 linked an issue Feb 27, 2026 that may be closed by this pull request
@github-actions github-actions bot mentioned this pull request Mar 5, 2026
@github-actions github-actions bot mentioned this pull request Mar 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Return amount wrapped on wrap call in ERC7984ERC20Wrapper

3 participants