-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
324 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.17; | ||
|
||
import './handlers/aavev3/IPool.sol'; | ||
import './handlers/aavev3/IPoolAddressesProvider.sol'; | ||
import './interfaces/IERC20Usdt.sol'; | ||
import './handlers/univ3/ISwapRouter.sol'; | ||
|
||
import '@openzeppelin/contracts/access/Ownable.sol'; | ||
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; | ||
|
||
contract Execution is Ownable { | ||
using SafeERC20 for IERC20; | ||
|
||
//Goerli | ||
address public constant PROVIDER = 0xc4dCB5126a3AfEd129BC3668Ea19285A9f56D15D; | ||
ISwapRouter public constant ROUTER = ISwapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564); | ||
address public constant NATIVE_TOKEN_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; | ||
|
||
function getContractName() public pure returns (string memory) { | ||
return 'Execution'; | ||
} | ||
|
||
function transferToken( | ||
address token, | ||
address to, | ||
uint256 amount, | ||
address originationAddress | ||
) external onlyOwner { | ||
IERC20(token).safeTransferFrom(originationAddress, to, amount); | ||
} | ||
|
||
function exactInputSingle( | ||
address originationAddress, | ||
address tokenIn, | ||
address tokenOut, | ||
uint24 fee, | ||
address destinationAddress, | ||
uint256 amountIn | ||
) external payable onlyOwner returns (uint256 amountOut) { | ||
// Build params for router call | ||
ISwapRouter.ExactInputSingleParams memory params; | ||
params.tokenIn = tokenIn; | ||
params.tokenOut = tokenOut; | ||
params.fee = fee; | ||
params.amountIn = _getBalance(tokenIn, amountIn); | ||
params.amountOutMinimum = 0; | ||
params.sqrtPriceLimitX96 = 0; | ||
params.recipient = destinationAddress; | ||
|
||
IERC20(tokenIn).safeTransferFrom(originationAddress, address(this), amountIn); | ||
_tokenApprove(tokenIn, address(ROUTER), params.amountIn); | ||
amountOut = _exactInputSingle(0, params); | ||
} | ||
|
||
function depositAaveV3( | ||
address token, | ||
uint256 amount, | ||
address destinationAddress, | ||
address originationAddress | ||
) external payable onlyOwner { | ||
amount = _getBalance(token, amount); | ||
IERC20(token).safeTransferFrom(originationAddress, address(this), amount); | ||
_depositAaveV3(token, amount, destinationAddress); | ||
} | ||
|
||
function _depositAaveV3( | ||
address asset, | ||
uint256 amount, | ||
address destinationAddress | ||
) internal { | ||
(address pool, ) = _getPoolAndAToken(asset); | ||
_tokenApprove(asset, pool, amount); | ||
try IPool(pool).supply(asset, amount, destinationAddress, 0) {} catch Error( | ||
string memory reason | ||
) { | ||
_revertMsg('supply', reason); | ||
} catch { | ||
_revertMsg('supply'); | ||
} | ||
} | ||
|
||
/* ========== INTERNAL FUNCTIONS ========== */ | ||
|
||
function _getPoolAndAToken(address underlying) | ||
internal | ||
view | ||
returns (address pool, address aToken) | ||
{ | ||
pool = IPoolAddressesProvider(PROVIDER).getPool(); | ||
try IPool(pool).getReserveData(underlying) returns (DataTypes.ReserveData memory data) { | ||
aToken = data.aTokenAddress; | ||
_requireMsg(aToken != address(0), 'General', 'aToken should not be zero address'); | ||
} catch Error(string memory reason) { | ||
_revertMsg('General', reason); | ||
} catch { | ||
_revertMsg('General'); | ||
} | ||
} | ||
|
||
function _exactInputSingle(uint256 value, ISwapRouter.ExactInputSingleParams memory params) | ||
internal | ||
returns (uint256) | ||
{ | ||
params.deadline = block.timestamp; | ||
|
||
try ROUTER.exactInputSingle{value: value}(params) returns (uint256 amountOut) { | ||
return amountOut; | ||
} catch Error(string memory reason) { | ||
_revertMsg('exactInputSingle', reason); | ||
} catch { | ||
_revertMsg('exactInputSingle'); | ||
} | ||
} | ||
|
||
function _tokenApprove( | ||
address token, | ||
address spender, | ||
uint256 amount | ||
) internal { | ||
try IERC20Usdt(token).approve(spender, amount) {} catch { | ||
IERC20(token).safeApprove(spender, 0); | ||
IERC20(token).safeApprove(spender, amount); | ||
} | ||
} | ||
|
||
function _getBalance(address token, uint256 amount) internal view returns (uint256) { | ||
if (amount != type(uint256).max) { | ||
return amount; | ||
} | ||
|
||
// ETH case | ||
if (token == address(0) || token == NATIVE_TOKEN_ADDRESS) { | ||
return address(this).balance; | ||
} | ||
// ERC20 token case | ||
return IERC20(token).balanceOf(address(this)); | ||
} | ||
|
||
function _requireMsg( | ||
bool condition, | ||
string memory functionName, | ||
string memory reason | ||
) internal pure { | ||
if (!condition) _revertMsg(functionName, reason); | ||
} | ||
|
||
function _revertMsg(string memory functionName, string memory reason) internal pure { | ||
revert(string(abi.encodePacked(getContractName(), '_', functionName, ': ', reason))); | ||
} | ||
|
||
function _revertMsg(string memory functionName) internal pure { | ||
_revertMsg(functionName, 'Unspecified'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// SPDX-License-Identifier: MIT | ||
|
||
pragma solidity 0.8.17; | ||
|
||
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol'; | ||
import '../HandlerBase.sol'; | ||
|
||
contract HFunds is HandlerBase { | ||
using SafeERC20 for IERC20; | ||
|
||
function getContractName() public pure override returns (string memory) { | ||
return 'HFunds'; | ||
} | ||
|
||
function inject(address[] calldata tokens, uint256[] calldata amounts) | ||
external | ||
payable | ||
returns (uint256[] memory) | ||
{ | ||
return _inject(tokens, amounts); | ||
} | ||
|
||
function _inject(address[] calldata tokens, uint256[] calldata amounts) | ||
internal | ||
returns (uint256[] memory) | ||
{ | ||
_requireMsg(tokens.length == amounts.length, 'inject', 'token and amount does not match'); | ||
address sender = _getSender(); | ||
uint256[] memory amountsInProxy = new uint256[](amounts.length); | ||
|
||
for (uint256 i = 0; i < tokens.length; i++) { | ||
_notMaticToken(tokens[i]); | ||
IERC20(tokens[i]).safeTransferFrom(sender, address(this), amounts[i]); | ||
|
||
amountsInProxy[i] = amounts[i]; | ||
|
||
// Update involved token | ||
_updateToken(tokens[i]); | ||
} | ||
return amountsInProxy; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
pragma solidity ^0.8.0; | ||
|
||
import '@uniswap/interfaces/callback/IUniswapV3SwapCallback.sol'; | ||
|
||
/// @title Periphery Payments | ||
/// @notice Functions to ease deposits and withdrawals of ETH | ||
interface IPeripheryPayments { | ||
/// @notice Unwraps the contract's WETH9 balance and sends it to recipient as ETH. | ||
/// @dev The amountMinimum parameter prevents malicious contracts from stealing WETH9 from users. | ||
/// @param amountMinimum The minimum amount of WETH9 to unwrap | ||
/// @param recipient The address receiving ETH | ||
function unwrapWETH9(uint256 amountMinimum, address recipient) external payable; | ||
|
||
/// @notice Refunds any ETH balance held by this contract to the `msg.sender` | ||
/// @dev Useful for bundling with mint or increase liquidity that uses ether, or exact output swaps | ||
/// that use ether for the input amount | ||
function refundETH() external payable; | ||
|
||
/// @notice Transfers the full amount of a token held by this contract to recipient | ||
/// @dev The amountMinimum parameter prevents malicious contracts from stealing the token from users | ||
/// @param token The contract address of the token which will be transferred to `recipient` | ||
/// @param amountMinimum The minimum amount of token required for a transfer | ||
/// @param recipient The destination address of the token | ||
function sweepToken( | ||
address token, | ||
uint256 amountMinimum, | ||
address recipient | ||
) external payable; | ||
} | ||
|
||
/// @title Router token swapping functionality | ||
/// @notice Functions for swapping tokens via Uniswap V3 | ||
interface ISwapRouter is IUniswapV3SwapCallback, IPeripheryPayments { | ||
struct ExactInputSingleParams { | ||
address tokenIn; | ||
address tokenOut; | ||
uint24 fee; | ||
address recipient; | ||
uint256 deadline; | ||
uint256 amountIn; | ||
uint256 amountOutMinimum; | ||
uint160 sqrtPriceLimitX96; | ||
} | ||
|
||
/// @notice Swaps `amountIn` of one token for as much as possible of another token | ||
/// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata | ||
/// @return amountOut The amount of the received token | ||
function exactInputSingle(ExactInputSingleParams calldata params) | ||
external | ||
payable | ||
returns (uint256 amountOut); | ||
|
||
struct ExactInputParams { | ||
bytes path; | ||
address recipient; | ||
uint256 deadline; | ||
uint256 amountIn; | ||
uint256 amountOutMinimum; | ||
} | ||
|
||
/// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path | ||
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata | ||
/// @return amountOut The amount of the received token | ||
function exactInput(ExactInputParams calldata params) | ||
external | ||
payable | ||
returns (uint256 amountOut); | ||
|
||
struct ExactOutputSingleParams { | ||
address tokenIn; | ||
address tokenOut; | ||
uint24 fee; | ||
address recipient; | ||
uint256 deadline; | ||
uint256 amountOut; | ||
uint256 amountInMaximum; | ||
uint160 sqrtPriceLimitX96; | ||
} | ||
|
||
/// @notice Swaps as little as possible of one token for `amountOut` of another token | ||
/// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata | ||
/// @return amountIn The amount of the input token | ||
function exactOutputSingle(ExactOutputSingleParams calldata params) | ||
external | ||
payable | ||
returns (uint256 amountIn); | ||
|
||
struct ExactOutputParams { | ||
bytes path; | ||
address recipient; | ||
uint256 deadline; | ||
uint256 amountOut; | ||
uint256 amountInMaximum; | ||
} | ||
|
||
/// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) | ||
/// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata | ||
/// @return amountIn The amount of the input token | ||
function exactOutput(ExactOutputParams calldata params) | ||
external | ||
payable | ||
returns (uint256 amountIn); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,19 @@ | ||
// SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.13; | ||
|
||
import {Counter} from "../src/Counter.sol"; | ||
import "forge-std/Test.sol"; | ||
import {Counter} from '../src/Counter.sol'; | ||
import 'forge-std/Test.sol'; | ||
|
||
contract CounterTest is Test { | ||
Counter c; | ||
Counter c; | ||
|
||
function setUp() public { | ||
c = new Counter(); | ||
} | ||
function setUp() public { | ||
c = new Counter(); | ||
} | ||
|
||
function testIncrementCounter() public { | ||
require(c.getCount() == 0, "Counter should be 0"); | ||
c.increment(); | ||
require(c.getCount() == 1, "Counter should be 1"); | ||
} | ||
function testIncrementCounter() public { | ||
require(c.getCount() == 0, 'Counter should be 0'); | ||
c.increment(); | ||
require(c.getCount() == 1, 'Counter should be 1'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
@openzeppelin/=./packages/contracts/lib/openzeppelin-contracts/ | ||
ds-test/=packages/contracts/lib/forge-std/lib/ds-test/src/ | ||
forge-std/=./packages/contracts/lib/forge-std/src/ | ||
@uniswap/=./packages/contracts/lib/v3-core/contracts/ |