Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Treasury cannot claim COMP tokens & COMP tokens are stuck #192

Open
code423n4 opened this issue Feb 2, 2022 · 2 comments
Open

Treasury cannot claim COMP tokens & COMP tokens are stuck #192

code423n4 opened this issue Feb 2, 2022 · 2 comments
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments)

Comments

@code423n4
Copy link
Contributor

Handle

cmichel

Vulnerability details

The TreasuryAction.claimCOMPAndTransfer function uses pre- and post-balances of the COMP token to check which ones to transfer:

function claimCOMPAndTransfer(address[] calldata cTokens)
    external
    override
    onlyManagerContract
    nonReentrant
    returns (uint256)
{
    // Take a snasphot of the COMP balance before we claim COMP so that we don't inadvertently transfer
    // something we shouldn't.
    uint256 balanceBefore = COMP.balanceOf(address(this));
    // @audit anyone can claim COMP on behalf of this contract and then it's stuck. https://github.com/compound-finance/compound-protocol/blob/master/contracts/Comptroller.sol#L1328
    COMPTROLLER.claimComp(address(this), cTokens);
    // NOTE: If Notional ever lists COMP as a collateral asset it will be cCOMP instead and it
    // will never hold COMP balances directly. In this case we can always transfer all the COMP
    // off of the contract.
    uint256 balanceAfter = COMP.balanceOf(address(this));
    uint256 amountClaimed = balanceAfter.sub(balanceBefore);
    // NOTE: the onlyManagerContract modifier prevents a transfer to address(0) here
    COMP.safeTransfer(treasuryManagerContract, amountClaimed);
    // NOTE: TreasuryManager contract will emit a COMPHarvested event
    return amountClaimed;
}

Note that anyone can claim COMP tokens on behalf of any address (see Comptroller.claimComp).
An attacker can claim COMP tokens on behalf of the contract and it'll never be able to claim any compound itself.
The COMP claimed by the attacker are stuck in the contract and cannot be retrieved.
(One can eventually get back the stuck COMP by creating a cCOMP market and then transferring it through transferReserveToTreasury.)

Recommended Mitigation Steps

Don't use pre-and post-balances, can you use the entire balance?

@code423n4 code423n4 added 3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working labels Feb 2, 2022
code423n4 added a commit that referenced this issue Feb 2, 2022
@jeffywu jeffywu added duplicate This issue or pull request already exists disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) labels Feb 6, 2022
@jeffywu
Copy link
Collaborator

jeffywu commented Feb 6, 2022

Duplicate of #192, dispute as a high risk bug. Would categorize this as medium risk.

There is no profit to be gained by doing this from the attacker besides denial of service. The protocol could simply upgrade to regain access to the tokens. We will fix this regardless.

@CloudEllie CloudEllie removed the duplicate This issue or pull request already exists label Feb 8, 2022
@pauliax
Copy link
Collaborator

pauliax commented Feb 16, 2022

Very good find.

It is a tough decision if this should be classified as High or Medium severity. An exploiter cannot acquire those assets, and the contracts are upgradeable if necessary, however, I think this time I will leave it in favor of wardens who both are experienced enough and submitted this as of high severity:
3 — High: Assets can be stolen/lost/compromised directly (or indirectly if there is a valid attack path that does not have hand-wavy hypotheticals).

jeffywu added a commit to notional-finance/contracts-v2 that referenced this issue Apr 4, 2022
* Hotfix: disable bitmap currency

* Bugfix: disallow changing bitmap currency

* Feature: Treasury Action

* Feature: switching to transfer / claim ownership

* Bugfix: settlement rates set prematurely

* Feature: adding patch fix router

* Hotfix: setting account context during liquidation calculations

* Deployment: adding treasury action to deployment

* Misc: removing github actions file

* Feature (SOLIDITY): allow nToken to redeem around residuals

* Feature (TESTS): allow nToken to redeem around residuals

* Deployment: deployed nToken redeem to Kovan

* Bugfix (SOLIDITY): incentives calculation fix and migration

* Bugfix (TESTS): incentives calculation fix and migration

* Refactor: modularizing nToken code

* Refactor: simplifying the nToken asset pv calculation

* Refactor: handling initialization edge case

* Testing: refactor migration code and add fix router

* Feature: adding a secondary incentive rewarder

* Feature (SOLIDITY): support Aave tokens

* Feature (TESTS): support Aave tokens

* add router fix message

* commenting out some views, code size

* refactoring treasury action code

* removing unused file

* moving address to a separate file

* fixing unit test

* Treasury cannot claim COMP tokens & COMP tokens are stuck [code-423n4/2022-01-notional-findings#192]

* Optimization on _redeemAndTransfer [code-423n4/2022-01-notional-findings#213]

* Gas: reserveInternal.subNoNeg(bufferInternal) can be unchecked [code-423n4/2022-01-notional-findings#199]

* Revert string > 32 bytes [code-423n4/2022-01-notional-findings#110]

* setReserveCashBalance can only set less reserves [code-423n4/2022-01-notional-findings#103]

* Gas: When a function uses the onlyManagerContract modifier, use msg.sender instead of treasuryManagerContract [code-423n4/2022-01-notional-findings#98]

* Prefix (++i), rather than postfix (i++), increment/decrement operators should be used in for-loops [code-423n4/2022-01-notional-findings#228]

* Gas: Missing checks for non-zero transfer value calls [code-423n4/2022-01-notional-findings#94]

* Working on token deployer

* Refactor compound deployer

* Adding notional deployer

* Adding mainnet addresses

* Adding governance deployer

* Adding liquidator deployer

* Implementing library checker

* Refactor token deployer

* Working on contract initialization

* Refactoring initializers

* Fixing lib deployment logic

* Implementing init parameters and various fixes

* Initialize markets and updated deployment json

* Adding liquidator addresses

* fixing tests

* Deploying governor and NOTE

* Re-deploying NOTE and upgraded router

* Adding deployment files

* Adding aave lending pool storage

* Moving calculation functions out of views

* Cleaning up

* Updating ABI

* Renaming contract

* renaming the calculation contract

* fixing deployment script

* fixing some tests (#29)

* fixing some tests

* fixes to aave tests

* bumping max market index

* combining two fixes into patch fix router

* updating a number of comments

* adding some comments in initi markets

* adding safety check in patch fix

* re-enabling view methods

* fixing potential edge case on claim time

* renaming incentives variable

* updating rewarder to include the nToken supply change

* adding an event for migration incentive

* updating abi

* adding events and exporting new abi

* moving events in treasury action

* removing WETH variable

* adding fork tests for incentives

* adding tests for trading calculations

* adding currency id to IRewarder

* Bugfix/init markets cash withholding (#32)

* adding fork tests for incentives

* adding tests for trading calculations

* adding currency id to IRewarder

* adding test for withholding amount

* fixing init markets cash withholding

* adding a get present value method for fCash

* adding additional checks in fcash liquidation

* updating ETH whale

* adding additional selector

* Fixing patchfix router (#33)

* Bugfix/last claim time revert (#34)

* adding additional checks in fcash liquidation

* updating ETH whale

* adding additional selector

* implemented a fix for last claim time issue

* updating test

* Bugfix/init markets at zero rate (#36)

* adding additional checks in fcash liquidation

* updating ETH whale

* adding additional selector

* fixing return value for zero rate

* Redeploy Kovan (#35)

* validated sources

* updating some config

* Deploying to mainnet (#96)

* Deploying to mainnet

* Updating mainnet addresses

* Adding v2.1 upgrade script

Co-authored-by: Tianjie Wei <[email protected]>
Co-authored-by: weitianjie2000 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3 (High Risk) Assets can be stolen/lost/compromised directly bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments)
Projects
None yet
Development

No branches or pull requests

4 participants