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

No Validation of Pool Capacity in `createContingentPool`

Summary

In IAaveDIVAWrapper.sol contract, the function createContingentPool on line 133 accepts a capacity parameter but does not validate whether the provided capacity exceeds the total liquidity already added to the pool.

Vulnerability Details

  • A user could potentially create a pool with a capacity that exceeds available liquidity, leading to an over-leveraged pool.

Impact

  • This could cause liquidity issues and potentially a denial of service if users try to add liquidity beyond the actual capacity.

Proof of Concept (PoC) for the No Validation of Pool Capacity in createContingentPool vulnerability:

Overview

In this PoC, the createContingentPool function does not validate whether the given capacity exceeds the available liquidity or the current pool size. This can lead to the creation of over-leveraged pools, potentially causing liquidity issues and denial of service if users try to interact with an overfilled pool.

Actors

  • Attacker: The user who attempts to create a pool with an invalid or excessive capacity.

  • Victim: Users who try to add liquidity to the over-leveraged pool.

  • Protocol: The smart contract that facilitates the pool creation and liquidity management.

PoC Steps

  1. Create a Contract with the Vulnerability The contract in this example lacks validation when creating a new pool, allowing the pool's capacity to be arbitrarily large:

// Vulnerable Contract for Testing
pragma solidity ^0.8.0;
contract AaveDIVAWrapper {
struct Pool {
uint256 capacity;
uint256 liquidity;
}
mapping(address => Pool) public pools;
// Vulnerable createContingentPool function with no capacity validation
function createContingentPool(address poolAddress, uint256 capacity) public {
pools[poolAddress] = Pool(capacity, 0); // No check for existing liquidity
}
// Add liquidity function
function addLiquidity(address poolAddress, uint256 amount) public {
Pool storage pool = pools[poolAddress];
pool.liquidity += amount;
require(pool.liquidity <= pool.capacity, "Pool liquidity exceeds capacity");
}
}

** 2 Deploy Vulnerable Contract** Deploy this contract in a test environment like Hardhat to simulate the vulnerability.

** 3 Create Pool with Excessive Capacity** The attacker creates a pool with a capacity that exceeds the available liquidity or goes beyond the protocol’s intended limits.

// Test Script using Hardhat
const { ethers } = require("hardhat");
async function main() {
const [owner, user] = await ethers.getSigners();
const AaveDIVAWrapper = await ethers.getContractFactory("AaveDIVAWrapper");
const aaveDIVA = await AaveDIVAWrapper.deploy();
await aaveDIVA.deployed();
console.log("Contract deployed to:", aaveDIVA.address);
// Attacker creates a pool with excessive capacity
const poolAddress = ethers.utils.getAddress('0x1234...'); // Use any address
await aaveDIVA.createContingentPool(poolAddress, ethers.utils.parseEther("1000")); // Excessive capacity
// User tries to add liquidity to the pool
try {
await aaveDIVA.connect(user).addLiquidity(poolAddress, ethers.utils.parseEther("500"));
console.log("Liquidity added successfully.");
} catch (error) {
console.error("Error adding liquidity:", error.message); // Should fail
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

Step-by-Step Exploit Scenario

  1. Deploy the contract: The attacker deploys the vulnerable contract.

  2. Create a pool: The attacker calls createContingentPool with an excessive capacity, e.g., 1000 tokens, without any validation.

  3. Add liquidity: Another user (or the attacker) tries to add liquidity to the pool. The contract doesn't prevent the creation of a pool with excessive capacity, leading to an over-leveraged situation.

  4. Failure Scenario: When liquidity is added, the contract could potentially allow more liquidity than intended (if there’s no explicit check for capacity), causing issues when trying to manage the pool in future operations.

Outcome & Implications

  • The vulnerability could allow the attacker to create a pool that accepts more liquidity than it can handle, causing denial of service for legitimate users.

  • This issue could lead to liquidity mismanagement, as users might attempt to add liquidity beyond the pool’s limits.

  • If the pool is overfilled, the contract might run into issues when trying to distribute yield, perform collateral swaps, or execute other pool-related operations.

Recommendations & Fixes

  • Validation Check: Implement a check to ensure that the pool’s capacity does not exceed the actual available liquidity or other defined constraints.

  • Limit Pool Capacity: Add an upper bound on the capacity, which can be based on the current state of the liquidity or market conditions.

For example:

function createContingentPool(address poolAddress, uint256 capacity) public {
require(capacity <= MAX_POOL_CAPACITY, "Capacity exceeds the maximum limit");
pools[poolAddress] = Pool(capacity, 0);
}

Where MAX_POOL_CAPACITY could be a fixed value or dynamically adjusted depending on liquidity or other parameters.

This would mitigate the risk of creating over-leveraged or invalid pools and protect the contract from liquidity mismanagement.

Tools Used

  • Manual code review

Recommendations

  • Add a check to ensure the capacity does not exceed available liquidity.

  • You may want to track current pool liquidity and validate it before allowing new pools to be created.

Updates

Lead Judging Commences

bube Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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