

Archon public report
AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_
Mantle Mainnet · scan depth quick · generated 6/18/2026, 6:09:17 PM
Risk Score
100
Archon completed a read-only Mantle Mainnet audit of AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_ and found 21 deterministic findings. The highest-priority issue is Arbitrary Send Eth, with risk score 100/100 based on severity-weighted findings. The repayETH function sends excess ETH back to msg.sender using transfer, but if msg.sender is a contract that does not implement a payable fallback or has a high gas requirement, the transfer can fail, locking funds. Additionally, using transfer instead of a low-level call like call{value} limits forward gas to 2300, which may not be sufficient for complex receivers and can cause permanent loss of refunds. Review the recommended fixes and run regression tests before deployment.
Models used: Tencent Cloud TokenHub (deepseek-v4-pro), OpenAI (gpt-4o-mini) — AI reasoning served on Tencent Cloud TokenHub.
Findings
| Severity | Finding | Location | Confidence |
|---|---|---|---|
| high | Arbitrary Send Eth The repayETH function sends excess ETH back to msg.sender using transfer, but if msg.sender is a contract that does not implement a payable fallback or has a high gas requirement, the transfer can fail, locking funds. Additionally, using transfer instead of a low-level call like call{value} limits forward gas to 2300, which may not be sufficient for complex receivers and can cause permanent loss of refunds. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:55 | 95% |
| high | Arbitrary Send Eth The borrowETH function sends ETH to msg.sender using transfer, which also has the same gas limit issue. Since the function withdraws WETH to ETH first, if the recipient is a contract that cannot accept the transfer with only 2300 gas, the entire borrowed amount can be lost in the contract. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:47 | 95% |
| high | Arbitrary Send Eth The `withdrawETH` function uses `payable(to).transfer(withdrawn)` which sends ETH to an arbitrary address provided by the caller. This is dangerous because `transfer` forwards only 2300 gas, which may cause the call to fail if the recipient is a contract that requires more gas, effectively locking funds. Additionally, it allows draining the contract's ETH balance to any address without restrictions. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:39 | 95% |
| medium | Unused Return In `depositETH`, the return value of `IWETHLike(WETH).approve(POOL, msg.value)` is not checked. If the approval fails (e.g., due to a token that returns false on failure), the subsequent `supply` call might revert or behave unexpectedly, potentially locking user funds. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:32 | 85% |
| medium | Unused Return The `repayETH` function ignores the return value from `IWETHLike(WETH).approve(POOL, amount)`. The ERC-20 `approve` function returns a boolean indicating success; ignoring it may lead to silent approval failures, preventing the subsequent `repay` call from spending WETH. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:55 | 90% |
| low | Missing Zero Check The `withdrawETH` function does not check that `amount` is nonzero before calling `IPoolLike(POOL).withdraw`. Withdrawing zero may emit events or consume gas without meaningful effect, and in some Aave pool versions it could return zero, leaving the caller with no WETH and no ETH. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:39 | 80% |
| low | Missing Zero Check Constructor parameters `weth` and `pool` lack zero-address validation, potentially allowing deployment with invalid addresses. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:25 | 95% |
| info | Naming Convention The naming convention for the contract and its variables could be improved for better readability and consistency. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:23 | 60% |
| info | Naming Convention The naming convention for the variable 'WETH' does not follow the standard camelCase format. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:22 | 70% |
| info | Naming Convention The naming convention for the variable 'POOL' does not follow the standard camelCase format. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:21 | 70% |
| low | Review calldata parameter width External function `supply` accepts `uint16 referralCode` but Mantle calldata overhead suggests `uint256` may be more gas-efficient; review actual usage. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:8 | 60% |
| low | Review calldata parameter width The calldata parameter 'referralCode' in the 'supply' function of the IPoolLike interface uses uint16, which takes 2 bytes. On Mantle Mainnet, calldata is priced per byte, so using a wider type than necessary increases gas costs. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:9 | 80% |
| low | Review calldata parameter width The calldata parameter 'referralCode' in the 'borrow' function of the IPoolLike interface uses uint16. On Mantle Mainnet, calldata is priced per byte, so using a wider type than necessary increases gas costs. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:10 | 80% |
| low | Review calldata parameter width The `repay` function in the IPool interface uses `uint256` for `amount` and `interestRateMode` parameters, but since `amount` represents a token amount and `interestRateMode` is typically a fixed set of modes (e.g., 0 or 1 for variable/fixed), using a narrower type like `uint160` for amounts or `uint8` for interestRateMode could reduce calldata size and gas costs on L2. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:11 | 70% |
| low | Review calldata parameter width The `withdraw` function in IWETHLike uses `uint256 amount` for the ETH amount to unwrap. Since WETH withdrawals typically involve ETH amounts up to ~2^128 in practice, narrowing to `uint128` or even `uint112` could reduce calldata size. However, WETH is an ERC-20 where decimals=18, so amounts can be up to the total supply (currently ~5e27, fits in uint256). | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:16 | 60% |
| low | Review calldata parameter width The parameter 'amount' in function `approve` is declared as uint256. Using a smaller type like uint128 or uint160 could reduce calldata gas costs when calling this function on L2, while remaining within typical token value ranges. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:17 | 70% |
| low | Review calldata parameter width The parameter 'amount' in function `transferFrom` is declared as uint256. Using a smaller type like uint128 could be considered to reduce L2 calldata costs, provided the token supply does not exceed the smaller type's range. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:18 | 60% |
| low | Review calldata parameter width The `withdrawETH` function uses `uint256 amount` as a calldata parameter, but the actual value may never need the full 256-bit range. Using a smaller unsigned integer type (e.g., `uint128` or `uint160`) can reduce calldata size and gas costs, especially on Mantle where calldata efficiency is important. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:39 | 70% |
| low | Review calldata parameter width The `borrowETH` function takes `uint256 amount`, `uint256 interestRateMode`, and `uint16 referralCode` as calldata. The `interestRateMode` is typically only 0 or 1 (stable/variable), which can be represented as a `uint8` or `uint16`. Reducing calldata width for `amount` and `interestRateMode` can lower gas costs on Mantle. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:47 | 75% |
| low | Review calldata parameter width The function 'repayETH' uses a uint256 type for the 'amount' parameter, which may be optimized for gas usage by using a smaller type. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:55 | 70% |
| info | Replace long revert string with custom error The contract uses a string-based revert reason ('INSUFFICIENT_MSG_VALUE') in a require statement. Replacing this with a custom error will reduce deployment and execution gas costs. | AaveWrappedTokenGatewayV3_Interface_Suite__3_contracts_.sol:56 | 95% |

