Lucene search

K
code423n4Code4renaCODE423N4:2023-11-CANTO-FINDINGS-ISSUES-412
HistoryNov 17, 2023 - 12:00 a.m.

The Invariant can be broken as 1 NOTE does not always equal to 1 cNOTE.

2023-11-1700:00:00
Code4rena
github.com
3
minting process
invariant
protocol
loss
cnote
note
mint
burn
contract balance

AI Score

6.8

Confidence

Low

Lines of code
<https://github.com/code-423n4/2023-11-canto/blob/335930cd53cf9a137504a57f1215be52c6d67cb3/asD/src/asD.sol#L52&gt;

Vulnerability details

Impact

users will not be able to redeem their asD tokens for equivalent amount of NOTE because when minting cNOTE, 1 cNOTE doesnโ€™t always equal 1 NOTE.
image

Link to site here
as of when the image above was taken, you needed exactly 1.0042 NOTES to be able to get 1 cNOTE, and you can see in the mint() function,

    function mint(uint256 _amount) external {
        CErc20Interface cNoteToken = CErc20Interface(cNote);
        IERC20 note = IERC20(cNoteToken.underlying());
        SafeERC20.safeTransferFrom(note, msg.sender, address(this), _amount);
        SafeERC20.safeApprove(note, cNote, _amount);
        uint256 returnCode = cNoteToken.mint(_amount);
        // Mint returns 0 on success: https://docs.compound.finance/v2/ctokens/#mint
        require(returnCode == 0, "Error when minting");
        _mint(msg.sender, _amount);
    }

if a user deposits 1 NOTE, the contract gets 0.9958 cNOTE and mint to the user 1 asD, whenever the user wants to burn that 1 asD for an equivalent 1 NOTE, the call to cNoteToken.redeemUnderlying(_amount) in burn() will revert as the contractโ€™s balance of cNOTE will not be able to redeem 1 NOTE from the cNOTE contract.

The issue with this is that

  1. This breaks the invariant of the protocol.
    Click here

> Main invariants
asD: It should always be possible to redeem 1 asD for 1 NOTE.

  1. Some users can unknowingly take other users share of NOTE.

> check the Proof of Concept

Proof of Concept

  • User A and User B mint 1 asD each when NOTE != cNOTE where 1.0042 NOTE = 1 cNOTE.
  • The contract gets 1.99 cNOTEs.
  • User A burns his 1 asD to get back his 1 NOTE and the transaction is successful as the contractโ€™s balance of cNOTE is 1.99.
  • User B wants to burn his 1 asD for his 1 NOTE back but the transaction fails as 0nly 0.99 cNOTEs are in the contract.

Here you can see User A has unknowingly taken a share of User Bโ€™s N0TE causing loss to User B, NOTE This is a simplified Instance, where in huge amount a lot of issues can arise as many users are in the protocol.

Tools Used

Manual review

Recommended Mitigation Steps

my recommendation would be to require that the amount of cNOTE minted for the contract is equivalent to the amount of asD token to be minted to the user on the call to mint().

Assessed type

Other


The text was updated successfully, but these errors were encountered:

All reactions

AI Score

6.8

Confidence

Low