Skip to content

Commit

Permalink
update paymaster
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeExplorer29 committed Jan 8, 2024
1 parent 02fdece commit db422fa
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 79 deletions.
2 changes: 1 addition & 1 deletion contracts/dev/TestOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ contract TestOracle {
view
returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)
{
return (110680464442257311610, 190355094900, 1685339747, block.timestamp, 110680464442257311610);
return (110680464442257311610, price, 1685339747, block.timestamp, 110680464442257311610);
}
}
28 changes: 18 additions & 10 deletions contracts/paymaster/ERC20Paymaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ contract ERC20Paymaster is BasePaymaster {

address public immutable WALLET_FACTORY;

IOracle public nativeAssetOracle;

mapping(address => TokenSetting) public supportedToken;

event ConfigUpdated(address token, address oracle, uint32 priceMarkup);
Expand All @@ -48,6 +50,11 @@ contract ERC20Paymaster is BasePaymaster {
WALLET_FACTORY = _walletFactory;
}

function setNativeAssetOracle(address _oracle) external onlyOwner {
require(_oracle != address(0), "Paymaster: invalid oracle addr");
nativeAssetOracle = IOracle(_oracle);
}

function setToken(address[] calldata _tokens, address[] calldata _tokenOracles, uint32[] calldata _priceMarkups)
external
onlyOwner
Expand All @@ -66,7 +73,7 @@ contract ERC20Paymaster is BasePaymaster {
require(IOracle(_tokenOracle).decimals() == 8, "Paymaster: token oracle decimals must be 8");
supportedToken[_token].priceMarkup = _priceMarkup;
supportedToken[_token].tokenOracle = IOracle(_tokenOracle);
supportedToken[_token].tokenDecimals = IERC20Metadata(_token).decimals();
supportedToken[_token].tokenDecimals = 10 ** IERC20Metadata(_token).decimals();
emit ConfigUpdated(_token, _tokenOracle, _priceMarkup);
}
}
Expand All @@ -78,7 +85,9 @@ contract ERC20Paymaster is BasePaymaster {
function updatePrice(address token) external {
require(isSupportToken(token), "Paymaster: token not support");
uint192 tokenPrice = fetchPrice(supportedToken[token].tokenOracle);
supportedToken[token].previousPrice = tokenPrice;
uint192 nativeAssetPrice = fetchPrice(nativeAssetOracle);
supportedToken[token].previousPrice =
nativeAssetPrice * uint192(supportedToken[token].tokenDecimals) / tokenPrice;
}

function isSupportToken(address token) public view returns (bool) {
Expand All @@ -104,12 +113,9 @@ contract ERC20Paymaster is BasePaymaster {
uint256 cachedPrice = supportedToken[token].previousPrice;
require(cachedPrice != 0, "Paymaster: price not set");

uint256 exchangeRate = (cachedPrice * 10 ** supportedToken[token].tokenDecimals) / 10 ** 8;
// tokenRequiredPreFund = requiredPreFund * exchangeRate / 10^18

uint256 costOfPost = userOp.gasPrice() * COST_OF_POST;

uint256 tokenRequiredPreFund = (requiredPreFund + costOfPost) * supportedToken[token].priceMarkup * exchangeRate
uint256 tokenRequiredPreFund = (requiredPreFund + costOfPost) * supportedToken[token].priceMarkup * cachedPrice
/ (1e18 * PRICE_DENOMINATOR);

require(tokenRequiredPreFund <= maxCost, "Paymaster: maxCost too low");
Expand All @@ -128,7 +134,7 @@ contract ERC20Paymaster is BasePaymaster {
sponsorWalletCreation = false;
}

return (abi.encode(sender, token, costOfPost, exchangeRate, tokenRequiredPreFund, sponsorWalletCreation), 0);
return (abi.encode(sender, token, costOfPost, cachedPrice, tokenRequiredPreFund, sponsorWalletCreation), 0);
}

/*
Expand Down Expand Up @@ -188,12 +194,12 @@ contract ERC20Paymaster is BasePaymaster {
address sender,
address payable token,
uint256 costOfPost,
uint256 exchangeRate,
uint256 cachedPrice,
uint256 tokenRequiredPreFund,
bool sponsorWalletCreation
) = abi.decode(context, (address, address, uint256, uint256, uint256, bool));
uint256 tokenRequiredFund =
(actualGasCost + costOfPost) * supportedToken[token].priceMarkup * exchangeRate / (1e18 * PRICE_DENOMINATOR);
(actualGasCost + costOfPost) * supportedToken[token].priceMarkup * cachedPrice / (1e18 * PRICE_DENOMINATOR);
if (sponsorWalletCreation) {
// if sponsor during wallet creatation, charge the acutal amount
IERC20Metadata(token).safeTransferFrom(sender, address(this), tokenRequiredPreFund);
Expand All @@ -203,7 +209,9 @@ contract ERC20Paymaster is BasePaymaster {
}
// update oracle
uint192 lasestTokenPrice = fetchPrice(supportedToken[token].tokenOracle);
supportedToken[token].previousPrice = lasestTokenPrice;
uint192 nativeAssetPrice = fetchPrice(nativeAssetOracle);
supportedToken[token].previousPrice =
nativeAssetPrice * uint192(supportedToken[token].tokenDecimals) / lasestTokenPrice;
emit UserOperationSponsored(sender, token, tokenRequiredFund, actualGasCost);
}

Expand Down
77 changes: 11 additions & 66 deletions script/PaymasterDeployer.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ contract PaymasterDeployer is Script, DeployHelper {

function delpoyGoerli() private {
address testUsdc = 0x07865c6E87B9F70255377e024ace6630C1Eaa37F;
address testOracle = 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e;
address nativeOracle = 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e;
address usdcOracle = 0xAb5c49580294Aff77670F839ea425f5b78ab3Ae7;
address paymaster = deploy(
"Paymaster",
bytes.concat(
Expand All @@ -102,13 +103,14 @@ contract PaymasterDeployer is Script, DeployHelper {
address[] memory tokens = new address[](1);
tokens[0] = testUsdc;
address[] memory oracles = new address[](1);
oracles[0] = testOracle;
oracles[0] = usdcOracle;
uint32[] memory priceMarkups = new uint32[](1);
priceMarkups[0] = 1e6;

vm.stopBroadcast();
// start broadcast using paymasterOwner
vm.startBroadcast(paymasterOwnerPrivateKey);
ERC20Paymaster(paymaster).setNativeAssetOracle(address(nativeOracle));

IEntryPoint(ENTRYPOINT_ADDRESS).depositTo{value: 0.05 ether}(address(paymaster));
ERC20Paymaster(paymaster).addStake{value: 0.03 ether}(1);
Expand All @@ -119,7 +121,8 @@ contract PaymasterDeployer is Script, DeployHelper {

function delpoySepolia() private {
address testUsdc = 0x94a9D9AC8a22534E3FaCa9F4e7F2E2cf85d5E4C8;
address testOracle = 0x694AA1769357215DE4FAC081bf1f309aDC325306;
address usdcOracle = 0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E;
address nativeOracle = 0x694AA1769357215DE4FAC081bf1f309aDC325306;
address paymaster = deploy(
"Paymaster",
bytes.concat(
Expand All @@ -129,52 +132,24 @@ contract PaymasterDeployer is Script, DeployHelper {
address[] memory tokens = new address[](1);
tokens[0] = testUsdc;
address[] memory oracles = new address[](1);
oracles[0] = testOracle;
oracles[0] = usdcOracle;
uint32[] memory priceMarkups = new uint32[](1);
priceMarkups[0] = 1e6;

vm.stopBroadcast();
// start broadcast using paymasterOwner
vm.startBroadcast(paymasterOwnerPrivateKey);

ERC20Paymaster(paymaster).setNativeAssetOracle(address(nativeOracle));

IEntryPoint(ENTRYPOINT_ADDRESS).depositTo{value: 0.05 ether}(address(paymaster));
ERC20Paymaster(paymaster).addStake{value: 0.03 ether}(1);

ERC20Paymaster(paymaster).setToken(tokens, oracles, priceMarkups);
ERC20Paymaster(paymaster).updatePrice(address(testUsdc));
}

function delpoyArbGoerli() private {
address testUsdc_bridge = 0x8FB1E3fC51F3b789dED7557E680551d93Ea9d892;
address testUsdc_circle = 0xfd064A18f3BF249cf1f87FC203E90D8f650f2d63;
address testOracle = 0x62CAe0FA2da220f43a51F86Db2EDb36DcA9A5A08;
address paymaster = deploy(
"Paymaster",
bytes.concat(
type(ERC20Paymaster).creationCode, abi.encode(ENTRYPOINT_ADDRESS, paymasterOwner, soulwalletFactory)
)
);
address[] memory tokens = new address[](2);
tokens[0] = testUsdc_bridge;
tokens[1] = testUsdc_circle;
address[] memory oracles = new address[](2);
oracles[0] = testOracle;
oracles[1] = testOracle;
uint32[] memory priceMarkups = new uint32[](2);
priceMarkups[0] = 1e6;
priceMarkups[1] = 1e6;

vm.stopBroadcast();
// start broadcast using paymasterOwner
vm.startBroadcast(paymasterOwnerPrivateKey);

IEntryPoint(ENTRYPOINT_ADDRESS).depositTo{value: 0.03 ether}(address(paymaster));
ERC20Paymaster(paymaster).addStake{value: 0.03 ether}(1);

ERC20Paymaster(paymaster).setToken(tokens, oracles, priceMarkups);
ERC20Paymaster(paymaster).updatePrice(address(testUsdc_bridge));
ERC20Paymaster(paymaster).updatePrice(address(testUsdc_circle));
}
function delpoyArbGoerli() private {}

function delpoyArbSepolia() private {
address paymaster = deploy(
Expand Down Expand Up @@ -204,37 +179,7 @@ contract PaymasterDeployer is Script, DeployHelper {
ERC20Paymaster(paymaster).addStake{value: 0.03 ether}(1);
}

function delpoyOpGoerli() private {
address testUsdc_bridge = 0xe05606174bac4A6364B31bd0eCA4bf4dD368f8C6;
address testUsdc_circle = 0x7E07E15D2a87A24492740D16f5bdF58c16db0c4E;
address testOracle = 0x57241A37733983F97C4Ab06448F244A1E0Ca0ba8;
address paymaster = deploy(
"Paymaster",
bytes.concat(
type(ERC20Paymaster).creationCode, abi.encode(ENTRYPOINT_ADDRESS, paymasterOwner, soulwalletFactory)
)
);
address[] memory tokens = new address[](2);
tokens[0] = testUsdc_bridge;
tokens[1] = testUsdc_circle;
address[] memory oracles = new address[](2);
oracles[0] = testOracle;
oracles[1] = testOracle;
uint32[] memory priceMarkups = new uint32[](2);
priceMarkups[0] = 1e6;
priceMarkups[1] = 1e6;

vm.stopBroadcast();
// start broadcast using paymasterOwner
vm.startBroadcast(paymasterOwnerPrivateKey);

IEntryPoint(ENTRYPOINT_ADDRESS).depositTo{value: 0.03 ether}(address(paymaster));
ERC20Paymaster(paymaster).addStake{value: 0.03 ether}(1);

ERC20Paymaster(paymaster).setToken(tokens, oracles, priceMarkups);
ERC20Paymaster(paymaster).updatePrice(address(testUsdc_bridge));
ERC20Paymaster(paymaster).updatePrice(address(testUsdc_circle));
}
function delpoyOpGoerli() private {}

function delpoylocalEntryPoint() private {
ENTRYPOINT_ADDRESS = deploy("EntryPoint", type(EntryPoint).creationCode);
Expand Down
5 changes: 4 additions & 1 deletion test/paymaster/ERC20Paymaster.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ contract ERC20PaymasterTest is Test, UserOpHelper {
address payable beneficiary;
TokenERC20 token;
TestOracle testOracle;
TestOracle nativeAssetOracle;
HelloWorld helloWorld;

function setUp() public {
Expand All @@ -41,7 +42,8 @@ contract ERC20PaymasterTest is Test, UserOpHelper {
beneficiary = payable(makeAddr("beneficiary"));

token = new TokenERC20(6);
testOracle = new TestOracle(190355094900);
testOracle = new TestOracle(166590000);
nativeAssetOracle = new TestOracle(190355094900);
helloWorld = new HelloWorld();
bundler = new Bundler();
bytes[] memory modules = new bytes[](0);
Expand All @@ -68,6 +70,7 @@ contract ERC20PaymasterTest is Test, UserOpHelper {

vm.deal(paymasterOwner, 10000e18);
vm.startPrank(paymasterOwner);
paymaster.setNativeAssetOracle(address(nativeAssetOracle));
entryPoint.depositTo{value: 1000e18}(address(paymaster));
paymaster.addStake{value: 1000e18}(1);
address[] memory tokens = new address[](1);
Expand Down
5 changes: 4 additions & 1 deletion test/paymaster/ERC20PaymasterActiveWallet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ contract ERC20PaymasterActiveWalletTest is Test, UserOpHelper {
address payable beneficiary;
TokenERC20 token;
TestOracle testOracle;
TestOracle nativeAssetOracle;
HelloWorld helloWorld;

function setUp() public {
Expand All @@ -50,7 +51,8 @@ contract ERC20PaymasterActiveWalletTest is Test, UserOpHelper {
beneficiary = payable(makeAddr("beneficiary"));

token = new TokenERC20(6);
testOracle = new TestOracle(190355094900);
testOracle = new TestOracle(166590000);
nativeAssetOracle = new TestOracle(190355094900);
helloWorld = new HelloWorld();
bundler = new Bundler();

Expand All @@ -76,6 +78,7 @@ contract ERC20PaymasterActiveWalletTest is Test, UserOpHelper {

vm.deal(paymasterOwner, 10000e18);
vm.startPrank(paymasterOwner);
paymaster.setNativeAssetOracle(address(nativeAssetOracle));
entryPoint.depositTo{value: 1000e18}(address(paymaster));
paymaster.addStake{value: 1000e18}(1);
address[] memory tokens = new address[](1);
Expand Down

0 comments on commit db422fa

Please sign in to comment.