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

No way to return and withdraw excess amount in EntityForging::forgeWithListed, Locking of funds. #498

Closed
howlbot-integration bot opened this issue Aug 9, 2024 · 6 comments
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-218 grade-c QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_54_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards

Comments

@howlbot-integration
Copy link

Lines of code

https://github.com/code-423n4/2024-07-traitforge/blob/279b2887e3d38bc219a05d332cbcb0655b2dc644/contracts/EntityForging/EntityForging.sol#L126

Vulnerability details

Impact

In EntityForging::forgeWithListed function a msg.sender can send money to forge with forgerId to generate a newTokenId to forge with any forgerId msg.sender have to pay some forgingFee amount. forgeWithListed also have a check that require(msg.value >= forgingFee, 'Insufficient fee for forging'); and except forgingFee the excess amount should return to msg.sender but missing this returning of msg.value-forgingFee to msg.sender cause locking of funds in EntityForging. No one can withdraw money from this contract anyway.

Proof of Concept

  1. In forgeWithListed function msg.sender sent money.
  2. checks for required forgingFee
  3. And if msg.value-forgingFee > 0 then, there is no code to return excess money to msg.sender and not also any withdraw function to take money out of this contract.

See code below EntityForging::forgeWithListed :

code
function forgeWithListed(
    uint256 forgerTokenId,
    uint256 mergerTokenId
  ) external payable whenNotPaused nonReentrant returns (uint256) {
    Listing memory _forgerListingInfo = listings[listedTokenIds[forgerTokenId]];
    require(
      _forgerListingInfo.isListed,
      "Forger's entity not listed for forging"
    );
    require(
      nftContract.ownerOf(mergerTokenId) == msg.sender,
      'Caller must own the merger token'
    );
    require(
      nftContract.ownerOf(forgerTokenId) != msg.sender,
      'Caller should be different from forger token owner'
    );
    require(
      nftContract.getTokenGeneration(mergerTokenId) ==
        nftContract.getTokenGeneration(forgerTokenId),
      'Invalid token generation'
    );

    uint256 forgingFee = _forgerListingInfo.fee;

    require(msg.value >= forgingFee, 'Insufficient fee for forging');
    _resetForgingCountIfNeeded(forgerTokenId); // Reset for forger if needed
    _resetForgingCountIfNeeded(mergerTokenId); // Reset for merger if needed

    // Check forger's breed count increment but do not check forge potential here
    // as it is already checked in listForForging for the forger

    forgingCounts[forgerTokenId]++;

    // Check and update for merger token's forge potential
    uint256 mergerEntropy = nftContract.getTokenEntropy(mergerTokenId);
    require(mergerEntropy % 3 != 0, 'Not merger');
    uint8 mergerForgePotential = uint8((mergerEntropy / 10) % 10); // Extract the 5th digit from the entropy

    forgingCounts[mergerTokenId]++;
    require(
      mergerForgePotential > 0 &&
        forgingCounts[mergerTokenId] <= mergerForgePotential,
      'forgePotential insufficient'
    );

    // according to docs devfee should only be 10% of the forgeFee Than why instead of takikng 10% we take taxCut as a state Variable and can be changed later??
    uint256 devFee = forgingFee / taxCut;
    uint256 forgerShare = forgingFee - devFee;
    address payable forgerOwner = payable(nftContract.ownerOf(forgerTokenId));

    uint256 newTokenId = nftContract.forge(
      msg.sender,
      forgerTokenId,
      mergerTokenId,
      ''
    );
    (bool success, ) = nukeFundAddress.call{ value: devFee }('');
    require(success, 'Failed to send to NukeFund');
    (bool success_forge, ) = forgerOwner.call{ value: forgerShare }('');
    require(success_forge, 'Failed to send to Forge Owner');

    // Cancel listed forger nft

    _cancelListingForForging(forgerTokenId);

    uint256 newEntropy = nftContract.getTokenEntropy(newTokenId);

    emit EntityForged(
      newTokenId,
      forgerTokenId,
      mergerTokenId,
      newEntropy,
      forgingFee
    );

    return newTokenId;
  }

Tools Used

Manual review

Recommended Mitigation Steps

Add the changes in the following code:

+   uint256 excessAmount = msg.value - forgingFee;
+   if(excessAmount > 0){
+      (bool success_return, ) = payable(msg.sender).call{ value: forgerShare }('');
+      require(success_return, 'Failed to send to msg.sender');
+   }

Assessed type

ETH-Transfer

@howlbot-integration howlbot-integration bot added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value 🤖_54_group AI based duplicate group recommendation bug Something isn't working duplicate-218 sufficient quality report This report is of sufficient quality labels Aug 9, 2024
howlbot-integration bot added a commit that referenced this issue Aug 9, 2024
@c4-judge
Copy link
Contributor

koolexcrypto changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax grade-c unsatisfactory does not satisfy C4 submission criteria; not eligible for awards and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Aug 18, 2024
@c4-judge
Copy link
Contributor

koolexcrypto marked the issue as grade-c

@c4-judge c4-judge reopened this Aug 31, 2024
@c4-judge
Copy link
Contributor

This previously downgraded issue has been upgraded by koolexcrypto

@c4-judge c4-judge added 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value and removed downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax labels Aug 31, 2024
@c4-judge
Copy link
Contributor

koolexcrypto marked the issue as duplicate of #687

@c4-judge
Copy link
Contributor

c4-judge commented Sep 5, 2024

koolexcrypto marked the issue as duplicate of #218

@c4-judge
Copy link
Contributor

c4-judge commented Sep 6, 2024

koolexcrypto changed the severity to QA (Quality Assurance)

@c4-judge c4-judge added downgraded by judge Judge downgraded the risk level of this issue QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax and removed 2 (Med Risk) Assets not at direct risk, but function/availability of the protocol could be impacted or leak value labels Sep 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working downgraded by judge Judge downgraded the risk level of this issue duplicate-218 grade-c QA (Quality Assurance) Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax 🤖_54_group AI based duplicate group recommendation sufficient quality report This report is of sufficient quality unsatisfactory does not satisfy C4 submission criteria; not eligible for awards
Projects
None yet
Development

No branches or pull requests

1 participant