Skip to content

Latest commit

 

History

History
62 lines (44 loc) · 1.94 KB

File metadata and controls

62 lines (44 loc) · 1.94 KB

Fast Khaki Raccoon

High

PodUnwrapLocker can be drained due to an arbitrary input

Summary

PodUnwrapLocker can be drained due to an arbitrary input

Root Cause

PodUnwrapLocker provides a functionality to debond your pod tokens without paying a fee by locking them for a period of time. The issue is that the function allows an arbitrary pod input which allows for a complete drain of the contract:

function debondAndLock(address _pod, uint256 _amount) external nonReentrant {
       // NO CHECK FOR THE POD HERE
}

Internal Pre-conditions

No response

External Pre-conditions

No response

Attack Path

  1. A malicious contract is provided as the pod upon calling debondAndLock()
  2. In the line below, pod returns an array of 2 addresses which are both the same token, token X (token to be drained, deposited by other users who are using the contract functionality):
IDecentralizedIndex.IndexAssetInfo[] memory _podTokens = _podContract.getAllAssets();
  1. In the line below, we store the token X balances in both of the array fields, let's say 100 tokens:
for (uint256 i = 0; i < _tokens.length; i++) {
            _tokens[i] = _podTokens[i].token;
            _balancesBefore[i] = IERC20(_tokens[i]).balanceOf(address(this));
        }
  1. We then call debond() on our contract which transfers in 100 tokens of X
  2. In the line below, we fill the received amounts array with 100 tokens twice:
for (uint256 i = 0; i < _tokens.length; i++) {
            _receivedAmounts[i] = IERC20(_tokens[i]).balanceOf(address(this)) - _balancesBefore[i];
        }
  1. We return our own config with a 0 duration to immediately withdraw and store our received amounts in the locks mapping
  2. We go over our token X twice with 100 amount in both fields, receiving 200 tokens even though we put in 100

Impact

Theft of funds

PoC

No response

Mitigation

Do not allow arbitrary pods