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

Removed BondNFT assets rewards will be lost #404

Closed
code423n4 opened this issue Dec 16, 2022 · 7 comments
Closed

Removed BondNFT assets rewards will be lost #404

code423n4 opened this issue Dec 16, 2022 · 7 comments
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) duplicate-73 satisfactory satisfies C4 submission criteria; eligible for awards sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Lines of code

https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/Lock.sol#L110-L120
https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/GovNFT.sol#L275-L280
https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/BondNFT.sol#L357-L360
https://github.com/code-423n4/2022-12-tigris/blob/588c84b7bb354d20cbca6034544c4faa46e6a80e/contracts/BondNFT.sol#L211-L215

Vulnerability details

Impact

BondNFT has its allowedAsset[] for allowed assets. But from Lock.sol#claimGovFees(), GovNFT will claim any asset rewards no matter it is allowed in BondNFT or not. So some asset not in BondNFT allowedAsset[] could possibly be collected from GovNFT claim(), in this case the corresponding rewards will be lost and locked in the contract.

Proof of Concept

Since the assets could change over time, the admin sometimes need to maintain the assets[] and allowedAsset[]. But for GovNFT, any asset can be claimed as rewards.

File: contracts/Lock.sol
110:     function claimGovFees() public {
111:         address[] memory assets = bondNFT.getAssets();
112: 
113:         for (uint i=0; i < assets.length; i++) {
114:             uint balanceBefore = IERC20(assets[i]).balanceOf(address(this));
115:             IGovNFT(govNFT).claim(assets[i]);
116:             uint balanceAfter = IERC20(assets[i]).balanceOf(address(this));
117:             IERC20(assets[i]).approve(address(bondNFT), type(uint256).max);
118:             bondNFT.distribute(assets[i], balanceAfter - balanceBefore);
119:         }
120:     }

File: contracts/GovNFT.sol
275:     function claim(address _tigAsset) external {
276:         address _msgsender = _msgSender();
277:         uint256 amount = pending(_msgsender, _tigAsset);
278:         userPaid[_msgsender][_tigAsset] += amount;
279:         IERC20(_tigAsset).transfer(_msgsender, amount);
280:     }

In BondNFT, some asset could be set as false. Then the BondNFT.sol#distribute() will silently return and do nothing.

File: contracts/BondNFT.sol
357:     function setAllowedAsset(address _asset, bool _bool) external onlyOwner {
358:         require(assets[assetsIndex[_asset]] == _asset, "Not added");
359:         allowedAsset[_asset] = _bool;
360:     }

211:     function distribute(
212:         address _tigAsset,
213:         uint _amount
214:     ) external {
215:         if (totalShares[_tigAsset] == 0 || !allowedAsset[_tigAsset]) return;

In this situation, although some asset might be claimed by GovNFT, and the balanceBefore and balanceAfter were changed, this part of rewards will be ignored in BondNFT.sol#distribute(). And be locked in the contract.

Tools Used

Manual analysis.

Recommended Mitigation Steps

  • In Lock.sol#claimGovFees(), Skip the disallowed assets.
File: contracts/Lock.sol
    function claimGovFees() public {
        address[] memory assets = bondNFT.getAssets();

        for (uint i=0; i < assets.length; i++) {
            if (bondNFT.allowedAsset(assets[i])) {
                uint balanceBefore = IERC20(assets[i]).balanceOf(address(this));
                IGovNFT(govNFT).claim(assets[i]);
                uint balanceAfter = IERC20(assets[i]).balanceOf(address(this));
                IERC20(assets[i]).approve(address(bondNFT), type(uint256).max);
                bondNFT.distribute(assets[i], balanceAfter - balanceBefore);
            }
        }
    }
  • In GovNFT, also enforce some allowedAssets list, to be synchronized with BondNFT.
  • Use some admin function to handle the disallowed assets in GovNFT.
@code423n4 code423n4 added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working labels Dec 16, 2022
code423n4 added a commit that referenced this issue Dec 16, 2022
@GalloDaSballo
Copy link

Looks off, if no reward is available we will receive zero
If the token is disallowed but some is still available as reward, we should claim it

Will double check

@TriHaz
Copy link

TriHaz commented Jan 5, 2023

Ideally, assets in BondNFT and GovNFT are synced.

@c4-sponsor
Copy link

TriHaz marked the issue as sponsor acknowledged

@c4-sponsor c4-sponsor added the sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons label Jan 5, 2023
@c4-sponsor
Copy link

TriHaz marked the issue as disagree with severity

@c4-sponsor c4-sponsor added the disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) label Jan 5, 2023
@c4-sponsor
Copy link

TriHaz marked the issue as sponsor confirmed

@c4-sponsor c4-sponsor added sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") and removed sponsor acknowledged Technically the issue is correct, but we're not going to resolve it for XYZ reasons labels Jan 5, 2023
@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as duplicate of #73

@c4-judge
Copy link
Contributor

GalloDaSballo marked the issue as satisfactory

@c4-judge c4-judge added the satisfactory satisfies C4 submission criteria; eligible for awards label Jan 22, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value bug Something isn't working disagree with severity Sponsor confirms validity, but disagrees with warden’s risk assessment (sponsor explain in comments) duplicate-73 satisfactory satisfies C4 submission criteria; eligible for awards sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

5 participants