Hesty Disclosed Report

Users receives significantly fewer tokens than invested, leading to complete loss of funds

Company
Created date
Mar 12 2025

Target

https://github.com/la-bomba-studio/hesty-contract/tree/29596447b9a06d4ad53360d4a15f349ebf9fa0d8

Vulnerability Details

Description:
The incorrect calculation in the getInvestmentTokens function of TokenFactory contract will cause a severe loss for investors, as users receive significantly fewer tokens than they should.   The initialSupply of property tokens is minted in multiples of 10 ** 18 (18 decimals):

        // Property Token Supply Issuance
@>        _mint(address(tokenManagerContract_), initialSupply_ * 1 ether);

  But when users call getInvestmentTokens, their investment is not adjusted accordingly:

@>            SafeERC20.safeTransfer(IERC20(p.asset), user, rightForTokens[user][id]);

  As a result, users receive tokens equivalent to their invested amount without the necessary multiplication by 10 ** 18. This leads to users receiving a negligible amount of tokens, making it impossible to recover their investment.

Impact:

  • Affected party: All investors in the protocol.
  • Loss: Investors suffer a 100% loss of their funds, as they receive an insignificant amount of tokens.

Mitigation:
Update the calculation in the getInvestmentTokens function of the TokenFactory contract by multiplying the token amount by 10 ** 18 (the decimals of the property token) to ensure correct token distribution.

--            SafeERC20.safeTransfer(IERC20(p.asset), user, rightForTokens[user][id]);
++            SafeERC20.safeTransfer(IERC20(p.asset), user, rightForTokens[user][id] *  1 ether);

Validation steps

Exploit Scenario:

  1. A user invests in a property with the goal of purchasing 2 Property tokens using the buyTokens function of the TokenFactory contract.
  2. After the property raise period ends and the user has paid for 2 Property tokens, they attempt to claim their tokens via the getInvestmentTokens function.
  3. The protocol should issue 2 Property tokens with 18 decimals (2 * 10 ** 18), but instead, it only issues 2 wei (the smallest unit).
  4. As a result, the user holds an insignificant number of tokens, making it impossible to recover their investment.

Add this code in TokenFactory.test.js file:

  describe("Incorrect Amount of Tokens Received", function () {
    beforeEach(async function () {
      //Not yet initialized so therefore address(0)
      expect(await tokenFactory.referralSystemCtr()).to.equal("0x0000000000000000000000000000000000000000");

      await tokenFactory.initialize(referral.address, issuance.address)

      await hestyAccessControlCtr.connect(addr2).approveUserKYC(propertyManager.address);

      await tokenFactory.addWhitelistedToken(token.address);

      await tokenFactory.connect(propertyManager).createProperty(1000000, 1000, 4, 1, token.address, token.address, "token", "TKN", hestyAccessControlCtr.address)

      expect(await tokenFactory.propertyCounter()).to.equal(1);

      await tokenFactory.approveProperty(0, 2937487238472834);

      // Approve owner kyc to allow him to buy property token
      await hestyAccessControlCtr.connect(addr2).approveUserKYC(owner.address);

      await token.approve(tokenFactory.address, 9);

      await token.mint(owner.address, 8);

      // User attempts to buy 2 Property Tokens
      await tokenFactory.buyTokens(owner.address, 0, 2, addr3.address);
    })

    it("IncorrectTokens", async function () {
      await ethers.provider.send("evm_mine", [2937487238472844]);

      await tokenFactory.completeRaise(0);

      await tokenFactory.getInvestmentTokens(owner.address, 0);

      [PropertyToken, RevenueAddress] = await tokenFactory.getPropertyInfo(0);

      // User only get 2 tokens instead of 2 x 10 ** 18 tokens
      expect(await PropertyToken.balanceof(owner.address)).to.equal(2);

    });

  })

Attachments

hidden
CommentsReport History
Comments on this report are hidden
Details
Statedisclosed
Severity
Critical
Bounty$609
Visibilitypartially
VulnerabilityBlockchain
Participants (4)
company admin
author
company admin