Centrifuge - Kow's results

The institutional ecosystem for on-chain credit.

General Information

Platform: Code4rena

Start Date: 08/09/2023

Pot Size: $70,000 USDC

Total HM: 8

Participants: 84

Period: 6 days

Judge: gzeon

Total Solo HM: 2

Id: 285

League: ETH

Centrifuge

Findings Distribution

Researcher Performance

Rank: 33/84

Findings: 1

Award: $172.71

🌟 Selected for report: 1

🚀 Solo Findings: 0

Findings Information

Awards

172.7134 USDC - $172.71

Labels

bug
2 (Med Risk)
high quality report
primary issue
satisfactory
selected for report
sponsor confirmed
edited-by-warden
M-04

External Links

Lines of code

https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/util/Factory.sol#L81-L109 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/token/ERC20.sol#L42-L49 https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/token/ERC20.sol#L225-L231

Vulnerability details

Impact

Attempts to interact with tranche tokens via permit may always revert.

Proof of Concept

When new tranche tokens are deployed, the initial DOMAIN_SEPARATOR is calculated and cached in the constructor. https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/token/ERC20.sol#L42-L49

    constructor(uint8 decimals_) {
        ...
        deploymentChainId = block.chainid;
        _DOMAIN_SEPARATOR = _calculateDomainSeparator(block.chainid);
    }

This uses an empty string since name is only set after deployment. https://github.com/code-423n4/2023-09-centrifuge/blob/512e7a71ebd9ae76384f837204216f26380c9f91/src/util/Factory.sol#L81-L109

    function newTrancheToken(
        uint64 poolId,
        bytes16 trancheId,
        string memory name,
        string memory symbol,
        uint8 decimals,
        address[] calldata trancheTokenWards,
        address[] calldata restrictionManagerWards
    ) public auth returns (address) {
        ...
        TrancheToken token = new TrancheToken{salt: salt}(decimals);

        token.file("name", name);
        ...
    }

Consequently, the domain separator is incorrect (when block.chainid == deploymentChainId where the domain separator is not recalculated) and will cause reverts when signatures for permit are attempted to be constructed using the tranche token's name (which will not be empty).

It should also be noted that the tranche token name could be changed by a call to updateTranchTokenMetadata which may also introduce complications with the domain separator.

Tools Used

Manual Review

Consider setting the name in the constructor before the cached domain separator is calculated.

Assessed type

Other

#0 - c4-pre-sort

2023-09-15T01:39:36Z

raymondfam marked the issue as primary issue

#1 - c4-pre-sort

2023-09-15T01:39:40Z

raymondfam marked the issue as sufficient quality report

#2 - c4-pre-sort

2023-09-17T06:27:20Z

raymondfam marked the issue as high quality report

#3 - c4-sponsor

2023-09-18T12:58:14Z

hieronx (sponsor) confirmed

#4 - c4-judge

2023-09-26T14:25:52Z

gzeon-c4 marked the issue as satisfactory

#5 - c4-judge

2023-09-26T14:25:57Z

gzeon-c4 marked the issue as selected for report

#6 - hieronx

2023-10-03T13:52:00Z

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter