-
Notifications
You must be signed in to change notification settings - Fork 30
Open
Description
Description
Aqua updates internal balances by the requested amount and then performs the ERC20 transfer without verifying the actual amount moved. For fee-on-transfer (taxed) or rebasing tokens, the internal Aqua accounting diverges from real wallet balances, and XYCSwap’s settlement check relies on Aqua’s internal view, not on actual token receipts.
function pull(address maker, bytes32 strategyHash, address token, uint256 amount, address to) external {
Balance storage balance = _balances[maker][msg.sender][strategyHash][token];
(uint248 prevBalance, uint8 tokensCount) = balance.load();
balance.store(prevBalance - amount.toUint248(), tokensCount);
IERC20(token).safeTransferFrom(maker, to, amount);
emit Pulled(maker, msg.sender, strategyHash, token, amount);
}
function push(address maker, address app, bytes32 strategyHash, address token, uint256 amount) external {
Balance storage balance = _balances[maker][app][strategyHash][token];
(uint248 prevBalance, uint8 tokensCount) = balance.load();
require(tokensCount > 0 && tokensCount != _DOCKED, PushToNonActiveStrategyPrevented(maker, app, strategyHash, token));
balance.store(prevBalance + amount.toUint248(), tokensCount);
IERC20(token).safeTransferFrom(msg.sender, maker, amount);
emit Pushed(maker, app, strategyHash, token, amount);
}Problematic dependency (XYCSwap):
_safeCheckAquaPush(strategy.maker, strategyHash, tokenIn, balanceIn + amountIn);Impact
- On push(), internal balance increases by amount even if the maker actually receives less due to transfer tax/rebase. _safeCheckAquaPush then considers the swap settled while the maker’s wallet is underfunded.
- On pull(), internal balance decreases by amount regardless of how much is actually delivered to the recipient in
deflationary transfers. This can systematically short-change the maker or the taker and create future pull failures
or stuck strategies. Because neither Aqua nor XYCSwap measure token balances pre/post transfer, the system can be exploited or
broken when non-standard ERC20s (fee-on-transfer, rebasing) are used.
Severity
- _safeCheckAquaPush compares Aqua’s internal balance to an expected value and does not read real token balances or measure pre/post transfer deltas.
- Tokens with fee-on-transfer or rebasing behavior can be used within Aqua/XYCSwap (no allowlist restrictions).
Metadata
Metadata
Assignees
Labels
No labels