Assessment reports>Yeet>Low findings>Zapper contract leaks excess token balance to OBRouter
Category: Coding Mistakes

Zapper contract leaks excess token balance to OBRouter

Low Severity
Low Impact
Low Likelihood

Description

The Zapper contract helps manage swaps on the Ooga Booga Router (OBRouter) and liquidity provisions on the Kodiak Vault. The contract makes trust assumptions about the inputAmount passed into the router; however, the router breaks those assumptions, causing loss of funds under very specific circumstances.

When a user executes zapIn() (as well as any other zap-in flow), lines 194–196 conduct a balance transfer as follows:

IERC20(inputToken).safeTransferFrom(
    _msgSender(), address(this), swapToToken0.inputAmount + swapToToken1.inputAmount
);

This infers that only balances transferred should be available to be swapped. However, the OBRouter (the contract can be found here), attempts to change the balance to the maximum held by the recipient.

 // Support rebasing tokens by allowing the user to trade the entire balance
if (tokenInfo.inputAmount == 0) {
    tokenInfo.inputAmount = IERC20(tokenInfo.inputToken).balanceOf(msg.sender);
}
IERC20(tokenInfo.inputToken).safeTransferFrom(msg.sender, executor, tokenInfo.inputAmount);

Impact

If Zapper holds any balance, a user is able to conduct a swap specifying tokenInfo.inputAmount == 0. This will not transfer any token from the user to Zapper; however, the trade will succeed, transferring the entire balance of Zapper for use in the OBRouter.

The Zapper contract is not designed to capture and retain token balances of any kind, and hence the likelihood of this vulnerability is low. The loss of funds is capped at the excess left through normal interaction with the Zapper and OBRouter contracts or direct transfers to Zapper.

Recommendations

If the requirement to transfer max balances of the Zapper contract is unintended, we recommend reverting on swapTokenInfo.inputAmount == 0.

Remediation

This issue has been acknowledged by Sanguine Labs LTD, and a fix was implemented in commit 7375a58c.

Zellic © 2025Back to top ↑