Q2 2026 Security & Compliance Report67 incidents, $764M in losses, 88% from operational failures.
Get the report →

Audit name:

[SCA] Tangible – USDR | USDR Redemption V2 | Sep2026

Date:

Sep 9, 2026

Table of Content

→Introduction
→Audit Summary
→System Overview
→Potential Risks
→Findings
→Appendix 1. Definitions
→Appendix 2. Scope
→Appendix 3. Additional Valuables
→Disclaimer

Want a comprehensive audit report like this?

Introduction

We express our gratitude to the Tangible – USDR team for the collaborative engagement that enabled the execution of this Smart Contract Security Assessment.

USDR Redemption v2 is a pro-rata redemption contract. Holders present USDR, which is burned, and receive a share of the USDC that has been funded, independent of redemption order. The audit covered the USDRRedemption implementation.

Document

NameSmart Contract Code Review and Security Analysis Report for Tangible – USDR
Audited ByKerem Solmaz
Approved ByOlesia Bilenka
Websitehttps://www.tangible.store/→
Changelog08/09/2026 - Preliminary Report
09/09/2026 - Final Report
PlatformPolygon
LanguageSolidity
TagsFungible Token, Decentralized Finance (DeFi), Centralization
Methodologyhttps://docs.hacken.io/methodologies/smart-contracts→

Review Scope

Repositoryhttps://github.com/TangibleTNFT/usdr-redemption-v2→
Initial Commite6f27d4
Final Commit62d30b0

Audit Summary

3Total Findings
3Resolved
0Accepted
0Mitigated

The system users should acknowledge all the risks summed up in the risks section of the report

Documentation quality

  • The repository includes a detailed README that states the pro-rata model, unit conventions, deploy parameters, and wind-down rules.

  • Public functions on USDRRedemption and IUSDRRedemption carry extensive NatSpec.

  • Documentation and implementation agree on share registration at redeem time, funding-based payouts, the 180-day post-full-funding sweep, the one-dollar rate ceiling, and that the sweep countdown arms only when remaining funding reaches zero, including the configured-supply slice that cannot be presented on Polygon.

  • Some operational assumptions, including that the owner is a Gnosis Safe, are documented rather than enforced on-chain.

Code quality

  • The implementation is a single non-upgradeable Solidity 0.8.30 contract that uses OpenZeppelin Contracts v5.6.1 for two-step ownership, transient reentrancy protection, SafeERC20 transfers, and mulDiv arithmetic.

Test coverage

  • Line, statement, branch, and function coverage on USDRRedemption stands at 100% as measured by the Foundry coverage tool on the unit, fuzz, and invariant suites. The suite covers primary redemption, funding, rate, sweep, and rescue flows, plus fuzzed rounding properties for path, tranche, and order independence, and an invariant suite for solvency and the pro-rata ledger. Negative cases cover a rate above the on-chain ceiling, including a mistyped rate, and a USDC recipient equal to the redemption contract. The invariant suite asserts the rate ceiling. Polygon fork tests against the live USDR token exist but require an archive RPC and are excluded from continuous integration. Continuous integration runs format, build, and non-fork tests.

System Overview

USDRRedemption is an immutable Polygon contract that converts USDR (ERC-20, 9 decimals) into native USDC (ERC-20, 6 decimals) on a pro-rata basis. The design replaces a first-come-first-served swap with a share ledger so that the order of redemptions does not change a holder's claim on funded USDC. The system consists of USDRRedemption, the IUSDRRedemption public interface, and the IUSDR burn surface used to destroy presented USDR. The USDR and USDC addresses and the redeemable population totalUSDRSupply are constructor immutables. That population is not read from the token total supply. The constructor requires USDR to report 9 decimals and USDC to report 6 decimals. The target rate is stored as USDC raw units per one whole USDR. It may only increase and cannot exceed 1,000,000 raw units, which is 1.00 USDC per whole USDR.

USDC enters the pro-rata ledger only when the owner funds the contract or recognizes an unaccounted balance already held. Funding cannot exceed the ceiling of supply times rate, rounded up, divided by 1e9. A holder who calls redeem burns USDR from themselves through IUSDR, registers matching shares, and is paid the current floor of shares times funded USDC divided by the immutable supply. Later funding is collected with claim. The rate does not appear in the payout formula. A packed position stores shares and USDC already paid. Raw USDC transfers are not funding unless the owner recognizes them. Redeem and claim reject the redemption contract itself as the USDC recipient.

