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 8b358da commit 5bda31e
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 8 deletions.
46 changes: 38 additions & 8 deletions contracts/src/ExaPlugin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
NotMarket,
Proposal,
Proposed,
SwapProposed,
Timelocked,
Unauthorized
} from "./IExaAccount.sol";
Expand Down Expand Up @@ -112,12 +113,30 @@ 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 }))
});
emit SwapProposed(
msg.sender, market, msg.sender, amount, block.timestamp + PROPOSAL_DELAY, assetOut, minAmountOut, route
);
}

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 +221,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 +774,9 @@ struct RepayCallbackData {
uint256 positionAssets;
uint256 maxRepay;
}

struct SwapData {
IERC20 assetOut;
uint256 minAmountOut;
bytes route;
}
14 changes: 14 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 @@ -62,6 +64,17 @@ event Proposed(
address indexed account, IMarket indexed market, address indexed receiver, uint256 amount, uint256 unlock
);

event SwapProposed(
address indexed account,
IMarket indexed market,
address indexed receiver,
uint256 amount,
uint256 unlock,
IERC20 assetOut,
uint256 minAmountOut,
bytes route
);

struct FixedPool {
uint256 borrowed;
uint256 supplied;
Expand All @@ -87,6 +100,7 @@ struct Proposal {
IMarket market;
address receiver;
uint256 timestamp;
bytes swapData;
}

error BorrowLimitExceeded();
Expand Down

0 comments on commit 5bda31e

Please sign in to comment.