Skip to content

Conversation

@MoMannn
Copy link
Contributor

@MoMannn MoMannn commented Jun 20, 2025

What?

  • Test on how to best use delegations to deposit / withdraw funds for Aave v3 protocol.

Why?

  • Requested feature.

How?

  • By leveraging existing caveat enforcers

Notes

  • This PR includes a POC of the adapter that will be used for interacting with the Aave protocol. This adapter helps skip the ERC20 approval step and directly transfer ERC20 tokens using a delegation.

Note

Medium Risk
Adds new adapter contracts that redeem delegation chains to move and approve tokens before calling external DeFi protocols (Aave/Morpho), so mistakes could impact funds flow despite comprehensive fork-based tests.

Overview
Adds Delegation Adapters for DeFi protocols that don’t natively support delegations, including a new AaveAdapter (supply/withdraw) and MorphoAdapter (ERC-4626 deposit/redeem) that redeem a delegation chain to atomically transfer tokens into the adapter, perform the protocol call, and direct outputs back to the root delegator.

Introduces supporting protocol interfaces (IAavePool, IMorphoVault), a DeployAaveAdapter Foundry script, and extensive mainnet-fork tests (AaveLending.t.sol, MorphoLending.t.sol) covering direct flows, adapter flows, events, and revert cases. Updates docs (README.md, new documents/Adapters.md) and enhances script/coverage.sh to run/merge coverage across EVM versions (London + Shanghai/Cancun-specific test subsets).

Written by Cursor Bugbot for commit 1ed69ec. This will update automatically on new commits. Configure here.

@MoMannn MoMannn requested a review from a team as a code owner June 20, 2025 13:09
@MoMannn MoMannn self-assigned this Jun 20, 2025
@MoMannn MoMannn requested a review from hanzel98 June 20, 2025 13:09
@hanzel98 hanzel98 added the new release This PR goes to the next release label Jun 25, 2025
@hanzel98 hanzel98 changed the title feat: Add Aave lending deposit and withdrawal with delegation Add Aave Lending Deposit and Withdrawal With Delegation Jun 26, 2025
cursor[bot]

This comment was marked as outdated.

@hanzel98
Copy link
Contributor

hanzel98 commented Jul 2, 2025

It is pending to validate if we prefer the simple withdrawByDelegation or withdrawByDelegationOpenEnded

If we decide that we want both options, then we need to unify the code to avoid code duplication and also apply the same approach to the other adapters.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Withdrawal Events Emit Incorrect Amount

The withdrawByDelegation and withdrawByDelegationOpenEnded functions incorrectly emit the WithdrawExecuted event with the requested _amount parameter. The aavePool.withdraw() function returns the actual amount withdrawn, which can differ from the requested amount (e.g., when type(uint256).max is used for full withdrawal). This leads to inaccurate event data.

src/helpers/AaveAdapter.sol#L186-L189

// Withdraw from Aave directly to the delegator
aavePool.withdraw(_token, _amount, msg.sender);
emit WithdrawExecuted(msg.sender, msg.sender, _token, _amount);

src/helpers/AaveAdapter.sol#L217-L220

// Withdraw from Aave directly to the delegator
aavePool.withdraw(_token, _amount, _delegations[0].delegator);
emit WithdrawExecuted(_delegations[0].delegator, msg.sender, _token, _amount);

Fix in Cursor


Bug: Allowance Overflow in SafeIncreaseAllowance

The _ensureAllowance function can cause an arithmetic overflow. If the current allowance is non-zero but insufficient, calling safeIncreaseAllowance with type(uint256).max will attempt currentAllowance + type(uint256).max, which overflows uint256 and reverts the transaction (due to Solidity 0.8+ overflow checks). This logical flaw, while unlikely in practice, can be resolved by using safeApprove to set the allowance directly to type(uint256).max or by calculating the precise increase amount.

src/helpers/AaveAdapter.sol#L93-L99

/// @param _amount Amount needed for the operation
function _ensureAllowance(IERC20 _token, uint256 _amount) private {
uint256 allowance_ = _token.allowance(address(this), address(aavePool));
if (allowance_ < _amount) {
_token.safeIncreaseAllowance(address(aavePool), type(uint256).max);
}
}

Fix in Cursor


Was this report helpful? Give feedback by reacting with 👍 or 👎

@hanzel98
Copy link
Contributor

hanzel98 commented Sep 3, 2025

This PR needs an RPC URL secret on github to work

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

if (allowance_ < _amount) {
_token.safeIncreaseAllowance(address(aavePool), _amount);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_ensureAllowance over-approves by adding instead of setting allowance

Medium Severity

_ensureAllowance calls safeIncreaseAllowance(spender, _amount) which adds _amount to the current allowance, resulting in allowance_ + _amount. The intent is to ensure the allowance is at least _amount, so the increase should be _amount - allowance_, or forceApprove could set it directly to _amount. While this works when the starting allowance is zero (normal flow), any residual allowance causes over-approval and risks arithmetic overflow with large _amount values. The same issue exists in MorphoAdapter._ensureAllowance.

Additional Locations (1)

Fix in Cursor Fix in Web


emit StuckTokensWithdrawn(_token, _recipient, _amount);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicated adapter infrastructure across AaveAdapter and MorphoAdapter

Low Severity

MorphoAdapter and AaveAdapter share identical implementations of executeFromExecutor, withdrawEmergency, all error definitions, both modifiers (onlyDelegationManager, onlySelf), and the _ensureAllowance pattern. A shared base adapter contract would eliminate this duplication, reducing maintenance burden and the risk of inconsistent bug fixes across adapters.

Additional Locations (1)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

new release This PR goes to the next release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants