Skip to content

Commit

Permalink
🚧 propose swap
Browse files Browse the repository at this point in the history
co-authored-by: danilo neves cruz <[email protected]>
  • Loading branch information
itofarina and cruzdanilo committed Jan 7, 2025
1 parent 1d2e9b4 commit 3d2552a
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 8 deletions.
43 changes: 35 additions & 8 deletions contracts/src/ExaPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,28 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {

function propose(IMarket market, uint256 amount, address receiver) external {
_checkMarket(market);
proposals[msg.sender] = Proposal({ amount: amount, market: market, timestamp: block.timestamp, receiver: receiver });
proposals[msg.sender] =
Proposal({ amount: amount, market: market, timestamp: block.timestamp, receiver: receiver, swapData: "" });
emit Proposed(msg.sender, market, receiver, amount, block.timestamp + PROPOSAL_DELAY);
}

function swap(IERC20 assetIn, IERC20 assetOut, uint256 maxAmountIn, uint256 minAmountOut, bytes memory route)
// TODO add to manifest, only self. or merge with propose
function proposeSwap(IMarket market, uint256 amount, IERC20 assetOut, uint256 minAmountOut, bytes memory route)
external
{
_checkMarket(market);
proposals[msg.sender] = Proposal({
amount: amount,
market: market,
timestamp: block.timestamp,
receiver: msg.sender,
swapData: abi.encode(SwapData({ assetOut: assetOut, minAmountOut: minAmountOut, route: route }))
});
// TODO emit
}

function swap(IERC20 assetIn, IERC20 assetOut, uint256 maxAmountIn, uint256 minAmountOut, bytes memory route)
public
returns (uint256 amountIn, uint256 amountOut)
{
uint256 balanceIn = assetIn.balanceOf(msg.sender);
Expand Down Expand Up @@ -202,14 +218,19 @@ contract ExaPlugin is AccessControl, BasePlugin, IExaAccount {
address market = address(proposal.market);
if (market == address(0)) revert NoProposal();

uint256 amount = proposal.amount;
if (market != address(EXA_WETH)) {
_executeFromSender(market, 0, abi.encodeCall(IERC4626.withdraw, (proposal.amount, proposal.receiver, msg.sender)));
return;
_executeFromSender(market, 0, abi.encodeCall(IERC4626.withdraw, (amount, proposal.receiver, msg.sender)));
} else {
_executeFromSender(market, 0, abi.encodeCall(IERC4626.withdraw, (amount, address(this), msg.sender)));
WETH.withdraw(amount);
proposal.receiver.safeTransferETH(amount);
}

if (proposal.swapData.length != 0) {
SwapData memory data = abi.decode(proposal.swapData, (SwapData));
swap(IERC20(proposal.market.asset()), data.assetOut, amount, data.minAmountOut, data.route);
}
uint256 amount = proposal.amount;
_executeFromSender(market, 0, abi.encodeCall(IERC4626.withdraw, (amount, address(this), msg.sender)));
WETH.withdraw(amount);
proposal.receiver.safeTransferETH(amount);
}

function collectCollateral(
Expand Down Expand Up @@ -750,3 +771,9 @@ struct RepayCallbackData {
uint256 positionAssets;
uint256 maxRepay;
}

struct SwapData {
IERC20 assetOut;
uint256 minAmountOut;
bytes route;
}
3 changes: 3 additions & 0 deletions contracts/src/IExaAccount.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { IERC4626 } from "openzeppelin-contracts/contracts/interfaces/IERC4626.s

interface IExaAccount {
function propose(IMarket market, uint256 amount, address receiver) external;
function proposeSwap(IMarket market, uint256 amount, IERC20 assetOut, uint256 minAmountOut, bytes memory route)
external;
function swap(IERC20 assetIn, IERC20 assetOut, uint256 maxAmountIn, uint256 minAmountOut, bytes memory route)
external
returns (uint256 amountIn, uint256 amountOut);
Expand Down Expand Up @@ -87,6 +89,7 @@ struct Proposal {
IMarket market;
address receiver;
uint256 timestamp;
bytes swapData;
}

error BorrowLimitExceeded();
Expand Down

0 comments on commit 3d2552a

Please sign in to comment.