diff --git a/contracts/token/BiconomyTokenPaymaster.sol b/contracts/token/BiconomyTokenPaymaster.sol index f898a46..e364d7d 100644 --- a/contracts/token/BiconomyTokenPaymaster.sol +++ b/contracts/token/BiconomyTokenPaymaster.sol @@ -223,16 +223,6 @@ contract BiconomyTokenPaymaster is entryPoint.withdrawTo(withdrawAddress, amount); } - /** - * @dev Returns the exchange price of the token in wei. - * @param _token ERC20 token address - */ - function exchangePrice( - address _token - ) internal view virtual returns (uint256 exchangeRate) { - exchangeRate = getTokenValueOfOneNativeToken(_token); - } - /** * @dev pull tokens out of paymaster in case they were sent to the paymaster at any point. * @param token the token deposit to withdraw @@ -572,22 +562,16 @@ contract BiconomyTokenPaymaster is userOpHash := calldataload(offset) } - // console.log("gas used for context decode: %s", gas - gasleft()); - - // console.log("account: %s", account); - // console.log("feeToken: %s", address(feeToken)); - // console.log("priceSource: %s", uint8(priceSource)); - // console.log("exchangeRate: %s", exchangeRate); - // console.log("priceMarkup: %s", priceMarkup); - // console.log("userOpHash: %s", uint256(userOpHash)); uint256 effectiveExchangeRate = exchangeRate; if ( priceSource == ExchangeRateSource.ORACLE_BASED ) { - uint256 result = exchangePrice(address(feeToken)); - if (result != 0) effectiveExchangeRate = result; + effectiveExchangeRate = getTokenValueOfOneNativeToken(address(feeToken)); + // uint256 result = getTokenValueOfOneNativeToken(address(feeToken)); + // Review + // if (result != 0) effectiveExchangeRate = result; } // We could either touch the state for BASEFEE and calculate based on maxPriorityFee passed (to be added in context along with maxFeePerGas) or just use tx.gasprice diff --git a/lib/scw-contracts b/lib/scw-contracts index 440132a..44fdb23 160000 --- a/lib/scw-contracts +++ b/lib/scw-contracts @@ -1 +1 @@ -Subproject commit 440132aeccbe073a45442104939e19d807439c9d +Subproject commit 44fdb23b2d811d78523a6767ce8da7fdd2879412 diff --git a/test/foundry/base/SATestBase.sol b/test/foundry/base/SATestBase.sol index 31c9c7a..4bbf6c3 100644 --- a/test/foundry/base/SATestBase.sol +++ b/test/foundry/base/SATestBase.sol @@ -268,19 +268,27 @@ abstract contract SATestBase is Test { TestAccount memory _signer, bytes memory _pnd ) internal view returns (UserOperation memory op) { + { op = UserOperation({ sender: address(_sa), nonce: entryPoint.getNonce(address(_sa), _nonceKey), initCode: bytes(""), callData: _calldata, - callGasLimit: gasleft() / 100, - verificationGasLimit: gasleft() / 100, - preVerificationGas: defaultPreVerificationGas, - maxFeePerGas: tx.gasprice, - maxPriorityFeePerGas: tx.gasprice - block.basefee, + // Review: If left to this some test fail + // callGasLimit: gasleft() / 100, + // verificationGasLimit: gasleft() / 100, + // preVerificationGas: defaultPreVerificationGas, + // maxFeePerGas: tx.gasprice, + // maxPriorityFeePerGas: tx.gasprice - block.basefee, + callGasLimit: 100000, + verificationGasLimit: 200000, + preVerificationGas: 50000, + maxFeePerGas: 100000000000, + maxPriorityFeePerGas: 40000000000, paymasterAndData: _pnd, signature: bytes("") }); + } // Sign the UserOp bytes32 userOpHash = entryPoint.getUserOpHash(op); diff --git a/test/foundry/token-paymaster/TokenPaymaster.t.sol b/test/foundry/token-paymaster/TokenPaymaster.t.sol index 2f41443..12b8c92 100644 --- a/test/foundry/token-paymaster/TokenPaymaster.t.sol +++ b/test/foundry/token-paymaster/TokenPaymaster.t.sol @@ -11,6 +11,7 @@ import "../../BytesLib.sol"; import "../../../contracts/test/helpers/TestCounter.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IEntryPoint} from "@account-abstraction/contracts/interfaces/IEntryPoint.sol"; import {UserOperation} from "@account-abstraction/contracts/interfaces/UserOperation.sol"; import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; @@ -28,17 +29,19 @@ error SetupIncomplete(); using ECDSA for bytes32; contract TokenPaymasterTest is SATestBase { - SmartAccount sa; + SmartAccount public sa; uint256 internal keyUser; uint256 internal keyVerifyingSigner; + address internal usdcMaticFeed = 0x000005ABaE3DEAdbe1FBD12105F950efbA9eaec4; BiconomyTokenPaymaster public _btpm; - MockToken usdc; - MockPriceFeed usdcMaticFeed; - TestCounter counter; + IERC20 public usdc = IERC20(0xdA5289fCAAF71d52a80A254da614a192b693e977); + TestCounter public counter; function setUp() public virtual override { + uint256 forkId = vm.createFork("https://polygon-mumbai.g.alchemy.com/v2/zX14dLXhTQqeK4LG2pNUsk7Gcet8iPXJ"); + vm.selectFork(forkId); super.setUp(); // Deploy Smart Account with default module @@ -52,27 +55,21 @@ contract TokenPaymasterTest is SATestBase { smartAccountDeploymentIndex, "aliceSA" ); + console2.log("SA address", address(sa)); keyUser = alice.privateKey; keyVerifyingSigner = bob.privateKey; _btpm = new BiconomyTokenPaymaster(alice.addr, entryPoint, bob.addr); - usdc = new MockToken(); - usdcMaticFeed = new MockPriceFeed(); counter = new TestCounter(); - // setting price oracle for token - bytes memory _data = abi.encodeWithSelector( - FeedInterface.getThePrice.selector - ); - vm.startPrank(alice.addr); // could also make a .call using selector and handle success _btpm.setTokenOracle( address(usdc), 18, - usdc.decimals(), - address(usdcMaticFeed), + ERC20(address(usdc)).decimals(), + usdcMaticFeed, true ); vm.stopPrank(); @@ -87,9 +84,6 @@ contract TokenPaymasterTest is SATestBase { vm.startPrank(charlie.addr); entryPoint.depositTo{value: 2 ether}(address(_btpm)); - // mint tokens to addresses - usdc.mint(charlie.addr, 100e6); - usdc.mint(accountAddress, 100e6); vm.stopPrank(); vm.warp(1680509051); } @@ -122,7 +116,7 @@ contract TokenPaymasterTest is SATestBase { function testWithdrawERC20(uint256 _amount) external { vm.assume(_amount < usdc.totalSupply()); - usdc.mint(address(_btpm), _amount); + deal(address(usdc), address(_btpm), _amount); vm.startPrank(alice.addr); _btpm.withdrawERC20(usdc, dan.addr, _amount); assertEq(usdc.balanceOf(address(_btpm)), 0); @@ -132,7 +126,7 @@ contract TokenPaymasterTest is SATestBase { function testWithdrawERC20FailNotOwner(uint256 _amount) external { vm.assume(_amount < usdc.totalSupply()); - usdc.mint(address(_btpm), _amount); + deal(address(usdc), address(_btpm), _amount); vm.startPrank(dan.addr); vm.expectRevert("Ownable: caller is not the owner"); _btpm.withdrawERC20(usdc, dan.addr, _amount); @@ -142,6 +136,7 @@ contract TokenPaymasterTest is SATestBase { // sanity check for everything works without paymaster function testCall() external { vm.deal(address(sa), 1e18); + vm.deal(dan.addr, 1e18); bytes memory data = getSmartAccountExecuteCalldata( address(counter), @@ -162,12 +157,17 @@ contract TokenPaymasterTest is SATestBase { // with token paymaster function testTokenPaymasterRefund() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) ); + console2.log( + "SA token balance before ", + usdc.balanceOf(address(sa)) + ); + console2.log("nonce from EP", entryPoint.getNonce(address(sa), 0)); bytes memory data = getSmartAccountExecuteCalldata( address(usdc), @@ -221,8 +221,10 @@ contract TokenPaymasterTest is SATestBase { function testTokenPaymasterFailInvalidPaymasteDataLength() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(sa), 100e6); + deal(address(usdc), address(_btpm), 100e6); + + console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) @@ -245,8 +247,8 @@ contract TokenPaymasterTest is SATestBase { function test2TokenPaymasterFailInvalidPaymasteDataLength() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(_btpm), 100e6); + deal(address(usdc), address(sa), 100e6); console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) @@ -276,8 +278,8 @@ contract TokenPaymasterTest is SATestBase { function testTokenPaymasterFailInvalidPMSignature() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(_btpm), 100e6); + deal(address(usdc), address(sa), 100e6); console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) @@ -321,8 +323,8 @@ contract TokenPaymasterTest is SATestBase { function testTokenPaymasterFailWrongPMSignature() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(_btpm), 100e6); + deal(address(usdc), address(sa), 100e6); console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) @@ -373,8 +375,8 @@ contract TokenPaymasterTest is SATestBase { function testTokenPaymasterFailHighPriceMarkup() external { vm.deal(address(sa), 1e18); - usdc.mint(address(sa), 100e6); // 100 usdc; - usdc.mint(address(_btpm), 100e6); // 100 usdc; + deal(address(usdc), address(_btpm), 100e6); + deal(address(usdc), address(sa), 100e6); console2.log( "paymaster balance before ", usdc.balanceOf(address(_btpm)) diff --git a/test/token-paymaster/biconomy-token-paymaster-specs.ts b/test/token-paymaster/biconomy-token-paymaster-specs.ts index c5d4c1b..7668fc2 100644 --- a/test/token-paymaster/biconomy-token-paymaster-specs.ts +++ b/test/token-paymaster/biconomy-token-paymaster-specs.ts @@ -341,6 +341,7 @@ describe("Biconomy Token Paymaster", function () { const postBalance = await token.balanceOf(paymasterAddress); const postTokenBalanceForAccount = await token.balanceOf(walletAddress); + expect(postTokenBalanceForAccount).to.be.lt(preTokenBalanceForAccount); const ev = await getUserOpEvent(entryPoint); expect(ev.args.success).to.be.true;