When funded USDC reaches the ceiling, a timestamp is stored. After 180 days the owner may sweep the entire USDC balance, which permanently closes the contract. Holders who never presented USDR, and holders who presented it but never claimed the remainder, forfeit what is left. Full funding includes the configured-supply slice that may never be presented. That slice sits idle until the terminal sweep. If remaining funding never reaches zero, sweep stays locked. A rate increase clears the sweep clock unless the new ceiling is already met. While closed, redeem, claim, fund, and rate changes revert, and entitlement views return zero. Sweep remains callable so USDC received after closure can still be recovered. Stray non-USDC tokens can be rescued. USDC cannot.

Privileged Roles

  • Owner (USDRRedemption, inherited from OpenZeppelin Ownable2Step): Funds USDC, recognizes unaccounted USDC, raises the rate up to the on-chain ceiling, sweeps after the delay, rescues non-USDC tokens, and starts a two-step ownership transfer. The constructor accepts any non-zero address. Production comments expect a Gnosis Safe, but the contract does not enforce one. Compromise or misuse of this role allows an immediate rate increase that can clear the sweep clock, funding recognition, token rescue, and a sweep of remaining USDC once the delay has elapsed. Loss of the key before handover can freeze further funding and keep sweep locked if full funding is never reached. Ownership renounce is disabled.

  • Pending owner (USDRRedemption, inherited from OpenZeppelin Ownable2Step): Completes ownership handover through acceptOwnership(). Until that call succeeds, the current owner retains every privileged path.

  • Redeem and claim, including the overloads that choose a USDC receiver, may be called by any account.

Potential Risks

Scope Definition and Security Guarantees: The audit covers USDRRedemption, IUSDRRedemption, and IUSDR. Tests, mocks, the Polygon deploy script, and the live USDR and native USDC token implementations are outside the review. Flaws in those out-of-scope components may still affect the audited contract because redemption, funding, and payouts call those tokens.

Dependency on External Logic for Implemented Logic: Redemption burns the caller's USDR through the custom allowance-based burn on the out-of-scope USDR token. USDRRedemption never holds USDR and is not granted a burner role. If that burn reverts, spends allowance differently than IUSDR describes, or is blocked while the token is paused, new shares cannot be registered. Already registered positions can still be settled because claim does not call USDR.

System Reliance on External Contracts: Redeem, claim, fund, sweep, stray-token recovery, and available-balance reads depend on the immutable USDR and USDC addresses set in USDRRedemption. Both tokens are upgradeable proxies. A proxy upgrade, a pause, or a change in transfer or burn behaviour can block burns or USDC movement while registered positions remain unpaid. The pro-rata denominator is an off-chain accessible-supply figure supplied at construction and is not read from the USDR token total supply. If that figure is below the USDR that can actually be presented, later holders cannot register shares. If it is above the presentable population, unused capacity leaves funded USDC unclaimable until a terminal sweep, or indefinitely if full funding never occurs.

Dependency on Unaudited External Libraries: The project depends on OpenZeppelin Contracts v5.6.1 for two-step ownership, transient reentrancy protection, SafeERC20 transfers, and mulDiv arithmetic. While OpenZeppelin is widely used and has undergone prior audits, the specific version integrated has not been independently verified as part of this engagement. Any defect in those base contracts would affect USDRRedemption.

Owner's Unrestricted State Modification: The owner may raise the rate on USDRRedemption at any time while the contract is open. The rate must be strictly greater than the current value and must not exceed 1,000,000 raw USDC units per whole USDR. A raise increases the funding target and clears the sweep clock unless the new ceiling is already met. There is no on-chain path to lower the rate. A raise to the ceiling after a full fund at the deploy rate leaves a remaining top-up on the same scale as the original funding target. Residual USDC still cannot leave through the stray-token recovery path. Existing positions remain entitled to a share of already recognized funding.

Coarse-grained Authorization Model Risks: A single owner on USDRRedemption controls funding, rate increases, the terminal sweep, recovery of tokens other than USDC, and two-step ownership transfer. No separate roles isolate those powers. Compromise of that one address grants every privileged path at once.

Absence of Time-lock Mechanisms for Critical Operations: Funding, rate increases, and non-USDC rescues on USDRRedemption execute in the calling transaction. The only delayed owner action is the terminal sweep, which waits 180 days after recognized funding equals the supply-times-rate ceiling.

Insufficient Multi-signature Controls for Critical Functions: Ownership is a single address assigned in the USDRRedemption constructor. Production comments expect a Gnosis Safe, but the contract does not require one. Rate changes, funding, sweep, and stray-token recovery do not require a second on-chain signature.

Single Points of Failure and Control: Funding progress, the rate, terminal closure, and stray-token recovery all require the current owner of USDRRedemption. Ownership cannot be renounced. If the key is lost before a two-step handover completes, further funding and rate increases stop, and the sweep may stay locked if full funding is never reached.

Administrative Key Control Risks: After the sweep delay the owner of USDRRedemption sends the entire USDC balance to a chosen recipient and permanently closes the contract. Holders who never presented USDR, and holders who presented it but never claimed the remainder, forfeit what is left. Non-USDC tokens can be redirected immediately. Payouts follow the funded ledger, not the raw USDC balance, so holders who burn USDR before funding arrives receive a zero or partial payout and must wait on later claims. Unrecognized raw USDC transfers are not owed to anyone.

Findings

Code
―
Title
Status
Severity
F-2026-1926Uncapped Rate Increase Clears The Sweep Clock And Risks Locking Residual USDC
fixed

Low
F-2026-1926Missing Self-Address Check In Redeem And Claim
fixed

Observation
F-2026-1926Funding Target Uses Configured Supply And Leaves Surplus Idle Until Sweep
fixed

Observation
1-3 of 3 findings

Identify vulnerabilities in your smart contracts.

Appendix 1. Definitions

Severities

When auditing smart contracts, Hacken is using a risk-based approach that considers Likelihood, Impact, Exploitability and Complexity metrics to evaluate findings and score severities.

Reference on how risk scoring is done is available through the repository in our Github organization:

Severity

Description

Critical
Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

High
High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

Medium
Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

Low
Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.
  • Severity

    Critical

    Description

    Critical vulnerabilities are usually straightforward to exploit and can lead to the loss of user funds or contract state manipulation.

    Severity

    High

    Description

    High vulnerabilities are usually harder to exploit, requiring specific conditions, or have a more limited scope, but can still lead to the loss of user funds or contract state manipulation.

    Severity

    Medium

    Description

    Medium vulnerabilities are usually limited to state manipulations and, in most cases, cannot lead to asset loss. Contradictions and requirements violations. Major deviations from best practices are also in this category.

    Severity

    Low

    Description

    Major deviations from best practices or major Gas inefficiency. These issues will not have a significant impact on code execution.

Potential Risks

The "Potential Risks" section identifies issues that are not direct security vulnerabilities but could still affect the project’s performance, reliability, or user trust. These risks arise from design choices, architectural decisions, or operational practices that, while not immediately exploitable, may lead to problems under certain conditions. Additionally, potential risks can impact the quality of the audit itself, as they may involve external factors or components beyond the scope of the audit, leading to incomplete assessments or oversight of key areas. This section aims to provide a broader perspective on factors that could affect the project's long-term security, functionality, and the comprehensiveness of the audit findings.

Appendix 2. Scope

The scope of the project includes the following smart contracts from the provided repository:

Scope Details

Repositoryhttps://github.com/TangibleTNFT/usdr-redemption-v2→
Initial Commite6f27d4fe2fae3ee2325a8f966f31eeccea70ca2
Final Commit62d30b0fa52793947171fecee1a7f0a48a3f0214
Whitepaper-
RequirementsREADME.md
Technical RequirementsREADME.md

Assets in Scope

src
USDRRedemption.sol - src › USDRRedemption.sol

Appendix 3. Additional Valuables

Additional Recommendations

The smart contracts in the scope of this audit could benefit from the introduction of automatic emergency actions for critical activities, such as unauthorized operations like ownership changes or proxy upgrades, as well as unexpected fund manipulations, including large withdrawals or minting events. Adding such mechanisms would enable the protocol to react automatically to unusual activity, ensuring that the contract remains secure and functions as intended.

To improve functionality, these emergency actions could be designed to trigger under specific conditions, such as:

  • Detecting changes to ownership or critical permissions.

  • Monitoring large or unexpected transactions and minting events.

  • Pausing operations when irregularities are identified.

These enhancements would provide an added layer of security, making the contract more robust and better equipped to handle unexpected situations while maintaining smooth operations.

Frameworks and Methodologies

This security assessment was conducted in alignment with recognised penetration testing standards, methodologies and guidelines, including the NIST SP 800-115 – Technical Guide to Information Security Testing and Assessment →, and the Penetration Testing Execution Standard (PTES) →, These assets provide a structured foundation for planning, executing, and documenting technical evaluations such as vulnerability assessments, exploitation activities, and security code reviews. Hacken’s internal penetration testing methodology extends these principles to Web2 and Web3 environments to ensure consistency, repeatability, and verifiable outcomes.

Disclaimer