Skip to content

Commit

Permalink
feat: Add Hybrid (Curve + UniV3) exchange for Zappers
Browse files Browse the repository at this point in the history
  • Loading branch information
bingen committed Oct 17, 2024
1 parent 61fddeb commit 0caf955
Show file tree
Hide file tree
Showing 12 changed files with 509 additions and 100 deletions.
10 changes: 6 additions & 4 deletions contracts/src/Zappers/GasCompZapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ contract GasCompZapper is LeftoversSweep, BaseZapper, IFlashLoanReceiver, IZappe
borrowerOperations.repayBold(_troveId, _boldAmount);

// return leftovers to user
_returnLeftovers(collToken, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

function adjustTrove(
Expand Down Expand Up @@ -247,7 +247,7 @@ contract GasCompZapper is LeftoversSweep, BaseZapper, IFlashLoanReceiver, IZappe
}

// return leftovers to user
_returnLeftovers(collToken, boldToken, _initialBalances);
_returnLeftovers(_initialBalances);
}

function closeTroveToRawETH(uint256 _troveId) external {
Expand Down Expand Up @@ -276,15 +276,17 @@ contract GasCompZapper is LeftoversSweep, BaseZapper, IFlashLoanReceiver, IZappe

// Set initial balances to make sure there are not lefovers
InitialBalances memory initialBalances;
_setInitialBalancesAndReceiver(collToken, boldToken, initialBalances, receiver);
initialBalances.tokens[0] = collToken;
initialBalances.tokens[1] = boldToken;
_setInitialBalancesAndReceiver(initialBalances, receiver);

// Flash loan coll
flashLoanProvider.makeFlashLoan(
collToken, _params.flashLoanAmount, IFlashLoanProvider.Operation.CloseTrove, abi.encode(_params)
);

// return leftovers to user
_returnLeftovers(collToken, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

function receiveFlashLoanOnCloseTroveFromCollateral(
Expand Down
46 changes: 25 additions & 21 deletions contracts/src/Zappers/LeftoversSweep.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,43 @@ import "../Interfaces/IBoldToken.sol";

contract LeftoversSweep {
struct InitialBalances {
uint256 boldBalance;
uint256 collBalance;
IERC20[4] tokens; // paving the way for completely dynamic routes
uint256[4] balances;
address receiver;
}

function _setInitialBalances(IERC20 _collToken, IBoldToken _boldToken, InitialBalances memory _initialBalances)
internal
view
{
_setInitialBalancesAndReceiver(_collToken, _boldToken, _initialBalances, msg.sender);
_initialBalances.tokens[0] = _collToken;
_initialBalances.tokens[1] = _boldToken;
_setInitialBalancesAndReceiver(_initialBalances, msg.sender);
}

function _setInitialBalancesAndReceiver(
IERC20 _collToken,
IBoldToken _boldToken,
InitialBalances memory _initialBalances,
address _receiver
) internal view {
_initialBalances.boldBalance = _boldToken.balanceOf(address(this));
_initialBalances.collBalance = _collToken.balanceOf(address(this));
_initialBalances.receiver = _receiver;
function _setInitialBalances(InitialBalances memory _initialBalances) internal view {
_setInitialBalancesAndReceiver(_initialBalances, msg.sender);
}

function _returnLeftovers(IERC20 _collToken, IBoldToken _boldToken, InitialBalances memory _initialBalances)
internal
{
uint256 currentCollBalance = _collToken.balanceOf(address(this));
if (currentCollBalance > _initialBalances.collBalance) {
_collToken.transfer(_initialBalances.receiver, currentCollBalance - _initialBalances.collBalance);
function _setInitialBalancesAndReceiver(InitialBalances memory _initialBalances, address _receiver) internal view {
for (uint256 i = 0; i < _initialBalances.tokens.length; i++) {
if (address(_initialBalances.tokens[i]) == address(0)) break;

_initialBalances.balances[i] = _initialBalances.tokens[i].balanceOf(address(this));
}
uint256 currentBoldBalance = _boldToken.balanceOf(address(this));
if (currentBoldBalance > _initialBalances.boldBalance) {
_boldToken.transfer(_initialBalances.receiver, currentBoldBalance - _initialBalances.boldBalance);
_initialBalances.receiver = _receiver;
}

function _returnLeftovers(InitialBalances memory _initialBalances) internal {
for (uint256 i = 0; i < _initialBalances.tokens.length; i++) {
if (address(_initialBalances.tokens[i]) == address(0)) break;

uint256 currentBalance = _initialBalances.tokens[i].balanceOf(address(this));
if (currentBalance > _initialBalances.balances[i]) {
_initialBalances.tokens[i].transfer(
_initialBalances.receiver, currentBalance - _initialBalances.balances[i]
);
}
}
}
}
6 changes: 3 additions & 3 deletions contracts/src/Zappers/LeverageLSTZapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ contract LeverageLSTZapper is GasCompZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(collToken, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down Expand Up @@ -145,7 +145,7 @@ contract LeverageLSTZapper is GasCompZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(collToken, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down Expand Up @@ -190,7 +190,7 @@ contract LeverageLSTZapper is GasCompZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(collToken, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down
6 changes: 3 additions & 3 deletions contracts/src/Zappers/LeverageWETHZapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ contract LeverageWETHZapper is WETHZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(WETH, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down Expand Up @@ -142,7 +142,7 @@ contract LeverageWETHZapper is WETHZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(WETH, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down Expand Up @@ -187,7 +187,7 @@ contract LeverageWETHZapper is WETHZapper, ILeverageZapper {
);

// return leftovers to user
_returnLeftovers(WETH, boldToken, initialBalances);
_returnLeftovers(initialBalances);
}

// Callback from the flash loan provider
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
pragma solidity ^0.8.0;

interface ICurvePool {
function add_liquidity(uint256[2] memory coins, uint256 min_mint_amount) external returns (uint256);
function add_liquidity(uint256[2] memory amounts, uint256 min_mint_amount) external returns (uint256);
//function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy, bool use_eth, address receiver) external returns (uint256 output);
function exchange(uint256 i, uint256 j, uint256 dx, uint256 min_dy) external returns (uint256 output);
function get_dy(uint256 i, uint256 j, uint256 dx) external view returns (uint256 dy);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./ICurveStableswapNGPool.sol";

interface ICurveStableswapNGFactory {
/*
function deploy_plain_pool(
string memory name,
string memory symbol,
address[2] memory coins,
uint256 A,
uint256 fee,
uint256 asset_type,
uint256 implementation_id
) external returns (ICurvePool);
*/
function deploy_plain_pool(
string memory name,
string memory symbol,
address[] memory coins,
uint256 A,
uint256 fee,
uint256 offpeg_fee_multiplier,
uint256 ma_exp_time,
uint256 implementation_id,
uint8[] memory asset_types,
bytes4[] memory method_ids,
address[] memory oracles
) external returns (ICurveStableswapNGPool);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface ICurveStableswapNGPool {
function add_liquidity(uint256[] memory amounts, uint256 min_mint_amount) external returns (uint256);
function exchange(int128 i, int128 j, uint256 dx, uint256 min_dy) external returns (uint256 output);
function get_dx(int128 i, int128 j, uint256 dy) external view returns (uint256 dx);
}
Loading

0 comments on commit 0caf955

Please sign in to comment.