Skip to content

Commit

Permalink
set up base + dev notes
Browse files Browse the repository at this point in the history
  • Loading branch information
livingrockrises committed May 11, 2023
1 parent 8307da6 commit 50e87ac
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 8 deletions.
12 changes: 12 additions & 0 deletions contracts/test/TestUniV3Contract.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol';

contract UniV3Integration {
ISwapRouter router;

function doSomethingWithSwapRouter() public {
// router.exactInput(...);
}
}
25 changes: 22 additions & 3 deletions contracts/token/BiconomyTokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
// Owned contract that manages chainlink price feeds (token / eth formaat) and helper to give exchange rate (inverse price)
IOracleAggregator public oracleAggregator;

// todo: possibly add interface later
address public swapAdapter1; // named 1 for now

/**
* Designed to enable the community to track change in storage variable UNACCOUNTED_COST which is used
* to maintain gas execution cost which can't be calculated within contract*/
Expand Down Expand Up @@ -125,9 +128,10 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
address _owner,
IEntryPoint _entryPoint,
address _verifyingSigner,
IOracleAggregator _oracleAggregator
// potentially take router param as well
// optionally get fee receiver if we need to (can always set after deploying!)
IOracleAggregator _oracleAggregator,
address _1inchAggregationRouter
// ^ let's pick 1inch here for swapping on eligible chains
// 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE // by default unsupported
) payable BasePaymaster(_owner, _entryPoint) {
if(_owner == address(0)) revert OwnerCannotBeZero();
if (address(_entryPoint) == address(0)) revert EntryPointCannotBeZero();
Expand All @@ -137,9 +141,15 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
sstore(verifyingSigner.slot, _verifyingSigner)
sstore(oracleAggregator.slot, _oracleAggregator)
sstore(feeReceiver.slot, address()) // initialize with self (could also be _owner)
sstore(swapAdapter1.slot, _1inchAggregationRouter) // valid only if supported
}
}

// if needful
function set1InchAdapter(address _newVerifyingSigner) external payable onlyOwner {

}

/**
* @dev Set a new verifying signer address.
* Can only be called by the owner of the contract.
Expand Down Expand Up @@ -258,6 +268,7 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
address _token
) public view virtual returns (uint256 exchangeRate) {
// get price from oracle aggregator.
// todo: from adapter TWAP oracle POV this would need more than token address, like price source
bytes memory _data = abi.encodeWithSelector(IOracleAggregator.getTokenValueOfOneEth.selector, _token);
(bool success, bytes memory returndata) = address(oracleAggregator).staticcall(_data);
exchangeRate = 0;
Expand All @@ -266,6 +277,14 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
}
}

// returns success and possibly amount and emits event
function swapTokenForETHAndDeposit(address _token, bytes memory _calldata) public /*returns*/{
// only proceed if adapter is not '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
// make approval to router
// 1InchAdapter.call(calldata)..
// entrypoint.depositTo
}

