Full Report
Pods Finance has a rewards system built into the protocol. If you decide to put issue options, then the contract will mint rewards for you. The vulnerability, which was present in both rewards system, allowed a malicious attack to claim rewards for other users. If a user had minted at least one option in the pat, they could repeatedly call unmintWithRewards() in order to claim the same share over and over again. By doing this, all of the funds from the contract could be stolen. The fix for this was calculating the reward based upon the options being unminted and NOT the shares that the user possesses. Even though this could steal all of the funds from the contract, it was rated as "high" instead of "critical" since just the theft of rewards was possible. Regardless, being able to drain the contract of all the money seems like a critical finding.
Analysis Summary
# Vulnerability: Pods Finance Rewards Calculation Logic Error
## CVE Details
- CVE ID: Not assigned in the provided context.
- CVSS Score: Not assigned in the provided context. Severity was internally rated as **High**.
- CWE: Logic Error (Likely related to miscalculation or improper state tracking)
## Affected Systems
- Products: Pods Finance rewards system, specifically in contracts `AavePodPut.sol` and `AavePodCall.sol`.
- Versions: The specific contract versions were not provided, but the vulnerability existed prior to the patch deployed on June 29, 2021.
- Configurations: Applicable to users who had minted at least one option and attempted to claim rewards via `unmintWithRewards()`.
## Vulnerability Description
The reward calculation logic in the Pods Finance options contracts (`AavePodPut.sol` and `AavePodCall.sol`) incorrectly calculated the amount of rewards to be sent upon calling `unmintWithRewards()`. The flawed logic based the reward distribution only on the user's accumulated `shares` without appropriately scaling it by the fraction of options being *unminted* in that specific transaction.
The vulnerable calculation was:
`uint256 rewardsToSend = shares[msg.sender].mul(_rewardBalance()).div(totalShares);`
An attacker who had previously minted options could repeatedly call `unmintWithRewards(amountOfOptions)` using a partial unmint (where the amount of options being unminted is less than 100% of their total shares). Because the calculation did not account for the partial withdrawal (the `amountOfOptions`), it incorrectly distributed the *full* potential share of rewards attributable to the user's total shares for every partial withdrawal, leading to an over-claim scenario until the contract rewards pool was drained.
While the bug could drain all reward funds, it **did not** allow the attacker to steal original user principal funds.
## Exploitation
- Status: Potential for exploitation, as the condition for the drain relates to repeating a specific function call (`unmintWithRewards()`). The summary notes the contract was **not deployed on mainnet** at the time of reporting, meaning no funds were at actual risk. Context implies the exploit involved repeated calls.
- Complexity: Medium (Requires knowledge of the specific function call sequence and contract logic).
- Attack Vector: Network (Interacting with the smart contract).
## Impact
- Confidentiality: No direct impact reported.
- Integrity: High Impact on the integrity of the rewards pool, allowing complete theft of accrued rewards.
- Availability: High. Complete draining of the rewards contract pool.
## Remediation
### Patches
The fix involved recalculating `rewardsToSend` to base the distribution not just on the user's shares, but proportionally on the options being unminted in that transaction relative to their total minted options:
**Patched Calculation:**
`uint256 rewardsToSend = (shares[msg.sender].mul(amountOfOptions).div(mintedOptions[msg.sender])).mul(_rewardBalance()).div(totalShares);`
The specific commit link provided in the article is: `https://github[.]com/pods-finance/contracts/commit/8549326c93e5542438ff75ed9f8075952a505f8e`
### Workarounds
No specific workarounds were detailed, as the contract was patched quickly. If the deployment had occurred, a temporary immediate solution would likely involve pausing reward accrual or function execution until a patch was applied, given the high severity of potential fund loss.
## Detection
- Indicators of Compromise: Excessive token transfers originating from the rewards contract to a single address utilizing the `unmintWithRewards()` function path, where the amount transferred significantly exceeds expected yield based on current holdings or transaction size.
- Detection methods and tools: Continuous monitoring of transaction traces through blockchain explorers or specialized DeFi monitoring tools focused on reward contract interactions and asset depletion rates. Internal audits focusing on reward calculation parity between withdrawal events and accrued rewards.
## References
- Vendor Advisories: Pods Finance Bug Bounty Program hosted on Immunefi.
- Relevant links:
- Report Summary: hxxps://medium[.]com/immunefi/pods-finance-logic-error-bugfix-review-959ae665e877
- Bug Bounty Program: hxxps://immunefi[.]com/bounty/pods