HardhatDeFi
15,000 USDC
View results
Submission Details
Severity: low
Invalid

Rounding Issue Allows Creation of Contingent Pools with Blocked Funds

Summary

The AaveDIVAWrapper contract does not implement frontend rounding handling for small amounts, allowing users to create Contingent Pools with minimal amounts that will become blocked during redemption due to rounding limitations.

Vulnerability Details

The DIVA protocol has a known rounding issue that is expected to be handled on the frontend. While the AaveDIVAWrapper contract acts as a frontend in an architectural sense, it does not implement this handling for small amounts.

it("Should revert when redemption amount is too small", async () => {
// ---------
// Act 1: Register collateral token.
// ---------
await s.aaveDIVAWrapper
.connect(s.owner)
.registerCollateralToken(collateralToken);
const longRecipient = s.impersonatedSigner
const shortRecipient = s.impersonatedSigner
// ---------
// Act 2: Create contingent pool with small collatreal amount
// ---------
await s.aaveDIVAWrapper
.connect(s.impersonatedSigner)
.createContingentPool({
...s.createContingentPoolParams,
collateralAmount: 1,
shortRecipient: shortRecipient.address
});
// Get poolId and pool parameters
const poolId = await getPoolIdFromAaveDIVAWrapperEvent(s.aaveDIVAWrapper);
const poolParams = await s.diva.getPoolParameters(poolId);
// ---------
// Act 3: Fast forward time and confirm pool to allow redemption
// ---------
const nextBlockTimestamp = Number(poolParams.expiryTime) + 1;
await mine(nextBlockTimestamp);
await s.diva
.connect(s.dataProvider)
.setFinalReferenceValue(poolId, parseUnits("10"), false);
// ---------
// Act 4: Redeem position tokens
// ---------
const longTokenContract = await ethers.getContractAt(
"IERC20",
poolParams.longToken
);
const shortTokenContract = await ethers.getContractAt(
"IERC20",
poolParams.shortToken
);
const longTokenBalance = await longTokenContract.balanceOf(
longRecipient.address
);
const shortTokenBalance = await shortTokenContract.balanceOf(
shortRecipient.address
);
// expect(nextPoolParams.payoutShort).eq(0)
// expect(shortTokenBalance).eq(0)
const longRecipientBalanceBeforeRedeem =
await s.collateralTokenContract.balanceOf(
longRecipient.address
);
await longTokenContract
.connect(longRecipient)
.approve(s.aaveDIVAWrapper.target, longTokenBalance);
await expect(s.aaveDIVAWrapper
.connect(longRecipient)
.redeemPositionToken(
poolParams.longToken,
longTokenBalance,
longRecipient.address
)).to.be.revertedWith("26");
});

The key issue is in the createContingentPool and addLiquidity functions which do not validate minimum amounts that would avoid rounding issues

Impact

  • Poor user experience and potential loss of funds

  • Architectural inconsistency as the wrapper does not fully implement expected frontend validations

Tools Used

  • Manual code review

  • Performing formal verification with Quint

Recommendations

Implement minimum amount validation in the AaveDIVAWrapper

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Appeal created

0x180db Submitter
9 months ago
bube Lead Judge
9 months ago
bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.