/**
* @dev pull tokens out of paymaster in case they were sent to the paymaster at any point.
* @param token the token deposit to withdraw
Expand Down
99 changes: 99 additions & 0 deletions contracts/token/adapters/UniswapExample.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
pragma abicoder v2;

import "@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol";
import "@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol";

interface IUniswapRouter is ISwapRouter {
function refundETH() external payable;
}

contract Uniswap3 {
IUniswapRouter public constant uniswapRouter = IUniswapRouter(0xE592427A0AEce92De3Edee1F18E0157C05861564);
IQuoter public constant quoter = IQuoter(0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6);
address private constant multiDaiKovan = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
address private constant WETH9 = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;

function convertExactEthToDai() external payable {
require(msg.value > 0, "Must pass non 0 ETH amount");

uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
address tokenIn = WETH9;
address tokenOut = multiDaiKovan;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountIn = msg.value;
uint256 amountOutMinimum = 1;
uint160 sqrtPriceLimitX96 = 0;

ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountIn,
amountOutMinimum,
sqrtPriceLimitX96
);

uniswapRouter.exactInputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();

// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}

function convertEthToExactDai(uint256 daiAmount) external payable {
require(daiAmount > 0, "Must pass non 0 DAI amount");
require(msg.value > 0, "Must pass non 0 ETH amount");

uint256 deadline = block.timestamp + 15; // using 'now' for convenience, for mainnet pass deadline from frontend!
address tokenIn = WETH9;
address tokenOut = multiDaiKovan;
uint24 fee = 3000;
address recipient = msg.sender;
uint256 amountOut = daiAmount;
uint256 amountInMaximum = msg.value;
uint160 sqrtPriceLimitX96 = 0;

ISwapRouter.ExactOutputSingleParams memory params = ISwapRouter.ExactOutputSingleParams(
tokenIn,
tokenOut,
fee,
recipient,
deadline,
amountOut,
amountInMaximum,
sqrtPriceLimitX96
);

uniswapRouter.exactOutputSingle{ value: msg.value }(params);
uniswapRouter.refundETH();

// refund leftover ETH to user
(bool success,) = msg.sender.call{ value: address(this).balance }("");
require(success, "refund failed");
}

// do not used on-chain, gas inefficient!
function getEstimatedETHforDAI(uint daiAmount) external payable returns (uint256) {
address tokenIn = WETH9;
address tokenOut = multiDaiKovan;
uint24 fee = 3000;
uint160 sqrtPriceLimitX96 = 0;

return quoter.quoteExactOutputSingle(
tokenIn,
tokenOut,
fee,
daiAmount,
sqrtPriceLimitX96
);
}

// important to receive ETH
receive() payable external {}
}
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,13 @@
"@chainlink/contracts": "^0.6.0",
"@ethersproject/abstract-signer": "^5.6.2",
"@ethersproject/constants": "^5.6.1",
"@mean-finance/uniswap-v3-oracle": "^1.0.3",
"@openzeppelin/contracts": "4.8.1",
"@openzeppelin/contracts-upgradeable": "4.8.1",
"@types/mocha": "^9.0.0",
"@uniswap/sdk-core": "^3.2.2",
"@uniswap/universal-router": "^1.4.1",
"@uniswap/v3-periphery": "^1.4.3",
"chai-as-promised": "^7.1.1",
"chai-string": "^1.5.0",
"dotenv": "^16.0.3",
Expand Down
4 changes: 3 additions & 1 deletion scripts/deploy-token-paymaster-mumbai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ async function main() {
const provider = ethers.provider;

const accounts = await ethers.getSigners();
const ZERO_ADDRESS_ROUTER = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'

const earlyOwner = await accounts[0].getAddress();
const owner = "0x7306aC7A32eb690232De81a9FFB44Bb346026faB";
Expand All @@ -31,7 +32,8 @@ async function main() {
earlyOwner,
entryPoint,
verifyingSigner,
oracleAggregator.address
oracleAggregator.address,
ZERO_ADDRESS_ROUTER
);

console.log(`TokenPaymaster deployed at ${tokenPaymaster.address}`);
Expand Down
4 changes: 3 additions & 1 deletion scripts/deploy-token-paymaster-polygon-mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ async function main() {
const provider = ethers.provider;

const gasPrices = {maxFeePerGas: 250e9, maxPriorityFeePerGas: 60e9}
const ZERO_ADDRESS_ROUTER = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'

const accounts = await ethers.getSigners();
const earlyOwner = await accounts[0].getAddress();
Expand Down Expand Up @@ -41,7 +42,8 @@ async function main() {
earlyOwner,
entryPoint,
verifyingSigner,
oracleAggregator.address
oracleAggregator.address,
ZERO_ADDRESS_ROUTER
);

await delay(5000)
Expand Down
5 changes: 4 additions & 1 deletion test/token-paymaster/biconomy-token-paymaster-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
MockToken,
} from "../../typechain-types";

const ZERO_ADDRESS_ROUTER = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'


import { fillAndSign } from "../../account-abstraction/test/UserOp";
import { UserOperation } from "../../account-abstraction/test/UserOperation";
Expand Down Expand Up @@ -150,7 +152,8 @@ describe("Biconomy Token Paymaster", function () {
walletOwnerAddress,
entryPoint.address,
await offchainSigner.getAddress(),
oracleAggregator.address
oracleAggregator.address,
ZERO_ADDRESS_ROUTER
);

await sampleTokenPaymaster.setTokenAllowed(token.address, true);
Expand Down
4 changes: 3 additions & 1 deletion test/token-paymaster/btpm-undeployed-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { createAccount, simulationResultCatch } from "../../account-abstraction/
import { EntryPoint, EntryPoint__factory, SimpleAccount, TestToken, TestToken__factory } from "../../account-abstraction/typechain";

export const AddressZero = ethers.constants.AddressZero;
const ZERO_ADDRESS_ROUTER = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
import { arrayify, hexConcat, parseEther } from "ethers/lib/utils";
import { BigNumber, BigNumberish, Contract, Signer } from "ethers";

Expand Down Expand Up @@ -150,7 +151,8 @@ describe("Biconomy Token Paymaster", function () {
walletOwnerAddress,
entryPoint.address,
await offchainSigner.getAddress(),
oracleAggregator.address
oracleAggregator.address,
ZERO_ADDRESS_ROUTER
);

await sampleTokenPaymaster.setTokenAllowed(token.address, true);
Expand Down
Loading

0 comments on commit 50e87ac

Please sign in to comment.