Skip to content

Commit

Permalink
import package for reference tests + feat/remove-allowed-token-entrie…
Browse files Browse the repository at this point in the history
…s-on-contract + dev notes + basic test setup in foundry
  • Loading branch information
livingrockrises committed May 11, 2023
1 parent 8307da6 commit b4ac466
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 58 deletions.
45 changes: 3 additions & 42 deletions contracts/token/BiconomyTokenPaymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import "../utils/Exec.sol";
import {TokenPaymasterErrors} from "../common/Errors.sol";
import "@openzeppelin/contracts/utils/Address.sol";

// todo add revert codes in errors. structure Errors.sol
// todo add try and catch for certain flows (call/static call and if else based on success and fallback)
// todo add more revert codes in errors. structure Errors.sol
// todo formal verification
// todo add and review natspecs

Expand Down Expand Up @@ -62,10 +61,6 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste

uint256 private constant SIGNATURE_OFFSET = 181;

// review
// notice: Since it's always verified by the signing service, below gated mapping state could be avoided.
mapping(address => bool) private supportedTokens;

// Owned contract that manages chainlink price feeds (token / eth formaat) and helper to give exchange rate (inverse price)
IOracleAggregator public oracleAggregator;

Expand Down Expand Up @@ -105,16 +100,6 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
address indexed _newfeeReceiver,
address indexed _actor
);

/**
* Designed to enable the community to track change in supported ERC20 tokens. Note that a token supported earlier
* can be denied*/
event TokenSupportedOrRevoked(
address indexed _token,
bool indexed _allowed,
address indexed _actor
);


/**
* Designed to enable tracking how much fees were charged from the sender and in which ERC20 token
Expand Down Expand Up @@ -192,20 +177,6 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste

}

/**
* @dev Allow a new token or revoke previously enabled ERC20 token.
* Can only be called by the owner of the contract.
* @param _token ERC20 address
* @param _allowed if new token is being allowed it will be true, for revoking already supported token it will be false
* @notice If _token is set to zero address, it will revert with an error.
* After allow/deny of the token, it will emit an event TokenSupportedOrRevoked.
*/
function setTokenAllowed(address _token, bool _allowed) external payable onlyOwner {
require(_token != address(0), "Token address cannot be zero");
supportedTokens[_token] = _allowed;
emit TokenSupportedOrRevoked(_token, _allowed, msg.sender);
}

/**
* @dev Set a new overhead for unaccounted cost
* Can only be called by the owner of the contract.
Expand Down Expand Up @@ -241,16 +212,6 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
entryPoint.withdrawTo(withdrawAddress, amount);
}

/**
* @dev Returns true if this contract supports the given fee token address.
* @param _token ERC20 token address
*/
function isSupportedToken(
address _token
) public view virtual returns (bool) {
return supportedTokens[_token];
}

/**
* @dev Returns the exchange price of the token in wei.
*/
Expand Down Expand Up @@ -370,8 +331,6 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste

address account = userOp.getSender();

require(isSupportedToken(feeToken), "TokenPaymaster: token is not supported as fee token") ;

uint256 costOfPost = userOp.maxFeePerGas * UNACCOUNTED_COST; // unaccountedEPGasOverhead

// This model assumes irrespective of priceSource exchangeRate is always sent from outside
Expand Down Expand Up @@ -432,12 +391,14 @@ contract BiconomyTokenPaymaster is BasePaymaster, ReentrancyGuard, TokenPaymaste
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
// instead of require could emit an event TokenPaymentDue()
// sender could be banned indefinitely or for certain period
}
emit TokenPaymasterOperation(account, address(feeToken), actualTokenCost + fee, fee, userOpHash, effectiveExchangeRate, priceSource);
}
// there could be else bit acting as deposit paymaster
else {
//in case above transferFrom failed, pay with deposit / notify at least
//sender could be banned indefinitely or for certain period
}
}

Expand Down
3 changes: 2 additions & 1 deletion contracts/token/oracles/OracleAggregator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
pragma solidity 0.8.17;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./IOracleAggregator.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

