Skip to content

Commit

Permalink
min eth received param for uniswapper
Browse files Browse the repository at this point in the history
  • Loading branch information
ShivaanshK committed Sep 15, 2024
1 parent 3c7f0ec commit 385823a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 25 deletions.
32 changes: 22 additions & 10 deletions contracts/token/BiconomyTokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import "./swaps/Uniswapper.sol";
* @author ShivaanshK<[email protected]>
* @author livingrockrises<[email protected]>
* @notice Biconomy's Token Paymaster for Entry Point v0.7
* @dev A paymaster that allows user to pay gas fees in ERC20 tokens. The paymaster uses the precharge and refund model
* @dev A paymaster that allows users to pay gas fees in ERC20 tokens. The paymaster uses the precharge and refund
* model
* to handle gas remittances.
*
* Currently, the paymaster supports two modes:
* 1. EXTERNAL - Relies on a quoted token price from a trusted entity (verifyingSigner).
* 2. INDEPENDENT - Relies purely on price oracles (Offchain and TWAP) which implement the IOracle interface. This mode
* doesn't require a signature and is always "available" to use.
* 2. INDEPENDENT - Relies purely on price oracles (Chainlink and TWAP) which implement the IOracle interface. This mode
* doesn't require a signature and is "always available" to use.
*
* The paymaster's owner has full discretion over the supported tokens (for independent mode), price adjustments
* applied, and how
Expand All @@ -51,7 +52,8 @@ contract BiconomyTokenPaymaster is
uint256 public priceMarkup;
uint256 public priceExpiryDuration;
IOracle public nativeAssetToUsdOracle; // ETH -> USD price oracle
mapping(address => TokenInfo) independentTokenDirectory; // mapping of token address => info for tokens supported in independent mode
mapping(address => TokenInfo) independentTokenDirectory; // mapping of token address => info for tokens supported in
// independent mode

// PAYMASTER_ID_OFFSET
uint256 private constant UNACCOUNTED_GAS_LIMIT = 50_000; // Limit for unaccounted gas cost
Expand Down Expand Up @@ -111,7 +113,8 @@ contract BiconomyTokenPaymaster is
// Token -> USD will always have 8 decimals
revert InvalidOracleDecimals();
}
independentTokenDirectory[_independentTokens[i]] = TokenInfo(_oracles[i], 10 ** IERC20Metadata(_independentTokens[i]).decimals());
independentTokenDirectory[_independentTokens[i]] =
TokenInfo(_oracles[i], 10 ** IERC20Metadata(_independentTokens[i]).decimals());
}
}

Expand Down Expand Up @@ -332,14 +335,23 @@ contract BiconomyTokenPaymaster is
* @dev Swap a token in the paymaster for ETH and deposit the amount received into the entry point
* @param _tokenAddress The token address of the token to swap
* @param _tokenAmount The amount of the token to swap
* @param _minEthAmountRecevied The minimum amount of ETH amount recevied post-swap
* @notice only to be called by the owner of the contract.
*/
function swapTokenAndDeposit(address _tokenAddress, uint256 _tokenAmount) external payable onlyOwner {
// Swap tokens
uint256 amountOut = _swapTokenToWeth(_tokenAddress, _tokenAmount);
function swapTokenAndDeposit(
address _tokenAddress,
uint256 _tokenAmount,
uint256 _minEthAmountRecevied
)
external
payable
onlyOwner
{
// Swap tokens for WETH
uint256 amountOut = _swapTokenToWeth(_tokenAddress, _tokenAmount, _minEthAmountRecevied);
// Unwrap WETH to ETH
unwrapWeth(amountOut);
// Deposit into EP
_unwrapWeth(amountOut);
// Deposit ETH into EP
entryPoint.depositTo{ value: amountOut }(address(this));
}

Expand Down
24 changes: 9 additions & 15 deletions contracts/token/swaps/Uniswapper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-periphery/contracts/interfaces/IPeripheryPayments.sol";

/**
* @title Uniswapper
* @author ShivaanshK<[email protected]>
* @notice An abstract contract to assist the paymaster in swapping tokens to WETH and unwrapping WETH
* @notice Based on Infinitism's Uniswap Helper contract
*/
abstract contract Uniswapper {
uint256 private constant SWAP_PRICE_DENOMINATOR = 1e26;

Expand Down Expand Up @@ -46,33 +52,21 @@ abstract contract Uniswapper {
tokenToPools[_token] = _poolFeeTier; // set mapping of token to uniswap pool to use for swap
}

function _swapTokenToWeth(address _tokenIn, uint256 _amountIn) internal returns (uint256) {
function _swapTokenToWeth(address _tokenIn, uint256 _amountIn, uint256 _minAmountOut) internal returns (uint256) {
ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({
tokenIn: _tokenIn,
tokenOut: wrappedNative,
fee: tokenToPools[_tokenIn],
recipient: address(this),
deadline: block.timestamp,
amountIn: _amountIn,
amountOutMinimum: 0,
amountOutMinimum: _minAmountOut,
sqrtPriceLimitX96: 0
});
return uniswapRouter.exactInputSingle(params);
}

function addSlippage(uint256 amount, uint8 slippage) private pure returns (uint256) {
return amount * (1000 - slippage) / 1000;
}

function tokenToWei(uint256 amount, uint256 price) public pure returns (uint256) {
return amount * price / SWAP_PRICE_DENOMINATOR;
}

function weiToToken(uint256 amount, uint256 price) public pure returns (uint256) {
return amount * SWAP_PRICE_DENOMINATOR / price;
}

function unwrapWeth(uint256 _amount) internal {
function _unwrapWeth(uint256 _amount) internal {
IPeripheryPayments(address(uniswapRouter)).unwrapWETH9(_amount, address(this));
}
}

0 comments on commit 385823a

Please sign in to comment.