Flash unwinder contracts and scripts, relay lane tuning, trustless bridge and token-aggregation updates.
Made-with: Cursor
This commit is contained in:
@@ -5,6 +5,19 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
interface IAavePoolLike {
|
||||
/// @notice Standard V3 flash loan (single-asset via length-1 arrays). Use this on Aave V3.2+ pools
|
||||
/// where `flashLoanSimple` may revert with `NotActivated()`.
|
||||
function flashLoan(
|
||||
address receiverAddress,
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata interestRateModes,
|
||||
address onBehalfOf,
|
||||
bytes calldata params,
|
||||
uint16 referralCode
|
||||
) external;
|
||||
|
||||
/// @dev Retained for compatibility with older pool deployments; prefer `flashLoan` for new integrations.
|
||||
function flashLoanSimple(
|
||||
address receiverAddress,
|
||||
address asset,
|
||||
@@ -14,6 +27,17 @@ interface IAavePoolLike {
|
||||
) external;
|
||||
}
|
||||
|
||||
/// @dev Callback for `flashLoan` (multi-asset API).
|
||||
interface IAaveFlashLoanReceiver {
|
||||
function executeOperation(
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata premiums,
|
||||
address initiator,
|
||||
bytes calldata params
|
||||
) external returns (bool);
|
||||
}
|
||||
|
||||
interface IAaveFlashLoanSimpleReceiver {
|
||||
function executeOperation(
|
||||
address asset,
|
||||
@@ -58,10 +82,10 @@ interface IAaveAtomicBridgeCoordinator {
|
||||
|
||||
/**
|
||||
* @title AaveQuotePushFlashReceiver
|
||||
* @notice Aave V3 flashLoanSimple receiver for the quote-push workflow:
|
||||
* flash borrow quote -> buy PMM base -> unwind base externally -> repay lender, retaining any surplus.
|
||||
* @notice Aave V3 flash-loan receiver for the quote-push workflow:
|
||||
* flash borrow quote (`flashLoan` single-asset) -> buy PMM base -> unwind base externally -> repay lender, retaining any surplus.
|
||||
*/
|
||||
contract AaveQuotePushFlashReceiver is IAaveFlashLoanSimpleReceiver {
|
||||
contract AaveQuotePushFlashReceiver is IAaveFlashLoanSimpleReceiver, IAaveFlashLoanReceiver {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
address public immutable pool;
|
||||
@@ -119,7 +143,29 @@ contract AaveQuotePushFlashReceiver is IAaveFlashLoanSimpleReceiver {
|
||||
}
|
||||
|
||||
function flashQuotePush(address asset, uint256 amount, QuotePushParams calldata params) external {
|
||||
IAavePoolLike(pool).flashLoanSimple(address(this), asset, amount, abi.encode(address(this), params), 0);
|
||||
address[] memory assets = new address[](1);
|
||||
uint256[] memory amts = new uint256[](1);
|
||||
uint256[] memory modes = new uint256[](1);
|
||||
assets[0] = asset;
|
||||
amts[0] = amount;
|
||||
modes[0] = 0;
|
||||
// `onBehalfOf` must not be zero on some Aave V3.2+ deployments (mapping lookups revert NotActivated).
|
||||
IAavePoolLike(pool).flashLoan(
|
||||
address(this), assets, amts, modes, address(this), abi.encode(address(this), params), 0
|
||||
);
|
||||
}
|
||||
|
||||
function executeOperation(
|
||||
address[] calldata assets,
|
||||
uint256[] calldata amounts,
|
||||
uint256[] calldata premiums,
|
||||
address initiator,
|
||||
bytes calldata params
|
||||
) external returns (bool) {
|
||||
if (msg.sender != pool) revert UntrustedPool();
|
||||
if (assets.length != 1 || amounts.length != 1 || premiums.length != 1) revert BadParams();
|
||||
_executeQuotePush(assets[0], amounts[0], premiums[0], initiator, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
function executeOperation(
|
||||
@@ -130,6 +176,17 @@ contract AaveQuotePushFlashReceiver is IAaveFlashLoanSimpleReceiver {
|
||||
bytes calldata params
|
||||
) external returns (bool) {
|
||||
if (msg.sender != pool) revert UntrustedPool();
|
||||
_executeQuotePush(asset, amount, premium, initiator, params);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _executeQuotePush(
|
||||
address asset,
|
||||
uint256 amount,
|
||||
uint256 premium,
|
||||
address initiator,
|
||||
bytes calldata params
|
||||
) internal {
|
||||
(address expectedInitiator, QuotePushParams memory p) = abi.decode(params, (address, QuotePushParams));
|
||||
if (initiator != expectedInitiator) revert UntrustedInitiator();
|
||||
if (
|
||||
@@ -148,7 +205,6 @@ contract AaveQuotePushFlashReceiver is IAaveFlashLoanSimpleReceiver {
|
||||
uint256 unwindOut = _unwindBaseIntoQuote(p.baseToken, asset, p.externalUnwinder, p.minOutUnwind, p.unwindData);
|
||||
uint256 surplus = _approveRepayment(asset, amount + premium);
|
||||
emit QuotePushExecuted(asset, p.baseToken, amount, premium, baseOut, unwindOut, surplus);
|
||||
return true;
|
||||
}
|
||||
|
||||
function _swapQuoteForBase(address asset, uint256 amount, address integration, address pmmPool, uint256 minOutPmm)
|
||||
|
||||
Reference in New Issue
Block a user