Skip to content

Commit

Permalink
Add Bridger integration to AaveWithdrawWorkflow with new withdrawAndB…
Browse files Browse the repository at this point in the history
…ridge function and corresponding tests.
  • Loading branch information
ylv-io committed Nov 14, 2024
1 parent ccf9449 commit 2d94fe4
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
3 changes: 2 additions & 1 deletion script/migrations/145-upgrade_access_protocol.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ contract DeployScript is Script, MigrationHelper {
registry.allowWorkflow(address(aaveRepayWorkflow));

vm.broadcast(deployerPrivateKey);
AaveWithdrawWorkflow aaveWithdrawWorkflow = new AaveWithdrawWorkflow(getAavePoolProvider());
AaveWithdrawWorkflow aaveWithdrawWorkflow =
new AaveWithdrawWorkflow(getAavePoolProvider(), _getChainDeployment("AccessRegistry"));
saveContractAddress("AaveWithdrawWorkflow", address(aaveWithdrawWorkflow));

vm.broadcast(deployerPrivateKey);
Expand Down
24 changes: 22 additions & 2 deletions src/access/workflows/AaveWithdrawWorkflow.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {IERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin-5.0.1/contracts/token/ERC20/utils/SafeERC20.sol";
import {Address} from "@openzeppelin-5.0.1/contracts/utils/Address.sol";
import {IWETH} from "@kinto-core/interfaces/IWETH.sol";
import {IBridger} from "@kinto-core/interfaces/bridger/IBridger.sol";

import {IAavePool, IPoolAddressesProvider} from "@kinto-core/interfaces/external/IAavePool.sol";

Expand All @@ -20,15 +21,18 @@ contract AaveWithdrawWorkflow {

/// @notice Address of the PoolAddressesProvider contract
IPoolAddressesProvider public immutable poolAddressProvider;
/// @notice Address of the Bridger contract
IBridger public immutable bridger;

/* ============ Constructor ============ */

/**
* @notice Initializes the contract with Aave's pool address provider
* @param poolAddressProvider_ The address of Aave's pool address provider
*/
constructor(address poolAddressProvider_) {
constructor(address poolAddressProvider_, address bridger_) {
poolAddressProvider = IPoolAddressesProvider(poolAddressProvider_);
bridger = IBridger(bridger_);
}

/* ============ External Functions ============ */
Expand All @@ -38,7 +42,7 @@ contract AaveWithdrawWorkflow {
* @param asset The address of the asset to withdraw
* @param amount The amount to withdraw (use type(uint256).max for max available)
*/
function withdraw(address asset, uint256 amount) external {
function withdraw(address asset, uint256 amount) public {
address pool = poolAddressProvider.getPool();

// If amount is max uint256, withdraw all available
Expand All @@ -49,4 +53,20 @@ contract AaveWithdrawWorkflow {
// Withdraw from Aave
IAavePool(pool).withdraw(asset, amount, address(this));
}

function withdrawAndBridge(
address asset,
uint256 amount,
address kintoWallet,
IBridger.BridgeData calldata bridgeData
) external payable returns (uint256 amountOut) {
withdraw(asset, amount);

// Approve max allowance to save on gas for future transfers
if (IERC20(asset).allowance(address(this), address(bridger)) < amount) {
IERC20(asset).forceApprove(address(bridger), type(uint256).max);
}

return bridger.depositERC20(asset, amount, kintoWallet, asset, amount, bytes(""), bridgeData);
}
}
57 changes: 55 additions & 2 deletions test/fork/workflows/AaveWithdrawWorkflow.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {IAccessPoint} from "@kinto-core/interfaces/IAccessPoint.sol";

import {AccessRegistry} from "@kinto-core/access/AccessRegistry.sol";
import {AaveWithdrawWorkflow} from "@kinto-core/access/workflows/AaveWithdrawWorkflow.sol";
import {IBridger} from "@kinto-core/interfaces/bridger/IBridger.sol";
import {Bridger} from "@kinto-core/bridger/Bridger.sol";
import {BridgeDataHelper} from "@kinto-core-test/helpers/BridgeDataHelper.sol";

import "@kinto-core-test/fork/const.sol";
import "@kinto-core-test/helpers/UUPSProxy.sol";
Expand All @@ -23,9 +26,10 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

import "forge-std/console2.sol";

contract AaveWithdrawWorkflowTest is SignatureHelper, ForkTest, ArtifactsReader, Constants {
contract AaveWithdrawWorkflowTest is SignatureHelper, ForkTest, ArtifactsReader, Constants, BridgeDataHelper {
using stdJson for string;

Bridger internal bridger;
AccessRegistry internal accessRegistry;
IAccessPoint internal accessPoint;
AaveWithdrawWorkflow internal aaveWithdrawWorkflow;
Expand All @@ -34,6 +38,7 @@ contract AaveWithdrawWorkflowTest is SignatureHelper, ForkTest, ArtifactsReader,
function setUp() public override {
super.setUp();

bridger = Bridger(payable(_getChainDeployment("Bridger")));
accessRegistry = AccessRegistry(_getChainDeployment("AccessRegistry"));

aavePool = IAavePool(IPoolAddressesProvider(ARB_AAVE_POOL_PROVIDER).getPool());
Expand All @@ -45,7 +50,7 @@ contract AaveWithdrawWorkflowTest is SignatureHelper, ForkTest, ArtifactsReader,
accessPoint = accessRegistry.deployFor(address(alice0));
vm.label(address(accessPoint), "accessPoint");

aaveWithdrawWorkflow = new AaveWithdrawWorkflow(ARB_AAVE_POOL_PROVIDER);
aaveWithdrawWorkflow = new AaveWithdrawWorkflow(ARB_AAVE_POOL_PROVIDER, address(bridger));
vm.label(address(aaveWithdrawWorkflow), "aaveWithdrawWorkflow");

vm.prank(accessRegistry.owner());
Expand Down Expand Up @@ -126,4 +131,52 @@ contract AaveWithdrawWorkflowTest is SignatureHelper, ForkTest, ArtifactsReader,
);
assertEq(IERC20(aToken).balanceOf(address(accessPoint)), 0, "Invalid aToken balance");
}

function testWithdrawAndBridge() public {
address assetToWithdraw = USDC_ARBITRUM;
uint256 amountToWithdraw = 1e6;
address aToken = aavePool.getReserveData(assetToWithdraw).aTokenAddress;

// Supply first to have something to withdraw
deal(assetToWithdraw, address(accessPoint), amountToWithdraw);
vm.startPrank(address(accessPoint));
IERC20(assetToWithdraw).approve(address(aavePool), amountToWithdraw);
aavePool.supply(assetToWithdraw, amountToWithdraw, address(accessPoint), 0);
vm.stopPrank();

IBridger.BridgeData memory bridgeData = bridgeData[block.chainid][USDC_ARBITRUM];

// Get initial balances
uint256 initialAccessPointBalance = IERC20(assetToWithdraw).balanceOf(address(accessPoint));
uint256 initialATokenBalance = IERC20(aToken).balanceOf(address(accessPoint));
uint256 initialBridgerBalance = IERC20(assetToWithdraw).balanceOf(address(bridger));
uint256 initialVaultBalance = IERC20(assetToWithdraw).balanceOf(address(bridgeData.vault));

// Prepare workflow data
bytes memory workflowData = abi.encodeWithSelector(
AaveWithdrawWorkflow.withdrawAndBridge.selector, assetToWithdraw, amountToWithdraw, alice0, bridgeData
);

// Execute the withdrawAndBridge workflow
vm.prank(alice0);
accessPoint.execute(address(aaveWithdrawWorkflow), workflowData);

// Assert balances changed correctly
assertEq(
IERC20(assetToWithdraw).balanceOf(address(accessPoint)),
initialAccessPointBalance,
"Invalid access point balance"
);
assertEq(
IERC20(aToken).balanceOf(address(accessPoint)),
initialATokenBalance - amountToWithdraw,
"Invalid aToken balance"
);
assertEq(IERC20(assetToWithdraw).balanceOf(address(bridger)), initialBridgerBalance, "Invalid bridger balance");
assertEq(
IERC20(assetToWithdraw).balanceOf(address(bridgeData.vault)),
initialVaultBalance + amountToWithdraw,
"Invalid vault balance"
);
}
}
9 changes: 9 additions & 0 deletions test/helpers/BridgeDataHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,15 @@ abstract contract BridgeDataHelper is Constants {
options: bytes("")
});

bridgeData[ARBITRUM_CHAINID][USDC_ARBITRUM] = IBridger.BridgeData({
vault: 0xC88A469B96A62d4DA14Dc5e23BDBC495D2b15C6B,
gasFee: 1e16,
msgGasLimit: 500_000,
connector: 0xD97E3cD27fb8af306b2CD42A61B7cbaAF044D08D,
execPayload: bytes(""),
options: bytes("")
});

bridgeData[ARBITRUM_CHAINID][DAI_ARBITRUM] = IBridger.BridgeData({
vault: 0x36E2DBe085eE4d028fD60f70670f662365d0E978,
gasFee: 1e16,
Expand Down

0 comments on commit 2d94fe4

Please sign in to comment.