Frankencoin - santipu_'s results

A decentralized and fully collateralized stablecoin.

General Information

Platform: Code4rena

Start Date: 12/04/2023

Pot Size: $60,500 USDC

Total HM: 21

Participants: 199

Period: 7 days

Judge: hansfriese

Total Solo HM: 5

Id: 231

League: ETH

Frankencoin

Findings Distribution

Researcher Performance

Rank: 45/199

Findings: 3

Award: $149.54

QA:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: cccz

Also found by: DishWasher, KIntern_NA, SolidityATL, ToonVH, giovannidisiena, joestakey, santipu_

Labels

bug
2 (Med Risk)
satisfactory
duplicate-396

Awards

93.1122 USDC - $93.11

External Links

Lines of code

https://github.com/Frankencoin-ZCHF/FrankenCoin/blob/main/contracts/Equity.sol#L262-L264

Vulnerability details

Impact

In the Equity contract, the calculateShares function returns a wrong value when equity is less than investment.

calculateShares is a view function that returns the number of shares that will be minted corresponding an investment of ZCHF tokens. This function calls directly calculateSharesInternal that calculates the shares to be minted.

The function that actually makes the mint of shares happen is onTokenTransfer. In this function there is a check to ensure that if equity <= amount the shares minted will always be 1000e18. This check is to assign 1000e18 shares minted to the first depositor.

The problem is that the calculateShares function doesn't account for this so will return a different amount of shares when the equity is less than investment. This can happen before the first deposit or in a situation of low liquidity when the equity is low.

Proof of Concept

Tools Used

Manual review

Check in calculateShares the same condition as in onTokenTransfer. Example:

function calculateShares(uint256 investment) public view returns (uint256) {
    uint256 equity = zchf.equity();
    return equity <= investment ? 1000 * ONE_DEC18 : calculateSharesInternal(equity, investment);
}

#0 - c4-pre-sort

2023-04-24T09:38:11Z

0xA5DF marked the issue as primary issue

#1 - 0xA5DF

2023-04-24T09:39:16Z

This can happen before the first deposit or in a situation of low liquidity when the equity is low.

For first depositor this isn't an issue since next deposits are relative to the first one. Situations where there's low liquidity might be a valid issue, will need sponsor's input on this

#2 - c4-pre-sort

2023-04-24T09:43:22Z

0xA5DF marked the issue as duplicate of #983

#3 - c4-judge

2023-05-18T04:59:56Z

hansfriese marked the issue as duplicate of #396

#4 - c4-judge

2023-05-18T05:21:49Z

hansfriese marked the issue as duplicate of #396

#5 - c4-judge

2023-05-18T13:35:27Z

hansfriese marked the issue as satisfactory

Findings Information

🌟 Selected for report: Ruhum

Also found by: 7siech, DadeKuma, J4de, Lirios, deliriusz, foxb868, hihen, juancito, ladboy233, rbserver, santipu_, zaevlad

Labels

bug
2 (Med Risk)
satisfactory
duplicate-230

Awards

33.835 USDC - $33.83

External Links

Lines of code

https://github.com/Frankencoin-ZCHF/FrankenCoin/blob/main/contracts/Frankencoin.sol#L146-L151

Vulnerability details

Impact

In the Frankencoin system a minter that hasn't been denied during the application period can't be revoked in case of a private keys leak or a malicious minter.

Currently, when a minter is suggested and not denied during the application period, it will be able to mint tokens and transfer tokens of users as it please so it has to be a trusted party. The problem is that in case the private keys of a minter are leaked or this minter turns out to be malicious, it has the power to mint mint infinite tokens or burn them. The FPS holders should have a mechanism to revoke the privileges of a minter if any of these happens.

Proof of Concept

https://github.com/Frankencoin-ZCHF/FrankenCoin/blob/main/contracts/Frankencoin.sol#L146-L151

Tools Used

Manual Review

Implement a mechanism to revoke the privileges of a minter in case something unexpected happens in order to prevent the destruction of the Frankencoin ecosystem.

#0 - c4-pre-sort

2023-04-21T14:20:44Z

0xA5DF marked the issue as duplicate of #230

#1 - c4-judge

2023-05-18T13:40:26Z

hansfriese marked the issue as satisfactory

Wrong comments at Ownable contract

https://github.com/Frankencoin-ZCHF/FrankenCoin/blob/main/contracts/Ownable.sol#L16-L17

In the Ownable contract, that is a modified copy from the Openzeppelin Ownable contract, the comments state that the owner will be by default the contract deployer. This statement is false because in the contract there's no constructor so the contract that inherit form this one must set the owner manually.

This issue has no real impact because the Position contract sets the owner in the constructor but this comment can lead to misunderstanding with other devs or with future versions of Frankencoin leading to a contract without owner.

checkQualified won't revert when there are no shares minted or if it's called in the same block as the first shares are minted

https://github.com/Frankencoin-ZCHF/FrankenCoin/blob/main/contracts/Equity.sol#L209-L212

In the Equity contract, the checkQualified function should revert when the sender doesn't hold at least the 3% of the votes. This doesn't happen when there're not shares minted of when the function is called in the same block as the transaction that minted the first shares.

This is because the function calls totalVotes, and this function makes the following calculation: totalVotesAtAnchor + totalSupply() * (anchorTime() - totalVotesAnchorTime) So, when there are no shares minted, totalVotesAtAnchor and totalSupply will be zero making the function to not revert as it should. Also, in the same block as the first deposit, totalVotesAtAnchor will still be zero and anchorTime() - totalVotesAnchorTime will also result in zero making the function to not revert as it should.

#0 - 0xA5DF

2023-04-27T09:55:19Z

#2 is dupe of #952

#1 - c4-judge

2023-05-16T16:38:16Z

hansfriese marked the issue as grade-b

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