Skip to content

Commit

Permalink
feat: depositWithPermit in ERC20 zappers
Browse files Browse the repository at this point in the history
  • Loading branch information
lekhovitsky committed Oct 18, 2023
1 parent 128dacc commit dd8e14d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 0 deletions.
14 changes: 14 additions & 0 deletions contracts/interfaces/zappers/IERC20Zapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@ pragma solidity ^0.8.17;
interface IERC20Zapper {
function deposit(uint256 tokenInAmount, address receiver) external returns (uint256 tokenOutAmount);

function depositWithPermit(uint256 tokenInAmount, address receiver, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
returns (uint256 tokenOutAmount);

function depositWithReferral(uint256 tokenInAmount, address receiver, uint256 referralCode)
external
returns (uint256 tokenOutAmount);

function depositWithReferralAndPermit(
uint256 tokenInAmount,
address receiver,
uint256 referralCode,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 tokenOutAmount);
}
14 changes: 14 additions & 0 deletions contracts/zappers/ERC20DepositZapper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: GPL-2.0-or-later
// Gearbox Protocol. Generalized leverage for DeFi protocols
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;

import {DepositTrait} from "./traits/DepositTrait.sol";
import {ERC20Trait} from "./traits/ERC20Trait.sol";
import {ZapperBase} from "./ZapperBase.sol";

/// @title ERC20 deposit zapper
/// @notice Zapper that allows to deposit an ERC20 token into a pool in one call using permit
contract ERC20DepositZapper is ERC20Trait, DepositTrait {
constructor(address pool) ZapperBase(pool) {}
}
33 changes: 33 additions & 0 deletions contracts/zappers/ERC20ZapperBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// (c) Gearbox Foundation, 2023.
pragma solidity ^0.8.17;

import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {ZapperBase} from "./ZapperBase.sol";
import {IERC20Zapper} from "../interfaces/zappers/IERC20Zapper.sol";

Expand All @@ -18,11 +19,43 @@ abstract contract ERC20ZapperBase is ZapperBase, IERC20Zapper {
tokenOutAmount = _deposit(tokenInAmount, receiver, false, 0);
}

/// @notice Performs deposit zap using signed EIP-2612 permit message for input token:
/// - receives `tokenInAmount` of `tokenIn` from `msg.sender` and converts it to `underlying`
/// - deposits `underlying` into `pool`
/// - converts `pool`'s shares to `tokenOutAmount` of `tokenOut` and sends it to `receiver`
/// @dev `v`, `r`, `s` must be a valid signature of the permit message from `msg.sender` for `tokenIn` to this contract
function depositWithPermit(uint256 tokenInAmount, address receiver, uint256 deadline, uint8 v, bytes32 r, bytes32 s)
external
returns (uint256 tokenOutAmount)
{
_permitTokenIn(tokenInAmount, deadline, v, r, s);
tokenOutAmount = _deposit(tokenInAmount, receiver, false, 0);
}

/// @notice Same as `deposit` but allows specifying the `referralCode` when depositing into the pool
function depositWithReferral(uint256 tokenInAmount, address receiver, uint256 referralCode)
external
returns (uint256 tokenOutAmount)
{
tokenOutAmount = _deposit(tokenInAmount, receiver, true, referralCode);
}

/// @notice Same as `depositWithPermit` but allows specifying the `referralCode` when depositing into the pool
function depositWithReferralAndPermit(
uint256 tokenInAmount,
address receiver,
uint256 referralCode,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external returns (uint256 tokenOutAmount) {
_permitTokenIn(tokenInAmount, deadline, v, r, s);
tokenOutAmount = _deposit(tokenInAmount, receiver, true, referralCode);
}

/// @dev Executes `tokenIn` permit from `msg.sender` to this contract
function _permitTokenIn(uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) internal {
try IERC20Permit(tokenIn()).permit(msg.sender, address(this), amount, deadline, v, r, s) {} catch {}
}
}

0 comments on commit dd8e14d

Please sign in to comment.