// SPDX-License-Identifier: MIT pragma solidity ^0.8.23; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; /** * @title AereVaultRelayer * @notice Token allowance proxy for the AereSettlement batch DEX. * Users approve THIS contract once for each token they intend to trade * (typically MaxUint256). AereSettlement calls into the relayer to pull * tokens during batch settlement. * * Following CoW Protocol's GPv2VaultRelayer pattern — separates token * allowances from the settlement contract so the settlement contract * can be upgraded without users having to re-approve. */ contract AereVaultRelayer is Ownable { using SafeERC20 for IERC20; /// The single authorised caller (AereSettlement). Owner can rotate it. address public settlement; event SettlementChanged(address indexed previousSettlement, address indexed newSettlement); modifier onlySettlement() { require(msg.sender == settlement, "Relayer: caller not settlement"); _; } function setSettlement(address _settlement) external onlyOwner { emit SettlementChanged(settlement, _settlement); settlement = _settlement; } /// Pull `amount` of `token` from `from` to `to`. Only callable by the settlement contract. function transferFromUser(IERC20 token, address from, address to, uint256 amount) external onlySettlement { token.safeTransferFrom(from, to, amount); } }