contract OracleAggregator is Ownable{
contract OracleAggregator is Ownable, IOracleAggregator{

struct TokenInfo {
/* Number of decimals represents the precision of the price returned by the feed. For example,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"@ethersproject/constants": "^5.6.1",
"@openzeppelin/contracts": "4.8.1",
"@openzeppelin/contracts-upgradeable": "4.8.1",
"@pimlico/erc20-paymaster": "^0.0.1",
"@types/mocha": "^9.0.0",
"chai-as-promised": "^7.1.1",
"chai-string": "^1.5.0",
Expand Down
4 changes: 0 additions & 4 deletions scripts/deploy-token-paymaster-mumbai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ async function main() {
receipt = await tx.wait();
console.log("Oracle set for USDC");

tx = await tokenPaymaster.setTokenAllowed(usdcAddress, true);
receipt = await tx.wait();
console.log("Token is marked allowed");

tx = await tokenPaymaster.transferOwnership(owner);
receipt = await tx.wait();
console.log("ownership transferred: Token Paymaster");
Expand Down
4 changes: 0 additions & 4 deletions scripts/deploy-token-paymaster-polygon-mainnet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ async function main() {
receipt = await tx.wait();
console.log("Oracle set for USDC");

tx = await tokenPaymaster.setTokenAllowed(usdcAddress, true);
receipt = await tx.wait();
console.log("Token is marked allowed");

await delay(5000)

tx = await tokenPaymaster.transferOwnership(owner);
Expand Down
63 changes: 63 additions & 0 deletions test/foundry/TokenPaymaster.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: Unlicense
pragma solidity >=0.8.0;

import {DSTest} from "ds-test/test.sol";
import {OracleAggregator} from "../../contracts/token/oracles/OracleAggregator.sol";
import {IOracleAggregator} from "../../contracts/token/oracles/IOracleAggregator.sol";
import {BiconomyTokenPaymaster} from "../../contracts/token/BiconomyTokenPaymaster.sol";
import "@account-abstraction/contracts/core/EntryPoint.sol";
import {Utilities} from "./utils/Utilities.sol";
import {console} from "./utils/Console.sol";
import {Vm} from "forge-std/Vm.sol";

contract ContractTest is DSTest {
Vm internal immutable vm = Vm(HEVM_ADDRESS);

Utilities internal utils;
address payable[] internal users;

OracleAggregator _oa;
BiconomyTokenPaymaster _btpm;
EntryPoint _ep;

function setUp() public {
utils = new Utilities();
users = utils.createUsers(5);
}

function testCreateOA() public {

address payable alice = users[0];
// labels alice's address in call traces as "Alice [<address>]"
vm.label(alice, "Alice");

address payable bob = users[1];
vm.label(bob, "Bob");

_oa = new OracleAggregator(alice);

assertEq(_oa.owner(),alice);

vm.prank(alice);
}

function testCreateTokenPaymaster() public {

address payable alice = users[0];
// labels alice's address in call traces as "Alice [<address>]"
vm.label(alice, "Alice");

address payable bob = users[1];
vm.label(bob, "Bob");

_oa = new OracleAggregator(alice);
_ep = new EntryPoint();
_btpm = new BiconomyTokenPaymaster(alice, _ep, bob, _oa);

assertEq(_oa.owner(),alice);
assertEq(_btpm.owner(),alice);
assertEq(_btpm.verifyingSigner(),bob);

vm.prank(alice);
}
}
2 changes: 0 additions & 2 deletions test/token-paymaster/biconomy-token-paymaster-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ describe("Biconomy Token Paymaster", function () {
oracleAggregator.address
);

await sampleTokenPaymaster.setTokenAllowed(token.address, true);

smartWalletImp = await new BiconomyAccountImplementation__factory(deployer).deploy(
entryPoint.address
);
Expand Down
2 changes: 0 additions & 2 deletions test/token-paymaster/btpm-undeployed-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ describe("Biconomy Token Paymaster", function () {
oracleAggregator.address
);

await sampleTokenPaymaster.setTokenAllowed(token.address, true);

smartWalletImp = await new BiconomyAccountImplementation__factory(deployer).deploy(
entryPoint.address
);
Expand Down
25 changes: 22 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -978,7 +978,7 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.1.tgz#709cfc4bbb3ca9f4460d60101f15dac6b7a2d5e4"
integrity sha512-xQ6eUZl+RDyb/FiZe1h+U7qr/f4p/SrTSQcTPH2bjur3C5DbuW/zFgCU/b1P/xcIaEqJep+9ju4xDRi3rmChdQ==

"@openzeppelin/contracts@^4.7.3":
"@openzeppelin/contracts@^4.7.3", "@openzeppelin/contracts@^4.8.2":
version "4.8.3"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.3.tgz#cbef3146bfc570849405f59cba18235da95a252a"
integrity sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==
Expand All @@ -988,6 +988,20 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.3.tgz#ff6ee919fc2a1abaf72b22814bfb72ed129ec137"
integrity sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g==

"@pimlico/erc20-paymaster@^0.0.1":
version "0.0.1"
resolved "https://registry.yarnpkg.com/@pimlico/erc20-paymaster/-/erc20-paymaster-0.0.1.tgz#d9c827f3f6c2c553870597a5dc3e1398967d7790"
integrity sha512-L7xJce76sxUK88lFqKI0J1BiQRa9cgj233Qke3rEOCzncG8Gl4Lx+/89/jWiqNbdyfHtjD4Dn2PKLyBj27ypxg==
dependencies:
"@account-abstraction/contracts" "^0.6.0"
"@account-abstraction/utils" "^0.5.0"
"@ethersproject/abstract-provider" "^5.7.0"
"@ethersproject/providers" "^5.7.2"
"@openzeppelin/contracts" "^4.8.2"
ethers "^5.7.2"
hardhat "^2.13.0"
solady "^0.0.90"

"@scure/base@~1.1.0":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
Expand Down Expand Up @@ -3251,7 +3265,7 @@ ethers@^4.0.40:
uuid "2.0.1"
xmlhttprequest "1.8.0"

ethers@^5.6.8, ethers@^5.7.0, ethers@^5.7.1:
ethers@^5.6.8, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2:
version "5.7.2"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==
Expand Down Expand Up @@ -4016,7 +4030,7 @@ hardhat-gas-reporter@^1.0.7:
eth-gas-reporter "^0.2.25"
sha1 "^1.1.1"

hardhat@^2.9.5:
hardhat@^2.13.0, hardhat@^2.9.5:
version "2.14.0"
resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.14.0.tgz#b60c74861494aeb1b50803cf04cc47865a42b87a"
integrity sha512-73jsInY4zZahMSVFurSK+5TNCJTXMv+vemvGia0Ac34Mm19fYp6vEPVGF3sucbumszsYxiTT2TbS8Ii2dsDSoQ==
Expand Down Expand Up @@ -6403,6 +6417,11 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"

solady@^0.0.90:
version "0.0.90"
resolved "https://registry.yarnpkg.com/solady/-/solady-0.0.90.tgz#2075349dfa6909b05ed04031f3b609ddbcd73598"
integrity sha512-NSc0mkfJo2CeKfFfyED1qbBQ8ofvDFxpBb0BLJ/wx2ZN7vCAYl8sp/j6TIIMdPb0BDvOKl2Rie9dVum+KIKeVA==

[email protected]:
version "0.7.3"
resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a"
Expand Down

0 comments on commit b4ac466

Please sign in to comment.